The spring saml authentication flow is not happening on the first request received from a given browser. Subsequent requests do initiate the spring saml authentication flow and everything works fine from there, but it should work on the first request as well.
The first request to http://localhost:8080/ does not get a 302 redirect to http://localhost:8080/saml2/authenticate/okta but all subsequent requests do.
Here's my security filter chain...
@Bean
public SecurityFilterChain samlFilterChain(HttpSecurity http) throws Exception {
HttpSessionCsrfTokenRepository repository = new HttpSessionCsrfTokenRepository();
repository.setHeaderName("X-XSRF-TOKEN");
http
.securityMatcher(
new OrRequestMatcher(
new NegatedRequestMatcher(new AntPathRequestMatcher(Rest.API_URL + "/**")),
new AntPathRequestMatcher("/login","/")
)
)
.authorizeHttpRequests(authorize -> authorize
.requestMatchers(
new OrRequestMatcher(
new NegatedRequestMatcher(new AntPathRequestMatcher(Rest.API_URL + "/**")),
new AntPathRequestMatcher("/login","/")
)
).authenticated()
)
.saml2Login(saml2 -> saml2.authenticationManager(
new RmsSaml2UserDetailsAuthenticationManager(
userDetailsService,
authUserService,
authRolesService,
dataGroupRepository
)))
.saml2Logout(withDefaults())
.logout(httpSecurityLogoutConfigurer ->
httpSecurityLogoutConfigurer.logoutUrl("/security/logout")
.permitAll().logoutSuccessHandler(new LogoutSuccessHandler() {
@Override
public void onLogoutSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication) throws IOException, ServletException {
response.setStatus(200);
response.setHeader("Custom-Location", "https://nasdaq.okta.com/");
}
})
)
.sessionManagement(httpSecuritySessionManagementConfigurer ->
httpSecuritySessionManagementConfigurer
.invalidSessionStrategy(new InvalidSessionStrategy() {
@Override
public void onInvalidSessionDetected(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException {
response.setStatus(200);
response.setHeader("Custom-Location", "https://nasdaq.okta.com/");
}
})
)
.csrf(httpSecurityCsrfConfigurer ->
httpSecurityCsrfConfigurer
.csrfTokenRepository(repository)
)
.addFilterAfter(xsrfHeaderFilter(), CsrfFilter.class)
.anonymous(httpSecurityAnonymousConfigurer ->
httpSecurityAnonymousConfigurer.disable())
;
return http.build();
}
I also wanted to provide the logs for the first and subsequent requests, but that makes this post too long and it gets rejected. I've been banging my head against this wall for a while now. Any help would be appreciated. Thanks!