Configuring Spring Security 3.X to Have Multiple Entry Points

Configuring Spring Security 3.x to have multiple entry points

You don't 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>

Spring Security multiple entry points - login process URL not found

Your login processing URL /mobile_login_processing_url is unavailable.

You configured a formLogin, which adds a UsernamePasswordAuthenticationFilter for a HttpSecurity, see FormLoginConfigurer:

The following Filters are populated

  • UsernamePasswordAuthenticationFilter

but your HttpSecurityis restricted to the pattern /mobile/**, see HttpSecurity#antMatcher:

Allows configuring the HttpSecurity to only be invoked when matching the provided ant pattern.

so with URL /mobile_login_processing_url the HttpSecurityis not invoked and therefore the UsernamePasswordAuthenticationFilter is never applied. Without this filter, the form login is not processible, see UsernamePasswordAuthenticationFilter:

Processes an authentication form submission.

You have to change your login processing URL to /mobile/mobile_login_processing_url. See your modified configuration:

@Configuration
@Order(1)
ublic static class MobileSecurityConfiguration extends WebSecurityConfigurerAdapter {

@Override
protected void configure(HttpSecurity http) throws Exception {

http
.antMatcher("/mobile/**")
.authorizeRequests()
.anyRequest().hasRole("MOBILE")
.and()
.formLogin()
.loginPage("/mobile_login")
.loginProcessingUrl("/mobile/mobile_login_processing_url")
.usernameParameter("ssoId")
.passwordParameter("password")
.defaultSuccessUrl("/mobile/menu")
.and()
.logout()
.logoutUrl("/mobile_logout")
.logoutSuccessUrl("/mobile_login?logout")
.deleteCookies("JSESSIONID")
.and()
.exceptionHandling()
.accessDeniedPage("/Access_Denied")
.defaultAuthenticationEntryPointFor(authenticationEntryPoint(), new AntPathRequestMatcher("/mobile/**"));
}

@Bean
Public AuthenticationEntryPoint authenticationEntryPoint(){
return new LoginUrlAuthenticationEntryPoint("/mobile_login");
}
}

Spring Security Multi Entry point with OAuth2

The SecurityFilterChain is what initiates the Authorization Request from "/oauth2/authorization/google".

Since "/oauth2/authorization/google" doesn't match "/api/v1/system/**", "/api/v1/access/**" or "/api/v1/**", the SecurityFilterChain is not called for that request, which means the Authorization Request is not initiated.

You can change the base URI used for authorization requests to match the path you've specified for the SecurityFilterChain (the default is "/oauth2/authorization/{registrationId}").

http
.antMatcher("/api/v1/access/**")
.authorizeRequests(authorize -> authorize
.anyRequest().authenticated()
)
.oauth2Login(oauth2 -> oauth2
.authorizationEndpoint(ae -> ae
.baseUri("/api/v1/access/oauth2/authorization/{registrationId}")
)
);


Related Topics



Leave a reply



Submit