0
votes

I have integrated our web application using spring security with spring-security-saml 2.0. The Integration works fine I can get the success authentication message from IDP however when i get redirected to my web application pages. An application creates its own SecurityContextHolder and I get the user as anonymous Authentication object is not the SAMLAuthentication which is created by SAMLAuthenticationProvider.

Need to know how can we integrate the spring security of an existing web application after we get the authentication success or error?.

2

2 Answers

0
votes

SAMLAuthenticationProvider validates the incoming SAML response, and returns an object of ExpiringUsernameAuthenticationToken, which is populated with the help of incoming SAML assertion(e.g UserDetails with claims and Token expiry time with SAML token expiry time). After this point, Spring security refers to this token for each and every request it receives to get user information.

To integrate Spring SAML with your existing spring security application, you may need to have custom implementation of user-context-mapper which can map the authorities in incoming SAML response to your local authorities(Groups).

Hope this helps.

0
votes

In your configuration for the SAML handler, you need to set the AuthenticationProvider. This is what will turn the SAMLAuthentication into the user details for your implementation.

@Configuration
public class WebSecuritySamlConfig extends WebSecurityConfigurerAdapter {
    @Override
    protected void configure(final AuthenticationManagerBuilder auth) {
        auth
            .authenticationProvider(samlAuthenticationProvider());
    }

    @Bean
    public SAMLAuthenticationProvider samlAuthenticationProvider() {
        final SAMLAuthenticationProvider samlAuthenticationProvider = new SAMLAuthenticationProvider();
        samlAuthenticationProvider.setUserDetails            (new MySamlUserDetailsService());
        samlAuthenticationProvider.setForcePrincipalAsString (false);
        return samlAuthenticationProvider;
    }
}

The user details service that is set in the provider can do whatever you need it to in order to get the UserDetails for the user the SAMLCredential represents. Very important: the object returned by this function must include a correct implementation of the getAuthorities method in order for the rest of Spring security to work. It would be best to just implement the UserDetails interface on the returned object to make sure that you implemented it correctly. If you do not include this implementation, you may notice that all pages return an access denied page since no authorities were set.

public class MySamlUserDetailsService implements SAMLUserDetailsService {
    @Override
    public Object loadUserBySAML(final SAMLCredential samlCredential) throws UsernameNotFoundException {
        final String      username    = samlCredential.getAttributeAsString("UserID");
        final UserDetails userDetails = myUserDetailsService.getUserData(username);
        return userDetails;
    }
}

Once you've added that, the Spring security functionality should function as normal with the UserDetails this process created. Here's the documentation on the SAMLAuthenticationProvider from Spring docs which states all of this information and more.

I also have my success handlers for the SAML use the same success handlers that my non-SAML logins use. This ensures that both types of logins follow the same path once the UserDetails have been determined. The code below is also placed in the WebSecuritySamlConfig from above:

@Bean
public SAMLProcessingFilter samlWebSSOProcessingFilter() throws Exception {
    final SAMLProcessingFilter samlWebSSOProcessingFilter = new SAMLProcessingFilter();
    samlWebSSOProcessingFilter.setAuthenticationManager        (authenticationManager());
    samlWebSSOProcessingFilter.setAuthenticationSuccessHandler (authenticationSuccessHandler);
    samlWebSSOProcessingFilter.setAuthenticationFailureHandler (failureRedirectHandler());
    return samlWebSSOProcessingFilter;
}

@Bean
public SAMLWebSSOHoKProcessingFilter samlWebSSOHoKProcessingFilter() throws Exception {
    final SAMLWebSSOHoKProcessingFilter filter = new SAMLWebSSOHoKProcessingFilter();
    filter.setAuthenticationManager        (authenticationManager());
    filter.setAuthenticationSuccessHandler (authenticationSuccessHandler);
    filter.setAuthenticationFailureHandler (failureRedirectHandler());
    return filter;
}