DEV Community

Cover image for Spring boot + Spring Security 5 + OAuth2/OIDC Client - Deep Dive

Spring boot + Spring Security 5 + OAuth2/OIDC Client - Deep Dive

Shyamala on March 25, 2019

In my previous post we saw how easy it is to protect your application with Google Login. Now let us see what are all the components responsible fo...
Collapse
 
erlendfg profile image
erlendfg

Thanks for your post. I was also surprised how little code that was necessary in order to do authentication and fetch user information from my provider's userinfo endpoint, but there is one crucial thing I cannot understand. How do I protect my application using such rules:

.antMatchers("/user/**").hasRole("USER")

ROLE_USER should be added by default, but Spring security is responding with 403/forbidden if I go to my protected page /user/index.html after successful authentication. I guess there is something I have misunderstood.

Here's part of my security config:

.authorizeRequests()
.antMatchers("/user/**").hasRole("USER")
.and()
.logout()
.logoutSuccessHandler(oidcLogoutSuccessHandler())
.and()
.csrf().disable()
.anonymous().disable()
.oauth2Login()
.userInfoEndpoint();

I have tried to map the roles by using a userAuthoritiesMapper, but it doesn't help much. If I try to write out the authorities after authentication, this is what I get (and notice the ROLE_USER which is actually present):

ROLE_USER
SCOPE_email
SCOPE_groups
SCOPE_openid
SCOPE_profile
SCOPE_userid-feide
Collapse
 
shyamala_u profile image
Shyamala

Hi,
Thank you for the response, I hope you already went through this.
The distinction between Role and Authority is subtle as explained here, without looking into your userAuthoritiesMapper, I cannot be sure. It would be helpful if you can share your code , for me to have a look at it.

Collapse
 
erlendfg profile image
erlendfg

Thanks for your reply and your willingness to help. Actually it works after I changed .antMatchers("/user/", "/user/index.html") to .antMatchers("/user/**").

Since our old SAML2.0-based application needs a UserDetails object, do you have any suggestions how to proceed? My thoughts is to configure the following to map authorities and to return a UserDetails object which implements OAuth2UserService<OidcUserRequest, OidcUser>.

.oidcUserService(oidcUserService());

private OAuth2UserService<OidcUserRequest, OidcUser> oidcUserService() { …

The latter question is just meant as a contribution to the discussion, not something I need help to implement. Using a UserDetails object is very usual in Spring Security, but the documentation does not mention this strategy.

Collapse
 
umeshumarani profile image
UmeshUmarani

Hi Shyamala,

Thanks a lot for the detailed description and working code.
Could you please add implementation of Resource Server (which accepts the access_token and responds with protected_resource) as per oauth.com/oauth2-servers/token-int... (Resource server introspects the access_token and caches it for future request processing)

Collapse
 
shyamala_u profile image
Shyamala

Hi Thank you for the feedback. Its a good idea for my next blog post :) in this series

Collapse
 
agamgupta6 profile image
agamgupta6

Hi, Thanks for the post. I have took a filter approach to refresh the token. Can you please have a look here:

stackoverflow.com/questions/591441...

Collapse
 
flythebluesky profile image
Rori Stumpf

This is great, thanks! I would love know how to set up a flow for an API client to access to OpenID where the API client doesn't redirect to a login page.

Collapse
 
shyamala_u profile image
Shyamala

Hi Rori, Do you mean you need server-server authentication, Where you do not need user token, If so then you have to use the OAuth2 Token Endpoint with grant_type=client credentials. If your identity provider supports that.

Collapse
 
luqmanulkhair profile image
luqmanulkhair

Hi Shyamala,
Do you know how to do this for webflux security, since the below methods are not there.
.redirectionEndpoint()
.baseUri("/oauth/callback/*")