Summary
I have configured Spring Security with SAML2 (SP Initiated) and OAuth2 Client implementation for user authentication. Both mechanisms uses an IDP to authenticate the User.
I have also configured OAuth2 Resource Server that take JWT Tokens to authorize for the protected resources.
There are two points that I want to achieve:
1 - Use the SAML assertion as means of authentication in request to allow further processing. Validate SAML Assertion using the configured IDP configurations that authenticated the user in first place. 2 - Use SAML assertion to exchange it for JWT Token for the User using the OAuth2Client configurations.
Similar scenario has been reported at following: https://stackoverflow.com/q/76035118/8919671 https://stackoverflow.com/q/71766820/8919671
Security Configuration
@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
http
.csrf().disable()
.authorizeRequests()
.antMatchers("/", "/login")
.permitAll().and()
.authorizeRequests()
.anyRequest().authenticated()
.and()
.saml2Login().defaultSuccessUrl("/dashboard")
.and()
.oauth2ResourceServer(oauth2 -> oauth2.jwt())
.oauth2Login(
oauth2 -> oauth2.
defaultSuccessUrl("/dashboard", true)
)
.logout().logoutSuccessUrl("/login").and()
.logout(logout -> logout
.deleteCookies("remove")
.invalidateHttpSession(true)
.logoutSuccessUrl("/login")
.logoutSuccessHandler(oidcLogoutSuccessHandler())
)
.saml2Logout(Customizer.withDefaults())
;
return http.build();
}
private LogoutSuccessHandler oidcLogoutSuccessHandler() {
OidcClientInitiatedLogoutSuccessHandler oidcLogoutSuccessHandler =
new OidcClientInitiatedLogoutSuccessHandler(this.clientRegistrationRepository);
oidcLogoutSuccessHandler.setPostLogoutRedirectUri("{baseUrl}");
return oidcLogoutSuccessHandler;
}
@Value("${spring.security.oauth2.resourceserver.jwt.jwk-set-uri}")
String jwkSetURI;
@Bean
public JwtDecoder jwtDecoder() {
return NimbusJwtDecoder
.withJwkSetUri(jwkSetURI)
.jwtProcessorCustomizer(customizer -> {
customizer.setJWSTypeVerifier(new DefaultJOSEObjectTypeVerifier<>(new JOSEObjectType("at+jwt")));
})
.build();
}
Application Configurations in application.yml
provider:
host: https://localhost:9443
spring:
security:
basic:
enabled: false
saml2:
# Issuer: {baseUrl}/saml2/service-provider-metadata/wso2
# Assertion Consumer URL: {baseUrl}/login/saml2/sso/wso2
# SLO Response Accepting URL: {baseUrl}/logout/saml2/slo
# SLO Request Accepting URL: {baseUrl}/logout/saml2/slo
relyingparty:
registration:
wso2:
signing:
credentials:
- private-key-location: classpath:saml2/local.key
certificate-location: classpath:saml2/local.crt
singlelogout:
binding: POST
response-url: "{baseUrl}/logout/saml2/slo"
assertingparty:
#metadata-uri: classpath:saml2/metadata_okta_idp.xml
metadata-uri: classpath:saml2/metadata_wso2_idp.xml
# OAuth2 Resource Server Configurations
oauth2:
resourceserver:
jwt:
issuer-uri: ${provider.host}/oauth2/token
jwk-set-uri: ${provider.host}/oauth2/jwks
client:
#OAUTH2 Code Configurations
# Authorization CallBack: ${baseUrl}/login/oauth2/code/{registrationId}
registration:
wso2:
client-name: OAuth2 OIDC - WSO2 IS
client-id: psr2YA51P......f2VvXUa
client-secret: 5qhez......W4KEa
authorization-grant-type: authorization_code
scope: openid
logout-callback: http://localhost:${server.port}/login
provider:
wso2:
issuer-uri: ${provider.host}/oauth2/token
build.gradle
// OAUTH2 Client
implementation 'org.springframework.boot:spring-boot-starter-oauth2-client'
implementation 'org.springframework.boot:spring-boot-starter-security'
implementation 'org.springframework.boot:spring-boot-starter-thymeleaf'
implementation 'org.springframework.boot:spring-boot-starter-web'
// OAUTH Resource Server
implementation 'org.springframework.boot:spring-boot-starter-oauth2-resource-server'
// saml2 dependencies
constraints {
implementation "org.opensaml:opensaml-core:4.2.0"
implementation "org.opensaml:opensaml-saml-api:4.2.0"
implementation "org.opensaml:opensaml-saml-impl:4.2.0"
}
implementation 'org.thymeleaf.extras:thymeleaf-extras-springsecurity5'
implementation 'org.springframework.security:spring-security-saml2-service-provider'
Version
Spring Boot v2.7.10, Spring v5.3.26 OpenSAML: 4.2.0
Comment From: jzheaux
Thanks, @muhammad438, I responded to your SO question. I'll close this issue in favor of continuing the conversation over there.