在未经身份验证的用户向受保护的资源发出请求后,我在重定向到 login.jsp 页面时遇到问题;我的 JSF 2 Web 应用程序部署在 WAS 8.5 上,我在其中设置了一个带有自定义数据库领域的自定义安全域,并位于带有 spring-security 框架的经典 preAuthenticated 场景下。我声明在 JBoss 6.1.0 上一切正常!!!好吧,我使用经典的基于表单的登录(j2ee 标准)设置了我的应用程序:
<login-config>
<auth-method>FORM</auth-method>
<form-login-config>
<form-login-page>/login.jsp</form-login-page>
<form-error-page>/loginError.jsp</form-error-page>
</form-login-config>
</login-config>
通过经典的安全约束配置保护页面,如 Spring Security 指南所示:
<security-constraint>
<display-name>Access Agent Security</display-name>
<web-resource-collection>
<web-resource-name>Secured resource</web-resource-name>
<url-pattern>/views/protected/*</url-pattern>
</web-resource-collection>
<auth-constraint>
<role-name>*</role-name>
</auth-constraint>
</security-constraint>
我的 Spring 安全性如下所示:
<bean class="org.springframework.web.context.support.ServletContextPropertyPlaceholderConfigurer"/>
<bean id="securityInfo" class="it.xxxxxx.common.security.SecurityInfo"/>
<bean id="securityService"
class="org.springframework.ejb.access.SimpleRemoteStatelessSessionProxyFactoryBean">
<property name="jndiName" value="AccessAgent/SecurityServiceBean/remote"/>
<property name="businessInterface" value="it.pegaso2000.access.service.bean.SecurityService"/>
</bean>
<bean id="filterChainProxy" class="org.springframework.security.web.FilterChainProxy">
<sec:filter-chain-map path-type="ant">
<sec:filter-chain pattern="/**" filters="sif,j2eePreAuthFilter,logoutFilter,etf,fsi"/>
</sec:filter-chain-map>
</bean>
<bean id="sif" class="org.springframework.security.web.context.SecurityContextPersistenceFilter"/>
<sec:authentication-manager alias="authenticationManager">
<sec:authentication-provider ref='preAuthenticatedAuthenticationProvider'/>
</sec:authentication-manager>
<bean id="preAuthenticatedAuthenticationProvider" class="org.springframework.security.web.authentication.preauth.PreAuthenticatedAuthenticationProvider">
<property name="preAuthenticatedUserDetailsService" ref="preAuthenticatedUserDetailsService"/>
</bean>
<bean id="preAuthenticatedUserDetailsService"
class="it.pegaso2000.access.web.security.auth.PreAuthenticatedUserDetailsService"/>
<bean id="mappableRolesRetriever"
class="it.pegaso2000.access.web.security.auth.preauth.j2ee.DatabaseMappableAttributesRetriever"/>
<bean id="authenticationDetailsSource" class="org.springframework.security.web.authentication.preauth.websphere.WebSpherePreAuthenticatedWebAuthenticationDetailsSource">
<property name="webSphereGroups2GrantedAuthoritiesMapper">
<bean class="org.springframework.security.core.authority.mapping.SimpleAttributes2GrantedAuthoritiesMapper">
<property name="convertAttributeToUpperCase" value="true"/>
</bean>
</property>
</bean>
<bean id="j2eePreAuthFilter" class="it.xxxxx.access.web.security.auth.preauth.websphere.WebSpherePreAuthenticatedProcessingFilter">
<property name="authenticationManager" ref="authenticationManager"/>
<property name="authenticationDetailsSource" ref="authenticationDetailsSource"/>
</bean>
<bean id="preAuthenticatedProcessingFilterEntryPoint"
class="org.springframework.security.web.authentication.Http403ForbiddenEntryPoint"/>
<bean id="logoutFilter" class="org.springframework.security.web.authentication.logout.LogoutFilter">
<constructor-arg value="/"/>
<constructor-arg>
<list>
<bean class="org.springframework.security.web.authentication.logout.SecurityContextLogoutHandler"/>
</list>
</constructor-arg>
</bean>
<bean id="servletContext" class="org.springframework.web.context.support.ServletContextFactoryBean"/>
<bean id="etf" class="org.springframework.security.web.access.ExceptionTranslationFilter">
<property name="authenticationEntryPoint" ref="preAuthenticatedProcessingFilterEntryPoint"/>
</bean>
<bean id="httpRequestAccessDecisionManager" class="org.springframework.security.access.vote.AffirmativeBased">
<property name="allowIfAllAbstainDecisions" value="false"/>
<property name="decisionVoters">
<list>
<ref bean="roleVoter"/>
</list>
</property>
</bean>
<bean id="securityMetadataSource" class="it.xxxxx.access.web.security.auth.DatabaseFilterInvocationSecurityMetadataSource"/>
<bean id="fsi" class="org.springframework.security.web.access.intercept.FilterSecurityInterceptor">
<property name="authenticationManager" ref="authenticationManager"/>
<property name="accessDecisionManager" ref="httpRequestAccessDecisionManager"/>
<property name="securityMetadataSource" ref="securityMetadataSource"/>
</bean>
<bean id="roleVoter" class="org.springframework.security.access.vote.RoleVoter"/>
<bean id="securityContextHolderAwareRequestFilter" class="org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter"/>
如您所见,我已经重载了org.springframework.security.web.authentication.preauth.websphere.WebSpherePreAuthenticatedProcessingFilter因为我注意到 doAuthentication() 方法从 WAS 返回一个主体值等于“未验证”的匿名请求,而 spring AbstractPreAuthenticatedProcessingFilter 类与主体匹配像这样使用null:
if (principal == null) {
if (logger.isDebugEnabled()) {
logger.debug("No pre-authenticated principal found in request");
}
enter code here
return;
}
结果是如果用户是匿名的,它永远不会返回语句。
但这并不能解决我的问题...如果对受保护资源完成未经身份验证的用户请求,我希望我的容器 (WAS) 重定向到 login.jsp 页面。有什么想念我的配置?这个场景在 JBoss 6 上成功运行,有人帮助我吗?
提前致谢 !!