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!