我正在尝试使用 Spring Security 来保护使用角色层次结构的方法。显然,由于我在这里发帖,所以它不起作用。
首先,这是一个接口的定义:
@PreAuthorize("isFullyAuthenticated()")
List<RetainUser> getByLocation(String location);
接下来,这是我试图用来测试它的单元测试:
@Test
public void getByLocation_anonymousUser_throwsAccessDeniedException() {
AppUser anonymousUser = (AppUser) retainUserManager.loadUserByUsername("1111");
Authentication auth = provider.authenticate(new PreAuthenticatedAuthenticationToken(anonymousUser, new AppAuthority(anonymousUser, "ROLE_ANONYMOUS")));
SecurityContext context = new SecurityContextImpl();
context.setAuthentication(auth);
SecurityContextHolder.setContext(context);
try {
List<AppUser> testResult = appUserManager.getByLocation("DAYTON");
fail("call by anonymous user should have thrown AccessDeniedException");
} catch (AccessDeniedException ex) {
System.out.println(ex.getMessage());
}
}
最后,我的 security.xml 文件:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:security="http://www.springframework.org/schema/security"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
http://www.springframework.org/schema/security
http://www.springframework.org/schema/security/spring-security-3.1.xsd">
<security:global-method-security pre-post-annotations="enabled">
<security:expression-handler ref="methodSecurityExpressionHandler"/>
</security:global-method-security>
<bean id="expressionHandler" class="org.springframework.security.web.access.expression.DefaultWebSecurityExpressionHandler">
<property name="roleHierarchy" ref="roleHierarchy" />
</bean>
<bean id="methodSecurityExpressionHandler" class="org.springframework.security.access.expression.method.DefaultMethodSecurityExpressionHandler">
<property name="roleHierarchy" ref="roleHierarchy" />
</bean>
<!-- In order to use a role hierarchy with the Security expressions, the
hierarchy needs to be injected into the expression handler -->
<!-- Configure static resources to have no Spring Security filters applied
to them -->
<security:http pattern="/common/**" security="none" />
<security:http pattern="/**/*.png" security="none" />
<security:http pattern="/styles/**/*.css" security="none" />
<security:http pattern="/**/*.css" security="none" />
<security:http pattern="/**/*.js" security="none" />
<security:http pattern="/login.jsp" security="none" />
<security:http use-expressions="true" access-denied-page="/accountWizard.html"
access-decision-manager-ref="accessDecisionManager">
<security:anonymous />
<security:x509 subject-principal-regex="CN=(.*?)," user-service-ref="retainUserManager" />
<!-- Role Anonymous needs to be able to hit the index controller in order to be -->
<!-- redirected to the account wizard (if necessary) -->
<security:intercept-url pattern="/index.html*" access="hasRole('ROLE_ANONYMOUS')" />
<security:intercept-url pattern="/**/acceptTerms.html*" access="hasRole('ROLE_ANONYMOUS')" />
<security:intercept-url pattern="/**/accountWizardHome.html*" access="hasRole('ROLE_ANONYMOUS')"/>
<security:intercept-url pattern="/**/accountPending.html*" access="hasRole('ROLE_ANONYMOUS')"/>
<!-- Since roles are hierarchal, ROLE_FIELD and above are legal -->
<security:intercept-url pattern="/**/*.html" access="hasRole('ROLE_FIELD')" />
<security:session-management>
<security:concurrency-control
max-sessions="1" error-if-maximum-exceeded="false" />
</security:session-management>
</security:http>
<security:authentication-manager alias="authenticationManager">
<security:authentication-provider
user-service-ref="appUserManager" />
</security:authentication-manager>
<bean id="accessDecisionManager" class="org.springframework.security.access.vote.AffirmativeBased">
<property name="decisionVoters">
<list>
<ref bean="webExpressionVoter" />
<ref bean="roleHierarchyVoter" />
</list>
</property>
</bean>
<bean id="webExpressionVoter" class="org.springframework.security.web.access.expression.WebExpressionVoter">
<property name="expressionHandler">
<bean
class="org.springframework.security.web.access.expression.DefaultWebSecurityExpressionHandler">
<property name="roleHierarchy" ref="roleHierarchy" />
</bean>
</property>
</bean>
<bean id="roleHierarchyVoter"
class="org.springframework.security.access.vote.RoleHierarchyVoter">
<constructor-arg ref="roleHierarchy" />
</bean>
<bean id="roleHierarchy"
class="org.springframework.security.access.hierarchicalroles.RoleHierarchyImpl">
<property name="hierarchy">
<value>
ROLE_SYSTEM > ROLE_MANAGER
ROLE_MANAGER > ROLE_FIELD
ROLE_FIELD > ROLE_ANONYMOUS
</value>
</property>
</bean>
<bean id="exceptionTranslationFilter"
class="org.springframework.security.web.access.ExceptionTranslationFilter">
<property name="authenticationEntryPoint" ref="authenticationEntryPoint" />
<property name="accessDeniedHandler" ref="accessDeniedHandler" />
</bean>
<bean id="authenticationEntryPoint"
class="org.springframework.security.web.authentication.LoginUrlAuthenticationEntryPoint">
<property name="loginFormUrl" value="/login.jsp" />
<property name="forceHttps" value="true" />
</bean>
<bean id="accessDeniedHandler"
class="org.springframework.security.web.access.AccessDeniedHandlerImpl">
<property name="errorPage" value="/403.jsp" />
</bean>
在上面的测试中,我期待一个 AccessDeniedException,因为表达式是“hasRole('ROLE_FIELD')”,它高于 ROLE_ANONYMOUS。不幸的是,没有抛出异常。
任何人都可以帮忙吗?