9

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

Manas Sahu
  • 91
  • 1
  • 3
  • Perhaps related to or duplicate of http://stackoverflow.com/questions/4783063/configuring-spring-security-3-x-to-have-multiple-entry-points? – Raghuram Sep 27 '11 at 10:07
  • The resolved solution for "Configuring Spring Security 3.x to have multiple entry points" is having a Single Entry Point and Single Successful Page for different types of User. The issue i have multiple entry point and each having own Successful Page. – Manas Sahu Sep 28 '11 at 04:31
  • @ManasSahu Can you add code of 'supports()' methods of your custom authentication providers in your question? – Ritesh Sep 28 '11 at 12:25
  • @Ritesh, I've added the Support method details in top section. While debug I found the request hits support method, but it doesn't hit the authenticate(Authentication authentication) method. – Manas Sahu Sep 29 '11 at 15:10

3 Answers3

2

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
Xilang
  • 1,513
  • 3
  • 18
  • 36
1

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

imrabti
  • 285
  • 4
  • 11
0

You should point the authenticationManager ref in 'authenticationProcessingFilterForCustomer' and 'authenticationProcessingFilterForEmployee' beans to correct bean i.e. 'authenticationManager' which has providers. No need to define 'authenticationManagerForCustomer' and 'authenticationManagerForEmployee' beans.

Sunil Chavan
  • 2,934
  • 4
  • 25
  • 24