Вопрос

i'm working with spring security 3.1.3 in a spring 3.2.0 project. I've configured two entry points for my security using spring security. The idea is to have a url like /enterprise_login where enterprise users should log in and other url like /login where normal users do their log in action. In my security configuration i've the next code

<security:global-method-security jsr250-annotations="enabled" pre-post-annotations="enabled" secured-annotations="enabled" />

<security:http pattern="/enterprise/**" auto-config="false" use-expressions="true" authentication-manager-ref="autenticationManagerUserEnterprise">
    <security:intercept-url pattern="/enterprise/**" access="hasRole('ROLE_ENTERPRISE')" />
    <security:intercept-url pattern="/enterprise_login" access="isAnonymous()" />
    <security:form-login login-page="/enterprise_login" default-target-url="/" authentication-failure-url="/empresas_login_error" login-processing-url="/enterprise_login_process" />
    <security:logout logout-success-url="/" delete-cookies="JSESSIONID"/>
    <security:remember-me user-service-ref="enterpriseAuthenticationProvider"/>
    <security:session-management invalid-session-url="/">
        <security:concurrency-control max-sessions="2" error-if-maximum-exceeded="true" />
    </security:session-management>
</security:http>

<security:http pattern="/**" auto-config="false" use-expressions="true" authentication-manager-ref="autenticationManagerUser">
    <security:intercept-url pattern="/**" access="permitAll" />
    <security:form-login login-page="/login" default-target-url="/" authentication-failure-url="/login_error" />
    <security:logout logout-success-url="/" delete-cookies="JSESSIONID"/>
    <security:remember-me user-service-ref="UserAuthenticationProvider"/>
    <security:session-management invalid-session-url="/">
        <security:concurrency-control max-sessions="2" error-if-maximum-exceeded="true" />
    </security:session-management>
</security:http>

<security:authentication-manager id="autenticationManagerUserEnterprise">
    <security:authentication-provider user-service-ref="enterpriseAuthenticationProvider">
        <security:password-encoder hash="plaintext"></security:password-encoder>
    </security:authentication-provider>
</security:authentication-manager>

<security:authentication-manager id="autenticationManagerUser">
    <security:authentication-provider user-service-ref="UserAuthenticationProvider">
        <security:password-encoder hash="plaintext"></security:password-encoder>
    </security:authentication-provider>
</security:authentication-manager>

<bean id="enterpriseAuthenticationProvider" class="com.test.security.enterpriseAuthenticationProvider"></bean>
<bean id="UserAuthenticationProvider" class="com.test.security.UserDetailsServiceImp"></bean>

Then when I go to /enterprise_login form and submit the login data I get a "HTTP 405 - Request method 'POST' not supported" throwed by tomcat in the url /enterprise_login_process (the url configured to act as login-processing-url. I can't figure out where the problem is, any help is really appreciated.

PD: My web.xml looks like:

<web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee"
     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
     xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
        http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">

<display-name>AT-2</display-name>

<context-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>
        /WEB-INF/spring-config.xml
    </param-value>
</context-param>

<context-param>
    <param-name>webAppRootKey</param-name>
    <param-value>tutorial.root</param-value>
</context-param>

<listener>
    <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>

<listener>
    <listener-class>org.springframework.security.web.session.HttpSessionEventPublisher</listener-class>
</listener>

<filter>
    <filter-name>springSecurityFilterChain</filter-name>
    <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
</filter>

<filter-mapping>
    <filter-name>springSecurityFilterChain</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>

<servlet>
    <servlet-name>mvc-dispatcher</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    <init-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>/WEB-INF/spring-config.xml</param-value>
    </init-param>
    <load-on-startup>0</load-on-startup>
</servlet>

<servlet-mapping>
    <servlet-name>mvc-dispatcher</servlet-name>
    <url-pattern>/</url-pattern>
</servlet-mapping>

<welcome-file-list>
    <welcome-file>index.jsp</welcome-file>
</welcome-file-list>

Это было полезно?

Решение

The issue is that the first configuration currently only matches on URLs that start with "/enterprise/" and the URL to process authentication is configured as "/enterprise_login_process". This means that submitting a POST to "/enterprise_login_process" will submit to the second configuration which is not trying to authenticate "/enterprise_login_process".

To fix this you need to ensure the http@pattern and the login-processing-url are aligned. For example:

<security:http pattern="/enterprise/**" 
      auto-config="false" 
      use-expressions="true" 
      authentication-manager-ref="autenticationManagerUserEnterprise">
    <security:intercept-url pattern="/enterprise/login" 
          access="isAnonymous()" />
    <security:intercept-url pattern="/**" 
          access="hasRole('ROLE_ENTERPRISE')" />
    <security:form-login login-page="/enterprise/login" 
          default-target-url="/" 
          authentication-failure-url="/enterprise/login?error" 
          login-processing-url="/enterprise/login_process" />
    <security:logout logout-success-url="/" 
          delete-cookies="JSESSIONID"/>
    <security:remember-me 
          user-service-ref="enterpriseAuthenticationProvider"/>
    <security:session-management invalid-session-url="/">
        <security:concurrency-control max-sessions="2" 
              error-if-maximum-exceeded="true" />
    </security:session-management>
</security:http>

You will observe that I modified the code to ensure all URLs within the block start with "/enterprise/". This also means that you will need to ensure that your login form for enterprise is updated to POST to "/enterprise/login_process".

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top