SpringBoot security fifth look: more OAuth2 client
Introduction
For this post, I want to focus on the client interactions with third party oidc providers such as GCP and okta.
Google OAuth2
To set up a simple oidc connection with Google, all we need is to the client id, client secret and the redirect url. The redirect uri is a must due to Google’s protocol requirement. Then we need to configure a SecurityFilterChain bean.
1 | spring.security.oauth2.client.registration.google.client-id=<client_id> |
Spring security providers some builtin ClientRegistration in the CommonOAuth2Provider.java. For the Google provider,
1 | GOOGLE { |
it defines things like default scopes, the authorization endpoint, jwk endpoint etc.
Debug request flow
To debug requests, we first put a breakpoint in FilterChainProxy. It results total of 18 filters, like we discussed in the previous post. The process is basically the same.
- We try to access the resource using URL, then encounter an AccessDeniedException.
- The exception handler redirect the AccessDeniedException to /login, then send the authorization request to Google’s /auth endpoint.
- After successfully authorizing with Google, we create an AuthenticationToken from returned Jwt.
The interesting thing here is that the “email”, “family_name”, “name” values are included as part of the returned Jwt claim set.
Okta OAuth2
To use Okta, it is the same idea. You create the application in auth0.com, configure the redirect-uri, grab the domain, client id, and client secret. The application.properities should like
1 | spring.security.oauth2.client.registration.okta.client-name=okta |
Observations:
- The redirect-uri should include the port if it is local development
- If issuer-uri is defined, the OKTA enum from CommonOAuth2Provider.java is not used. In that case, you need to provide the scope.
Otherwise, if issuer-uri is not define, you have to provide the authorization endpoint, user endpoint, code endpoint etc. - Since Okta support Google login, the “sub” attribute will start with “google-oauth2|” instead of “auth0|”