我正在一个新项目中工作,我需要管理用户角色,因为这个应用程序通过 Web 服务使用自己的身份验证系统。所以,我唯一需要做的就是验证每个用户角色,如果用户 id 存在于我的数据库中,他可以输入,否则将被拒绝。这意味着,没有密码,没有登录页面(由 Web 服务执行),只需验证用户 ID 并获取他们的角色。
我做了一个概念证明,以便根据我的理解来实现这一点,这是在阅读了所涉及的文档之后。关键是这没有按预期工作,让我与您分享这个示例:
安全设定
<?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.0.xsd
http://www.springframework.org/schema/security
http://www.springframework.org/schema/security/spring-security-3.1.xsd">
<security:http use-expressions="true" entry-point-ref="http403ForbiddenEntryPoint">
<security:anonymous enabled="false" />
<security:intercept-url pattern="index.jsp" access="permitAll" />
<security:intercept-url pattern="home.html" access="hasRole('ROLE_ADMIN')" />
<security:intercept-url pattern="excel.html" access="hasAnyRole('ROLE_USER','ROLE_ADMIN')" />
<security:intercept-url pattern="denied.jsp" access="permitAll" />
<security:custom-filter position="PRE_AUTH_FILTER" ref="meivFilter" />
</security:http>
<bean id="http403ForbiddenEntryPoint" class="org.springframework.security.web.authentication.Http403ForbiddenEntryPoint" />
<bean id="meivFilter" class="org.springframework.security.web.authentication.preauth.RequestHeaderAuthenticationFilter">
<property name="principalRequestHeader" value="Host" />
<property name="authenticationManager" ref="authenticationManager" />
</bean>
<bean id="preauthAuthProvider"
class="org.springframework.security.web.authentication.
preauth.PreAuthenticatedAuthenticationProvider">
<property name="preAuthenticatedUserDetailsService">
<bean id="userDetailsServiceWrapper"
class="org.springframework.security.core.userdetails.UserDetailsByNameServiceWrapper">
<property name="userDetailsService" ref="userDetailsService" />
</bean>
</property>
</bean>
<security:authentication-manager alias="authenticationManager">
<security:authentication-provider ref="preauthAuthProvider" />
</security:authentication-manager>
<bean id="userDetailsService" class="com.gm.gpsc.meiv.security.UserServiceImpl" />
</beans>
注意:为了测试它,如您所见,我在 RequestHeaderAuthenticationFilter 中使用作为 principalRequestHeader 属性,Host 标头值作为默认标头值存在。只是为了测试。因为将来我会从标题中读取一个值。
这是我为获取用户角色所做的 userDetailService。
public class UserServiceImpl implements UserDetailsService {
private boolean accountNonExpired = true;
private boolean accountNonLocked = true;
private boolean credentialsNonExpired = true;
private boolean enabled = true;
@Override
public UserDetails loadUserByUsername(String userId)
throws UsernameNotFoundException {
GrantedAuthority[] grantedAuthority = new GrantedAuthority[1];
grantedAuthority[0] = new GrantedAuthorityImpl("ROLE_USER");
Collection<GrantedAuthority> authorities = new ArrayList<GrantedAuthority>();
authorities.add(grantedAuthority[0]);
return new User(userId, "x",enabled, accountNonExpired, credentialsNonExpired, accountNonLocked, authorities);
}
}
当我运行此示例时,设置已成功加载,然后当我尝试访问第一个模式 home.html 时,我可以访问该页面,这是错误的,因为根据我的规则我有 ROLE_USER 并且如上所示我需要 ROLE_ADMIN。
对于第二种模式,我也可以访问,但在这种情况下,这是有道理的,因为 ROLE_USER 被包含为规则。
对于第一种情况,我将 home.html 更改为 /home.html 并且我得到 403 Access denied 。但是如果我对第二个选项 excel 使用相同的模式,这意味着 /excel.html,我得到了同样的错误(403)。
这是我从日志文件中得到的错误:
DEBUG | 2012-09-30 03:55:09,738 | FilterChainProxy | /index.jsp at position 1 of 7 in additional filter chain; firing Filter: 'SecurityContextPersistenceFilter'
DEBUG | 2012-09-30 03:55:09,739 | HttpSessionSecurityContextRepository | No HttpSession currently exists
DEBUG | 2012-09-30 03:55:09,739 | HttpSessionSecurityContextRepository | No SecurityContext was available from the HttpSession: null. A new one will be created.
DEBUG | 2012-09-30 03:55:09,744 | FilterChainProxy | /index.jsp at position 2 of 7 in additional filter chain; firing Filter: 'RequestHeaderAuthenticationFilter'
DEBUG | 2012-09-30 03:55:09,744 | RequestHeaderAuthenticationFilter | Checking secure context token: null
DEBUG | 2012-09-30 03:55:09,744 | HttpSessionSecurityContextRepository | SecurityContext is empty or contents are anonymous - context will not be stored in HttpSession.
DEBUG | 2012-09-30 03:55:09,744 | SecurityContextPersistenceFilter | SecurityContextHolder now cleared, as request processing completed
30/09/2012 03:55:09 org.apache.catalina.core.StandardWrapperValve invoke
GRAVE: Servlet.service() para servlet jsp lanzó excepción
org.springframework.security.web.authentication.preauth.PreAuthenticatedCredentialsNotFoundException: MYID header not found in request.
我不明白这里发生了什么,也许有人可以解释我哪里错了。
感谢您的帮助,因为我对此感到非常困惑,并且厌倦了无处可去地阅读文档。