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;
}