views:

70

answers:

2

I've got HTTP Security working in my web application with CAS authentication using Spring Security. However, I'm trying to mix it with method level security for some service methods (specifically GWT RPC), but it doesn't seem to be working. It gets to the point where it executes the @PostAuthorize annotation. However, it doesn't seem to pay attention to the configuration I have and executes some other way that does deny access to the returned object.

Cut down deployerConfigContext.xml read by org.springframework.web.context.ContextLoaderListe ner listener.

    <?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
 xmlns:security="http://www.springframework.org/schema/security"
 xmlns:context="http://www.springframework.org/schema/context"
 xmlns:tx="http://www.springframework.org/schema/tx" xmlns:aop="http://www.springframework.org/schema/aop"
 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 xsi:schemaLocation="schemaURLs here">

 <security:http use-expressions="true"
  entry-point-ref="casProcessingFilterEntryPoint">
  <security:intercept-url pattern="/casfailed.jsp"
   requires-channel="any" access="permitAll" />
  <security:intercept-url pattern="/cas-logout.jsp"
   requires-channel="any" access="permitAll" />
  <security:intercept-url pattern="/**"
   access="isAuthenticated()" requires-channel="https" />
  <security:logout logout-success-url="/cas-logout.jsp" />
  <security:custom-filter ref="casAuthenticationFilter"
   after="CAS_FILTER" />
 </security:http>

 <security:authentication-manager alias="authenticationManager">
  <security:authentication-provider
   ref="casAuthenticationProvider" />
 </security:authentication-manager>

 <!-- setup method level security using annotations -->
 <security:global-method-security
  jsr250-annotations="disabled" secured-annotations="enabled"
  pre-post-annotations="enabled">
  <security:expression-handler ref="expressionHandler" />
 </security:global-method-security>

 <bean id="expressionHandler"
  class="org.springframework.security.access.expression.method.DefaultMethodSecurityExpressionHandler">
  <property name="permissionEvaluator" ref="permissionEvaluator" />
 </bean>

 <bean id="permissionEvaluator"
  class="org.springframework.security.acls.AclPermissionEvaluator">
  <constructor-arg ref="aclService" />
 </bean>

 <bean id="aclService"
  class="my.custom.AclService">
  <constructor-arg>
   <bean class="org.springframework.security.acls.domain.ConsoleAuditLogger" />
  </constructor-arg>
  <constructor-arg>
   <bean
    class="org.springframework.security.acls.domain.AclAuthorizationStrategyImpl">
    <constructor-arg>
     <list>
      <bean
       class="org.springframework.security.core.authority.GrantedAuthorityImpl">
       <constructor-arg value="ROLE_ADMINISTRATOR" />
      </bean>
      <bean
       class="org.springframework.security.core.authority.GrantedAuthorityImpl">
       <constructor-arg value="ROLE_ADMINISTRATOR" />
      </bean>
      <bean
       class="org.springframework.security.core.authority.GrantedAuthorityImpl">
       <constructor-arg value="ROLE_ADMINISTRATOR" />
      </bean>
     </list>
    </constructor-arg>
   </bean>
  </constructor-arg>
 </bean>

 <bean
  class="org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor" />

 <tx:annotation-driven transaction-manager="transactionManager" />

 <bean id="systemEMF"
  class="org.springframework.orm.jpa.LocalEntityManagerFactoryBean">
  <property name="persistenceUnitName" value="_persistenceunit_" />
 </bean>

 <bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
  <property name="entityManagerFactory" ref="systemEMF" />
 </bean>
</beans>

The bean for my AclService gets created, however nothing after that is executed in it (I have logging on every method). I'm not even sure the expressionHandler bean is being used. Do I need to move something up into the security:http section?

Here's the section of the debug log where it gets executed:

2010-07-23 17:39:17,885 [org.springframework.security.access.prepost.PrePostAnnotationSecurityMetadataSource] DEBUG: @org.springframework.security.access.prepost.PostAuthorize(value=hasPermission(filterObject,'read')) found on specific method: public ReturnType my.rpc.RPCClass.getObject(java.lang.Long)
    2010-07-23 17:39:17,885 [org.springframework.security.access.method.DelegatingMethodSecurityMetadataSource] DEBUG: Adding security method [CacheKey[my.rpc.RPCClass; public abstract ReturnType my.rpc.RPCClass.getObject(java.lang.Long)]] with attributes [[authorize: 'permitAll', filter: 'null', filterTarget: 'null'], [authorize: 'hasPermission(filterObject,'read')', filter: 'null']]
    2010-07-23 17:39:17,885 [org.springframework.transaction.annotation.AnnotationTransactionAttributeSource] DEBUG: Adding transactional method 'getObject' with attribute: PROPAGATION_REQUIRED,ISOLATION_DEFAULT; '',-java.lang.Throwable
    2010-07-23 17:39:17,886 [org.springframework.security.access.intercept.aopalliance.MethodSecurityInterceptor] DEBUG: Secure object: ReflectiveMethodInvocation: public abstract ReturnType my.rpc.RPCClass.getObject(java.lang.Long); target is of class [my.rpc.RPCClass]; Attributes: [[authorize: 'permitAll', filter: 'null', filterTarget: 'null'], [authorize: 'hasPermission(filterObject,'read')', filter: 'null']]
    2010-07-23 17:39:17,886 [org.springframework.security.access.intercept.aopalliance.MethodSecurityInterceptor] DEBUG: Previously Authenticated: org.springframework.security.cas.authentication.CasAuthenticationToken@eeb49577: Principal: org.springframework.security.core.userdetails.User@8d32400: Username: kevin.jordan; Password: [PROTECTED]; Enabled: true; AccountNonExpired: true; credentialsNonExpired: true; AccountNonLocked: true; Granted Authorities: ROLE_USER; Password: [PROTECTED]; Authenticated: true; Details: org.springframework.security.web.authentication.WebAuthenticationDetails@0: RemoteIpAddress: 192.168.0.16; SessionId: HZFBB0B9768A164833B6C659177874FC9C; Granted Authorities: ROLE_USER Assertion: org.jasig.cas.client.validation.AssertionImpl@5b8f67a6 Credentials (Service/Proxy Ticket): ST-27-lUehDttiUOLU041sBEio-cas
    2010-07-23 17:39:17,890 [org.springframework.security.access.vote.AffirmativeBased] DEBUG: Voter: org.springframework.security.access.prepost.PreInvocationAuthorizationAdviceVoter@52691fcf, returned: 1
    2010-07-23 17:39:17,890 [org.springframework.security.access.intercept.aopalliance.MethodSecurityInterceptor] DEBUG: Authorization successful
    2010-07-23 17:39:17,890 [org.springframework.security.access.intercept.aopalliance.MethodSecurityInterceptor] DEBUG: RunAsManager did not change Authentication object
    2010-07-23 17:39:17,890 [org.springframework.beans.factory.support.DefaultListableBeanFactory] DEBUG: Returning cached instance of singleton bean 'transactionManager'
    2010-07-23 17:39:17,890 [org.springframework.orm.jpa.JpaTransactionManager] DEBUG: Creating new transaction with name [my.rpc.RPCClass.getObject]: PROPAGATION_REQUIRED,ISOLATION_DEFAULT; '',-java.lang.Throwable
    2010-07-23 17:39:17,891 [org.springframework.orm.jpa.JpaTransactionManager] DEBUG: Opened new EntityManager [org.hibernate.ejb.EntityManagerImpl@62701e2a] for JPA transaction
    2010-07-23 17:39:18,333 [org.springframework.orm.jpa.JpaTransactionManager] DEBUG: Initiating transaction commit
    2010-07-23 17:39:18,339 [org.springframework.orm.jpa.JpaTransactionManager] DEBUG: Committing JPA transaction on EntityManager [org.hibernate.ejb.EntityManagerImpl@62701e2a]
    2010-07-23 17:39:18,342 [org.springframework.orm.jpa.JpaTransactionManager] DEBUG: Closing JPA EntityManager [org.hibernate.ejb.EntityManagerImpl@62701e2a] after transaction
    2010-07-23 17:39:18,342 [org.springframework.orm.jpa.EntityManagerFactoryUtils] DEBUG: Closing JPA EntityManager
    2010-07-23 17:39:18,343 [org.springframework.security.access.expression.method.ExpressionBasedPostInvocationAdvice] DEBUG: PostAuthorize expression rejected access

If anyone needs information from when it starts up or anything let me know. Thanks for your help!

A: 

Probably your calls are not intercepted by AOP proxy, because methods are called directly (see 7.6.1 Understanding AOP proxies). It's definitely so if you annotated methods of the RemoteServiceServlet itself.

You should either annotate methods of the service beans called from the RemoteServiceServlet or use spring4gwt.

axtavt
I'm not calling service beans. I'm trying to secure the actual GWT RPC method. In this case, with a @PostAuthorize("hasPermission(filterObject,'read')"). Problem is it doesn't seem to use any of my ACL service objects. It just automatically denies.
kjordan
A: 

And apparently it's because I was using filterObject when for that it should be returnObject.

kjordan