3

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

当我使用登录页面正确登录应用程序时,应用程序工作正常

但是当我尝试访问一些需要身份验证而不是重定向到登录页面的受保护 url 时;我得到一个类转换异常。

调试显示返回字符串“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>
4

1 回答 1

2

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

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

正如我所见ExceptionTranslationFilter,您的conf中没有。因此,请将其添加到您的过滤器链中。顺序很重要,一定要放在前面 FilterSecurityInterceptor

于 2013-07-31T09:24:19.613 回答