I have to add OpenId Connect as a login option to our application. The application is running spring boot 3.1.2 and the client is a SPA, currently it is possible to redirect to the open id connect login page and get back to our application when the login is succesful, but I can't figure out how to find out who the user is on the subsequent request, the only information the client sends back is the JSESSIONID.
I need to be able to identify the user on the subsequent requests to check the permissions of the user in our local permission manager. I got recommended to link the sessionId to a User and look up the user via the sessionId on the subsequence request. Is this the correct way to handle the identification?
Is there a build in way to do this in spring security (Get the openIdConnection user-information from the session) I have overlooked or do I have to implement a link between a active session and the user. I have not been able a easy way to do this and it feels like I'm trying to work around Spring and not with it.
I have not been able to identify the current session in my OidcUserService, this is the location I have been able to find the user information needed to identify the local user which is linked to the openId user. I have also tried to add a filter after the OAuth2LoginAuthenticationFilter, however here it is not possible to identify the user from the open id connection, the SecurityContextHolder.getContext().getAuthentication() is null. I have also tried to set the authentication in SecurityContextHolder inside the OidcUserService however when setting the authentication I am still not able to retrieve the user in the filter after OAuth2LoginAuthenticationFilter and my filter is running after the OidcUserService.
security:
oauth2:
client:
registration:
open-id-connect-client:
client-id: ...
client-secret: ...
redirect-uri: http://localhost:8088/login/oauth2/code/open-id-connect-client
client-name: open-id-connect-client
scope:
- openid
- email
- profile
authorization-grant-type: authorization_code
provider:
open-id-connect-client:
issuer-uri: ...
public class SecurityConfig {
@Autowired
AuthenticationService authenticationService;
private final UserAuthenticationEntryPoint userAuthenticationEntryPoint;
private final UserAuthProvider userAuthenticationProvider;
public SecurityConfig(UserAuthenticationEntryPoint userAuthenticationEntryPoint,
UserAuthProvider userAuthenticationProvider) {
this.userAuthenticationEntryPoint = userAuthenticationEntryPoint;
this.userAuthenticationProvider = userAuthenticationProvider;
}
@Bean
public AuthenticationManager authenticationManager(){
UserAuthProvider authProvider = new UserAuthProvider(authenticationService);
return new ProviderManager(authProvider);
}
@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
return http.exceptionHandling(httpSecurityExceptionHandlingConfigurer -> httpSecurityExceptionHandlingConfigurer
.authenticationEntryPoint(new UserAuthenticationEntryPoint())
.authenticationEntryPoint(new RedirectAuthenticationEntryPoint())
)
.addFilterBefore(new UsernamePasswordAuthFilter(this.userAuthenticationProvider), BasicAuthenticationFilter.class)
.addFilterBefore(new CookieAuthenticationFilter(this.userAuthenticationProvider), UsernamePasswordAuthFilter.class)
.addFilterAfter(new AfterOAuth2LoginAuthenticationFilter(), OAuth2LoginAuthenticationFilter.class)
.addFilterBefore(new MultipleReadEnableFilter(), CookieAuthenticationFilter.class)
.addFilterBefore(new RequestLoggingFilter(), MultipleReadEnableFilter.class)
.csrf(AbstractHttpConfigurer::disable)
.sessionManagement(httpSecuritySessionManagementConfigurer -> httpSecuritySessionManagementConfigurer.sessionCreationPolicy(SessionCreationPolicy.STATELESS))
.logout(httpSecurityLogoutConfigurer -> httpSecurityLogoutConfigurer.deleteCookies(CookieAuthenticationFilter.COOKIE_NAME).deleteCookies("JSESSIONID"))
.authorizeHttpRequests((authorize) -> authorize
.requestMatchers(HttpMethod.POST, "/rest/login").permitAll()
.requestMatchers(HttpMethod.GET, "/login.html").permitAll()
.requestMatchers(HttpMethod.GET, "/login-classic.json").permitAll()
.requestMatchers(HttpMethod.GET, "/login-classic.jsonp").permitAll()
.requestMatchers(HttpMethod.GET, "/login-classic/**").permitAll()
.requestMatchers(HttpMethod.GET, "/login-resources/**").permitAll()
.requestMatchers(HttpMethod.GET, "/sencha-workspace/ext751/**").permitAll()
.requestMatchers(HttpMethod.GET, "/sencha-workspace/login-app/**").permitAll()
.requestMatchers(HttpMethod.GET, "/sencha-workspace/build/development/Login/**").permitAll()
.requestMatchers(HttpMethod.GET, "/sencha-workspace/build/production/Login/**").permitAll()
.requestMatchers(HttpMethod.GET, "/oauth2/code/open-id-connect-client").permitAll()
.anyRequest().authenticated()
)
.oauth2Login(oauthLogin -> oauthLogin.loginPage(OAuth2AuthorizationRequestRedirectFilter.DEFAULT_AUTHORIZATION_REQUEST_BASE_URI + "/open-id-connect-client")
.permitAll()
.userInfoEndpoint(userInfoEndpointConfig -> userInfoEndpointConfig
.oidcUserService(this.oidcUserService()))
)
.build();
}
private OAuth2UserService<OidcUserRequest, OidcUser> oidcUserService(){
final OidcUserService delegate = new OidcUserService();
return (userRequest) -> {
OidcUser oidcUser = delegate.loadUser(userRequest);
SecurityContextHolder.getContext().setAuthentication(userAuthenticationProvider.test(oidcUser));
oidcUser = new DefaultOidcUser(mappedAuthorities, oidcUser.getIdToken(), oidcUser.getUserInfo());
return oidcUser;
};
}
}
The old application used the SessionCreationPolicy.STATELESS, when I changed it to SessionCreationPolicy.IF_REQUIRED the user was saved in the session