Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Spring 3.x configuration for multiple login pages

I'm using Spring 3.1 for authentication purpose.

My requirement:

  • Two different login pages. One for Customer and other for Employee.
  • Each after successful authentication, will be forwarded to respective successful URL.

My spring security configuration:

<sec:http pattern="/resources/**" security="none" />
<sec:http auto-config="true">
    <sec:intercept-url pattern="/**" access="IS_AUTHENTICATED_ANONYMOUSLY" />
    <sec:intercept-url pattern="/customer/**" access="ROLE_CUSTOMER" />
    <sec:intercept-url pattern="/employee/**" access="ROLE_EMPLOYEE" />
</sec:http>

<bean id="springSecurityFilterChain" class="org.springframework.security.web.FilterChainProxy">
    <sec:filter-chain-map path-type="ant">
        <sec:filter-chain pattern="/**"
            filters="authenticationProcessingFilterForCustomer,authenticationProcessingFilterForEmployee" />
    </sec:filter-chain-map>
</bean>

<bean id="authenticationProcessingFilterForCustomer"
    class="org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter">
    <property name="authenticationManager" ref="authenticationManagerForCustomer" />
    <property name="filterProcessesUrl" value="/j_spring_security_check_for_customer" />
    <property name="authenticationSuccessHandler" ref="customerSuccessHandler" />
    <property name="authenticationFailureHandler" ref="customerFailureHandler" />
</bean>
<bean id="customerSuccessHandler"
    class="org.springframework.security.web.authentication.SavedRequestAwareAuthenticationSuccessHandler">
    <property name="defaultTargetUrl" value="/customer/index.html" />
</bean>
<bean id="customerFailureHandler"
    class="org.springframework.security.web.authentication.SimpleUrlAuthenticationFailureHandler">
    <property name="defaultFailureUrl" value="/customer.html?login_error=1" />
</bean>
<bean id="authenticationManagerForCustomer"
    class="org.springframework.security.authentication.ProviderManager">
    <property name="providers">
        <list>
            <ref bean="customCustomerAuthenticationProvider" />
        </list>
    </property>
</bean>
<bean id="customCustomerAuthenticationProvider" class="com.edu.CustomerCustomAuthenticationProvider">
    <property name="userDetailsService">
        <bean class="com.edu.CustomerUserDetailsService" />
    </property>
</bean>

<bean id="authenticationProcessingFilterForEmployee"
    class="org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter">
    <property name="authenticationManager" ref="authenticationManagerForEmployee" />
    <property name="filterProcessesUrl" value="/j_spring_security_check_for_employee" />
    <property name="authenticationSuccessHandler" ref="employeeSuccessHandler" />
    <property name="authenticationFailureHandler" ref="employeeFailureHandler" />
</bean>
<bean id="employeeSuccessHandler"
    class="org.springframework.security.web.authentication.SavedRequestAwareAuthenticationSuccessHandler">
    <property name="defaultTargetUrl" value="/employee/index.html" />
</bean>
<bean id="employeeFailureHandler"
    class="org.springframework.security.web.authentication.SimpleUrlAuthenticationFailureHandler">
    <property name="defaultFailureUrl" value="/employee.html?login_error=1" />
</bean>
<bean id="authenticationManagerForEmployee"
    class="org.springframework.security.authentication.ProviderManager">
    <property name="providers">
        <list>
            <ref bean="customEmployeeAuthenticationProvider" />
        </list>
    </property>
</bean>
<bean id="customEmployeeAuthenticationProvider" class="com.edu.EmployeeCustomAuthenticationProvider">
    <property name="userDetailsService">
        <bean class="com.edu.EmployeeUserDetailsService" />
    </property>
</bean>

<sec:authentication-manager alias="authenticationManager">
    <sec:authentication-provider ref="customCustomerAuthenticationProvider" />
    <sec:authentication-provider ref="customEmployeeAuthenticationProvider" />
</sec:authentication-manager>

Both CustomAuthenticationProvider have implemented Support method as follows:

public boolean supports(Class<? extends Object> authentication) {
    return UsernamePasswordAuthenticationToken.class.isAssignableFrom(authentication);
}

After launching application, while trying to authenticate, the message displayed in login pages are:

Your login attempt was not successful, try again.
Reason: No AuthenticationProvider found for org.springframework.security.authentication.UsernamePasswordAuthenticationToken

I'm using Spring 3.1. Any help appreciated.

Thank You

like image 707
Manas Sahu Avatar asked Sep 24 '11 15:09

Manas Sahu


2 Answers

I have done similar things in grails, what you need is:

  1. extend UsernamePasswordAuthenticationToken, create two sub-class for employee and customer, say EmployeeUsernamePasswordAuthenticationToken and CustomerUsernamePasswordAuthenticationToken
  2. extend UsernamePasswordAuthenticationFilter, to create different instance of EmployeeUsernamePasswordAuthenticationToken or CustomerUsernamePasswordAuthenticationToken based on current auth request
  3. extend AuthenticationProvider for employee and custoner, create two class say EmployeeAuthenticationProvider and CustomerAuthenticationProvider, overwrite each class' supports method to support its target UsernamePasswordAuthenticationToken
  4. you only need one authenticationManager, register both provide into it
  5. only need one AuthenticationSuccessHandler, you can decide which url want to go in it
  6. I also create a my own instance of AuthenticationEntryPoint to support multi entrypoint
like image 163
Xilang Avatar answered Nov 16 '22 00:11

Xilang


Beginning from Spring 3.1 you have as many configuration as you want : https://jira.springsource.org/browse/SEC-1171

like image 28
imrabti Avatar answered Nov 16 '22 01:11

imrabti