spring 在没有http自动配置的情况下直接配置spring security后找不到“j_spring_security_check”

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/7661023/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-08 04:41:11  来源:igfitidea点击:

"j_spring_security_check" not found after configuring spring security directly without http auto config

spring

提问by Ben Wu

I'm trying to convert Spring Security configuration from HTTP namespace into direct configuration using FilterChainProxy. Before the conversion, everything was ok with HTTP namespace. But after replacing element by several elements with FilterChainProxy, I got “j_spring_security_check not found” error while login to the system. I tried to change all or some of “/j_spring_security_check” with “/app/j_spring_security_check” but still could not login successfully.

我正在尝试使用 FilterChainProxy 将 Spring Security 配置从 HTTP 命名空间转换为直接配置。在转换之前,HTTP 命名空间一切正常。但是用FilterChainProxy用几个元素替换元素后,登录系统时出现“j_spring_security_check not found”错误。我试图用“/app/j_spring_security_check”更改全部或部分“/j_spring_security_check”,但仍然无法成功登录。

My environment: AppFuse 2.1 with Spring MVC, iBatis, Spring Security 3.0.7, tuckey urlrewrite 3.2.0, Spring 3.0.6 Windows 7 JDK 1.5.0_17 Maven 2.2.1 apache-tomcat-6.0.32

我的环境:AppFuse 2.1 with Spring MVC, iBatis, Spring Security 3.0.7, tuckey urlrewrite 3.2.0, Spring 3.0.6 Windows 7 JDK 1.5.0_17 Maven 2.2.1 apache-tomcat-6.0.32

Security.xml (before conversion, everything is OK.)

Security.xml(转换前,一切正常。)

…
<http auto-config="true" lowercase-comparisons="false">
    <intercept-url pattern="/images/**" filters="none"/>
    <intercept-url pattern="/styles/**" filters="none"/>
    <intercept-url pattern="/scripts/**" filters="none"/>
    <intercept-url pattern="/app/admin/**" access="ROLE_ADMIN"/>
    <intercept-url pattern="/app/passwordHint*" access="ROLE_ANONYMOUS,ROLE_ADMIN,ROLE_USER"/>
    <intercept-url pattern="/app/signup*" access="ROLE_ANONYMOUS,ROLE_ADMIN,ROLE_USER"/>
    <intercept-url pattern="/app/**" access="ROLE_ADMIN,ROLE_USER"/>
    <form-login login-page="/login" authentication-failure-url="/login?error=true"
                login-processing-url="/j_spring_security_check"/>
    <remember-me user-service-ref="userDao" key="e37f4b31-0c45-11dd-bd0b-0800200c9a66"/>
</http>
<authentication-manager alias="authenticationManager">
    <authentication-provider user-service-ref="userDao">
        <password-encoder ref="passwordEncoder"/>
    </authentication-provider>
</authentication-manager>
…

Security.xml (after replacing http namespace, "j_spring_security_check" not found)

Security.xml(替换http命名空间后,找不到“j_spring_security_check”)

<beans:bean id="springSecurityFilterChain"
            class="org.springframework.security.web.FilterChainProxy">
    <filter-chain-map path-type="ant">
        <filter-chain pattern="/images/**" filters="none"/>
        <filter-chain pattern="/styles/**" filters="none"/>
        <filter-chain pattern="/scripts/**" filters="none"/>
        <filter-chain pattern="/app/**" filters="
             securityContextPersistenceFilter,
             authenticationProcessingFilter,
             exceptionTranslationFilter,
        filterSecurityInterceptor"/>
    </filter-chain-map>
</beans:bean>

<beans:bean id="securityContextPersistenceFilter"
            class="org.springframework.security.web.context.SecurityContextPersistenceFilter">
</beans:bean>
<beans:bean id="authenticationProcessingFilter"
            class="org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter">
    <beans:property name="authenticationManager" ref="authenticationManager"/>
    <beans:property name="authenticationSuccessHandler" ref="authenticationSuccessHandler"/>
    <beans:property name="authenticationFailureHandler" ref="authenticationFailureHandler"/>
    <beans:property name="filterProcessesUrl" value="/j_spring_security_check"/>
</beans:bean>
<beans:bean id="authenticationSuccessHandler"
            class="org.springframework.security.web.authentication.SimpleUrlAuthenticationSuccessHandler">
    <beans:property name="defaultTargetUrl" value="/mainMenu"/>
</beans:bean>
<beans:bean id="authenticationFailureHandler"
            class="org.springframework.security.web.authentication.SimpleUrlAuthenticationFailureHandler">
    <beans:property name="defaultFailureUrl" value="/login.jsp"/>
</beans:bean>
<beans:bean id="exceptionTranslationFilter"
            class="org.springframework.security.web.access.ExceptionTranslationFilter">
    <beans:property name="authenticationEntryPoint" ref="authenticationEntryPoint"/>
    <beans:property name="accessDeniedHandler" ref="accessDeniedHandler"/>
</beans:bean>

<beans:bean id="authenticationEntryPoint"
            class="org.springframework.security.web.authentication.LoginUrlAuthenticationEntryPoint">
    <beans:property name="loginFormUrl" value="/login.jsp"/>
</beans:bean>

<beans:bean id="accessDeniedHandler"
            class="org.springframework.security.web.access.AccessDeniedHandlerImpl">
    <beans:property name="errorPage" value="/403.jsp"/>
</beans:bean>


<beans:bean id="filterSecurityInterceptor"
            class="org.springframework.security.web.access.intercept.FilterSecurityInterceptor">
    <beans:property name="authenticationManager" ref="authenticationManager"/>
    <beans:property name="accessDecisionManager" ref="accessDecisionManager"/>
    <beans:property name="securityMetadataSource">
        <filter-security-metadata-source>
            <intercept-url pattern="/app/admin/**" access="ROLE_ADMIN"/>
            <intercept-url pattern="/app/passwordHint*" access="ROLE_ANONYMOUS,ROLE_ADMIN,ROLE_USER"/>
            <intercept-url pattern="/app/signup*" access="ROLE_ANONYMOUS,ROLE_ADMIN,ROLE_USER"/>
            <intercept-url pattern="/app/**" access="ROLE_ADMIN,ROLE_USER"/>
        </filter-security-metadata-source>
    </beans:property>
</beans:bean>
<beans:bean id="myFilterInvocationSecurityMetadataSource"
            class="com.tangram.ebiz.webapp.authentication.MyFilterInvocationSecurityMetadataSource">
</beans:bean>


<beans:bean id="accessDecisionManager"
            class="org.springframework.security.access.vote.AffirmativeBased">
    <beans:property name="decisionVoters">
        <beans:list>
            <beans:bean class="org.springframework.security.access.vote.RoleVoter">
                <beans:property name="rolePrefix" value="ROLE_"/>
            </beans:bean>
            <beans:bean
                    class="org.springframework.security.access.vote.AuthenticatedVoter"/>
        </beans:list>
    </beans:property>
</beans:bean>

<authentication-manager alias="authenticationManager">
    <authentication-provider user-service-ref="userDao">
        <password-encoder ref="passwordEncoder"/>
    </authentication-provider>
</authentication-manager>

Login.jsp

登录.jsp

    <form method="post" id="loginForm" action="<c:url value='/j_spring_security_check'/>" onsubmit="saveUsername(this);return validateForm(this)">
…
        <li>
            <label for="j_username" class="required desc"><fmt:message key="label.username"/> <span class="req">*</span></label>
            <input type="text" class="text medium" name="j_username" id="j_username" tabindex="1" />
        </li>
        <li>
            <label for="j_password" class="required desc"><fmt:message key="label.password"/> <span class="req">*</span></label>
            <input type="password" class="text medium" name="j_password" id="j_password" tabindex="2" />
        </li>
…
    </form>

Urlrewrite.xml

urlrewrite.xml

<urlrewrite default-match-type="wildcard">
…
<!-- Add rules here for anything that shouldn't be served up by Spring MVC. -->
<rule>
    <from>/</from>
    <to type="redirect" last="true">mainMenu</to>
</rule>
<rule>
    <from>/app/**</from>
    <to last="true" type="redirect">%{context-path}/</to>
</rule>
<rule>
    <from>/j_spring_security_check**</from>
    <to last="true">/j_spring_security_check</to>
</rule>
…

<!-- Spring MVC -->
<rule>
    <from>/**</from>
    <to>/app/</to>
</rule>
<outbound-rule>
    <from>/app/**</from>
    <to>/</to>
</outbound-rule>
…
</urlrewrite>

回答by Ben Wu

Finally I fixed it myself.

最后我自己修好了。

While debugging the doFilter() method of SecurityContextPersistenceFilter without Spring security namespace, I found that contextBeforeChainExecution and contextAfterChainExecution were null. But when debugging the program with namespace the value of both of them were something about Anonymous.

在调试没有Spring安全命名空间的SecurityContextPersistenceFilter的doFilter()方法时,发现contextBeforeChainExecution和contextAfterChainExecution为null。但是在调试带有命名空间的程序时,它们的值都是关于匿名的。

I added “/j_spring_security_check” and “/login” with “IS_AUTHENTICATED_ANONYMOUSLY” access in securityMetadataSource as shown below and the problem was solved.

我在 securityMetadataSource 中添加了“/j_spring_security_check”和“/login”以及“IS_AUTHENTICATED_ANONYMOUSLY”访问权限,如下所示,问题解决了。

    <beans:property name="securityMetadataSource">
        <filter-security-metadata-source>
            <intercept-url pattern="/j_spring_security_check" access="IS_AUTHENTICATED_ANONYMOUSLY"/>
            <intercept-url pattern="/login" access="IS_AUTHENTICATED_ANONYMOUSLY"/>
            <intercept-url pattern="/app/admin/**" access="ROLE_ADMIN"/>
            <intercept-url pattern="/app/passwordHint*" access="ROLE_ANONYMOUS,ROLE_ADMIN,ROLE_USER"/>
            <intercept-url pattern="/app/signup*" access="ROLE_ANONYMOUS,ROLE_ADMIN,ROLE_USER"/>
            <intercept-url pattern="/app/**" access="ROLE_ADMIN,ROLE_USER"/>
        </filter-security-metadata-source>
    </beans:property>

This blog really helped me a lot: http://blog.springsource.com/2010/03/06/behind-the-spring-security-namespace/

这个博客真的帮了我很多:http: //blog.springsource.com/2010/03/06/behind-the-spring-security-namespace/