wb256
July 30, 2022, 3:07pm
1
I’m running a java-based external webservice that needs to know the user id after the user calls its http endpoint.
Basically, there are 2 cases. The user might be logged in or not. My current vague idea to achieve this is:
1.) User is logged in:
User clicks on link to the webservice.
Webservice redirects to Keycloak
Keycloak calls the webservice back with the userid
2.) User is not logged in:
User clicks on link to the webservice
Webservice redirects to Keycloak
Keycloak performs login
Redirect back to webservice with userid
What would be a way to achieve something similar to this? Ideally, this should be done via http redirects without involving javascript .
wb256
July 30, 2022, 7:14pm
2
This turned out to be more complecated than I thought. Here is what I ended up doing:
Use spring-boot-starter-security
with spring-boot-starter-oauth2-client
Connect Keycloak:
spring:
security:
oauth2:
client:
registration:
xxx-client:
provider: keycloak
client-id: ...
client-secret: ...
client-authentication-method: client_secret_basic
authorization-grant-type: authorization_code
redirect-uri: "{baseUrl}/login/oauth2/code/{registrationId}"
provider:
keycloak:
issuer-uri: .../realms/<Realm>
user-name-attribute: sub
And then protect the endpoint:
@Bean
public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
http
.authorizeRequests(authorizeRequests -> authorizeRequests
.antMatchers("/payment/test").authenticated()
.anyRequest().anonymous())
.oauth2Client(Customizer.withDefaults())
.oauth2Login(Customizer.withDefaults());
return http.build();
}
This way the webservice will perform a couple of redirects to establish the user identity. In the end I can access the id this way:
@GetMapping("payment/test")
public String test(@AuthenticationPrincipal DefaultOAuth2User user) {
return user.getName();
}
This requires 4 redirects just to establish the id. But at least it works.
If you think this is to complex, you might want to have a look into the OAuth2/OIDC protocol spec. It‘s all like designed, for good reasons. It‘ not just „login and give me an id“.
Possibly interesting for you:
If you set the scope
of your client.registration….
to the value openid
you‘ll get an OidcUser
instead of an OAuth2User
in your method as an authenticator principal. The OidcUser
will give you more standard user profile information, as mentioned in the OIDC spec.