java – Configuring Spring Security 3.x to have multiple entry points

java – Configuring Spring Security 3.x to have multiple entry points

You dont need to create /j_spring_security_check_for_employee and /j_security_check_for_customer filterProcessingUrl.

The default one will work just fine with radio button field idea.

In the custom login LoginFilter, you need to create different tokens for employee and customer.

Here are the steps:

  1. Use default UsernamePasswordAuthenticationToken for employee login.

  2. Create CustomerAuthenticationToken for customer login. Extend AbstractAuthenticationToken so that its class type is distinct from UsernamePasswordAuthenticationToken.

  3. Define a custom login filter:

    <security:http>
        <security:custom-filter position=FORM_LOGIN_FILTER ref=customFormLoginFilter />
    </security:http>
    
  4. In customFormLoginFilter, override attemptAuthentication as follows (pseudo code):

    if (radiobutton_param value employee) {
        UsernamePasswordAuthenticationToken authRequest = new UsernamePasswordAuthenticationToken(username, password);
        setDetails(whatever);
        return getAuthenticationManager().authenticate(authRequest);
    } else if (radiobutton_param value customer) {
        CustomerAuthenticationToken authRequest = new CustomerAuthenticationToken(username, password);
        setDetails(whatever);
        return getAuthenticationManager().authenticate(authRequest);
    }
    
  5. Override supports method in EmployeeCustomAuthenticationProvider to support UsernamePasswordAuthenticationToken.

  6. Override supports method in CustomerCustomAuthenticationProvider to support CustomerAuthenticationToken.

    @Override
    public boolean supports(Class<?> authentication) {
        return (CustomerAuthenticationToken.class.isAssignableFrom(authentication));
    }
    
  7. Use both providers in authentication-manager:

    <security:authentication-manager alias=authenticationManager>
        <security:authentication-provider ref=employeeCustomAuthenticationProvider  />
        <security:authentication-provider ref=customerCustomAuthenticationProvider  />
    </security:authentication-manager>
    

You can define several AuthenticationProcessingFilter filters. Each of them can have different URL like /j_security_check_for_employee and /j_security_check_for_customer. Here is example of the security application context that demonstrates this idea:

<bean id=myfilterChainProxy class=org.springframework.security.util.FilterChainProxy>
     <security:filter-chain-map pathType=ant>
         <security:filter-chain pattern=/** filters=authenticationProcessingFilterForCustomer, authenticationProcessingFilterForEmployee, ... />
     </security:filter-chain-map>
</bean>


<bean id=authenticationProcessingFilterForCustomer class=org.springframework.security.web.authentication.AuthenticationProcessingFilter>
    <property name=authenticationManager ref=authenticationManagerForCustomer/>
    <property name=filterProcessesUrl value=/j_security_check_for_customer/>
</bean>

<bean id=authenticationProcessingFilterForEmployee class=org.springframework.security.web.authentication.AuthenticationProcessingFilter>
    <property name=authenticationManager ref=authenticationManagerForEmployee/>
    <property name=filterProcessesUrl value=/j_security_check_for_employee/>
</bean>

<bean id=authenticationManagerForCustomer class=org.springframework.security.authentication.ProviderManager>
    <property name=providers>
        <list>
            <bean class=org.acegisecurity.providers.dao.DaoAuthenticationProvider>
                <property name=userDetailsService>
                    <ref bean=customerUserDetailsServiceThatUsesDB/>
                </property>
            </bean>
        </list>
    </property>
</bean>

<bean id=authenticationManagerForEmployee class=org.springframework.security.authentication.ProviderManager>
    <property name=providers>
        <list>
            <bean class=org.springframework.security.authentication.dao.DaoAuthenticationProvider>
                <property name=userDetailsService>
                    <ref bean=employeeUserDetailsServiceThatUsesLDAP/>
                </property>
            </bean>
        </list>
    </property>
</bean>

As you can see, in this scenario you have also different UserDetailServices – for DB auth and LDAP.

I think its good idea to have different auth URLs for customers and employee (especially if they use different authentication strategies). You can even have different login pages for them.

java – Configuring Spring Security 3.x to have multiple entry points

For Java Configuration reference

As i keen to write here java configuration way of implementing the same technique to help people who is not familiar with xml configuration but i dont want to hijack this thread beauty with such a long answer of java configuration code.

People who wants to achieve the same with java configuration(Annotation based) can refer my self answered question link is given below and also you can find my github repository link for the code in the answer.

For Annotation based configuration code refer my answer here
Multiple AuthenticationProvider with different UsernamePasswordAuthToken to authenticate different login forms without fallback authentication

Leave a Reply

Your email address will not be published. Required fields are marked *