Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

Tags:

spring

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.

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

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

…
<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)

<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

    <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 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}/$1</to>
</rule>
<rule>
    <from>/j_spring_security_check**</from>
    <to last="true">/j_spring_security_check$1</to>
</rule>
…

<!-- Spring MVC -->
<rule>
    <from>/**</from>
    <to>/app/$1</to>
</rule>
<outbound-rule>
    <from>/app/**</from>
    <to>/$1</to>
</outbound-rule>
…
</urlrewrite>
like image 797
Ben Wu Avatar asked Oct 05 '11 12:10

Ben Wu


People also ask

Does Spring Security use default login form?

In this configuration Spring Security will render a default log in page. Most production applications will require a custom log in form. The configuration below demonstrates how to provide a custom log in form. public SecurityFilterChain filterChain(HttpSecurity http) { http .

What is J_spring_security_check?

j_spring_security_check is a Servlet where the actual authentication is made and you must map the action of your login form to this Servlet.

Can we use Spring Security in Spring MVC?

To enable Spring Security integration with Spring MVC add the @EnableWebSecurity annotation to your configuration. Spring Security provides the configuration using Spring MVC's WebMvcConfigurer.


1 Answers

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.

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

    <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/

like image 67
Ben Wu Avatar answered Nov 15 '22 07:11

Ben Wu