Spring Custom过滤链

时间:2013-07-31 07:43:56

标签: spring-security

我正在编写自己的过滤器链,以便从数据库动态加载用户角色并过滤网址

当我使用登录页面

正确登录应用程序时,

应用程序正常工作

当我尝试访问一些需要身份验证而不是重定向到登录页面的受保护网址时;我正在获得一个阶级演员例外。

调试显示返回String“anonymousUser”而不是我的域主体对象:(

java.lang.ClassCastException: java.lang.String cannot be cast to com.mytech.myapp.model.MyAppUser at com.mytech.myapp.web.controller.helper.LeftMenuHelper.getManageLeftMenu(LeftMenuHelper.java:171) at com.mytech.myapp.web.controller.ManageController.setLeftTree(ManageController.java:1377) at com.mytech.myapp.web.controller.ManageController.renderManagePage(ManageController.java:379) at com.mytech.myapp.web.controller.ManageController.handleNoSuchRequestHandlingMethod(ManageController.java:371) at org.springframework.web.servlet.mvc.multiaction.MultiActionController.handleRequestInternal(MultiActionController.java:413) at org.springframework.web.servlet.mvc.AbstractController.handleRequest(AbstractController.java:153) at org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter.handle(SimpleControllerHandlerAdapter.java:48) at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:875) at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:809) at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:571) at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:501) at javax.servlet.http.HttpServlet.service(HttpServlet.java:621) at javax.servlet.http.HttpServlet.service(HttpServlet.java:722) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:305) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210) at org.springframework.security.util.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:378) at org.springframework.security.intercept.web.FilterSecurityInterceptor.invoke(FilterSecurityInterceptor.java:109) at org.springframework.security.intercept.web.FilterSecurityInterceptor.doFilter(FilterSecurityInterceptor.java:83) at org.springframework.security.util.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:390) at org.springframework.security.providers.anonymous.AnonymousProcessingFilter.doFilterHttp(AnonymousProcessingFilter.java:105) at org.springframework.security.ui.SpringSecurityFilter.doFilter(SpringSecurityFilter.java:53) at

我的安全xml如下

    <?xml version="1.0" encoding="UTF-8"?>

<b:beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:sec="http://www.springframework.org/schema/security"
    xmlns:b="http://www.springframework.org/schema/beans"
    xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
                        http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security-2.0.4.xsd">

    <b:bean id="springSecurityFilterChain" class="org.springframework.security.util.FilterChainProxy">
        <sec:filter-chain-map path-type="ant">
            <sec:filter-chain pattern="/brands/**" filters="none" />
            <sec:filter-chain pattern="/javascript/**" filters="none" />
            <sec:filter-chain pattern="/index.html" filters="none" />
            <sec:filter-chain pattern="/login.do" filters="none" />
            <sec:filter-chain pattern="/forgotPassword.do" filters="none" />
            <sec:filter-chain pattern="/ws/restapi/**" filters="none" />
            <sec:filter-chain pattern="/**" filters="
                httpSessionContextIntegrationFilter,
                logoutFilter,
                preAuthFilter,
                authenticationProcessingFilter,
                anonymousProcessingFilter,
                filterSecurityInterceptor
            "/>
        </sec:filter-chain-map>
    </b:bean>
    <!--
    -->

    <b:bean id="anonymousProcessingFilter" class="org.springframework.security.providers.anonymous.AnonymousProcessingFilter">
        <b:property name="key" value="foobar" />
        <b:property name="userAttribute" value="anonymousUser,ROLE_ANONYMOUS" />
    </b:bean>

    <b:bean id="anonymousAuthenticationProvider" class="org.springframework.security.providers.anonymous.AnonymousAuthenticationProvider">
        <b:property name="key" value="foobar" />
    </b:bean>

    <b:bean id="httpSessionContextIntegrationFilter" class="org.springframework.security.context.HttpSessionContextIntegrationFilter">
        <sec:custom-filter position="SESSION_CONTEXT_INTEGRATION_FILTER"/>
    </b:bean>

    <b:bean id="logoutFilter" class="org.springframework.security.ui.logout.LogoutFilter">
        <b:constructor-arg value="/login.do?code=logout" />
        <b:constructor-arg>
            <b:list>
                <b:ref bean="securityContextLogoutHandler" />
            </b:list>
        </b:constructor-arg>
        <sec:custom-filter position="LOGOUT_FILTER"/>
    </b:bean>

    <b:bean id="securityContextLogoutHandler" class="org.springframework.security.ui.logout.SecurityContextLogoutHandler" />

    <b:bean id="filterSecurityInterceptor" class="org.springframework.security.intercept.web.FilterSecurityInterceptor">
        <sec:custom-filter position="FILTER_SECURITY_INTERCEPTOR"/>
        <b:property name="authenticationManager" ref="authenticationManagerAlias" />
        <b:property name="accessDecisionManager" ref="accessDecisionManager" />
        <b:property name="objectDefinitionSource" ref="MyAppRoleUrlFilterSource" />
    </b:bean>

    <b:bean id="MyAppRoleUrlFilterSource" class="com.softech.myapp.web.filter.MyAppRoleUrlFilterSource">
    </b:bean>

    <b:bean id="accessDecisionManager" class="org.springframework.security.vote.UnanimousBased">
        <b:property name="decisionVoters" ref="roleVoter" />
    </b:bean>

    <b:bean id="roleVoter" class="org.springframework.security.vote.RoleVoter">
        <b:property name="rolePrefix" value="" />
    </b:bean>

    <b:bean id="preAuthFilter" class="com.softech.myapp.web.filter.MyAppRequestPreAuthFilter">
        <sec:custom-filter position="PRE_AUTH_FILTER" />
        <b:property name="principalRequestHeader" value="MYAPP_AUTH_USER_TOKEN" />
        <b:property name="authenticationManager" ref="authenticationManagerAlias" />
        <b:property name="authenticationDetailsSource" ref="userDetailsService"></b:property>

        <b:property name="preAuthEntryUrl" value="/interceptor.do"></b:property>
        <b:property name="listenFrom" value="*"></b:property>
    </b:bean>

    <b:bean id="preAuthProvider" class="org.springframework.security.providers.preauth.PreAuthenticatedAuthenticationProvider">
        <sec:custom-authentication-provider />
        <b:property name="preAuthenticatedUserDetailsService">
            <b:bean id="userDetailsServiceWrapper" class="org.springframework.security.userdetails.UserDetailsByNameServiceWrapper">
                <b:property name="userDetailsService" ref="userDetailsService" />
            </b:bean>
        </b:property>
    </b:bean>

    <b:bean id="authenticationProcessingFilterEntryPoint" class="org.springframework.security.ui.webapp.AuthenticationProcessingFilterEntryPoint">
        <b:property name="loginFormUrl" value="/login.do"/>
        <b:property name="forceHttps" value="false" />
    </b:bean>

    <sec:authentication-manager alias='authenticationManagerAlias'/>
    <b:bean id="authenticationManager" class="org.springframework.security.providers.ProviderManager">
        <b:property name="providers">
            <b:list>
                <b:ref local="secureDaoAuthenticationProvider"/>
                <b:ref local="daoAuthenticationProvider"/>
            </b:list>
        </b:property>
    </b:bean>

    <b:bean id="authenticationProcessingFilter" class="org.springframework.security.ui.webapp.AuthenticationProcessingFilter">
        <sec:custom-filter position="AUTHENTICATION_PROCESSING_FILTER"/>
        <b:property name="defaultTargetUrl" value="/interceptor.do"/>
        <b:property name="authenticationFailureUrl" value="/login.do"/>
        <b:property name="authenticationManager" ref="authenticationManagerAlias"/>
        <b:property name="authenticationDetailsSource" ref="myAppUserAuthenticationDetailsSource"/>
        <b:property name="alwaysUseDefaultTargetUrl" value="true"/>
    </b:bean>    

    <!-- <authentication-provider user-service-ref="userDetailsService"/> -->
    <!-- the SHA-1 password encoder -->
    <b:bean id="secureDaoAuthenticationProvider" class="org.springframework.security.providers.dao.DaoAuthenticationProvider">
        <b:property name="userDetailsService" ref="userDetailsService"/>
        <b:property name="passwordEncoder" ref="passwordEncoder"/>
        <b:property name="saltSource" ref="saltSource"/>
        <sec:custom-authentication-provider/>  
    </b:bean>   

    <!-- Plain Text password encoder - the default -->
    <b:bean id="daoAuthenticationProvider" class="org.springframework.security.providers.dao.DaoAuthenticationProvider">
        <b:property name="userDetailsService" ref="userDetailsService"/>
        <sec:custom-authentication-provider/>  
    </b:bean>

    <b:bean id="myAppUserAuthenticationDetailsSource" class="org.springframework.security.ui.WebAuthenticationDetailsSource">
        <b:property name="clazz" value="com.softech.myapp.web.filter.MyAppUserAuthenticationDetails"/>
    </b:bean>   

   <!-- Automatically receives AuthenticationEvent messages -->
   <b:bean id="loggerListener" class="org.springframework.security.event.authentication.LoggerListener"/>

</b:beans>

1 个答案:

答案 0 :(得分:2)

“重定向到登录页面”功能取决于两个过滤器:

  • FilterSecurityInterceptor - 检查安全规则,抛出AccessDeniedException
  • ExceptionTranslationFilter - 捕获AccessDeniedException并在匿名用户的情况下启动身份验证

我可以看到ExceptionTranslationFilter在你的conf中不存在。所以请将它添加到您的过滤器链中。订单非常重要,必须先插入 <{strong> FilterSecurityInterceptor