Let us walk throught OAuth2 Authorization Process. Have some basic understanding the classes mentioned in Spring Security OAuth2 Core Classes will help you understanding OAuth2 process in this post.
When the user logs in using Github using auhtorization code grant flow. The following three classes are responsible for handling the user login.
OAuth2LoginAuthenticationFilter
OAuth2LoginAuthenticationProvider
DefaultOAuth2UserService
OAuth2LoginAuthenticationFilter
This authentication Filter handles the processing of an OAuth 2.0 Authorization Response for the authorization code grant flow and delegates an OAuth2LoginAuthenticationToken to the AuthenticationManager to log in the End-User.
Create OAuth2LoginAuthenticationToken as authentication request
Delegate authentication to AuthenticationManager. OAuth2LoginAuthenticationToken is passed as parameter
Create OAuth2AuthenticationToken from the AuthenticationManager.authenticate(…) method call result
Create OAuth2AuthorizedClient
Save OAuth2AuthorizedClient to authorizedClientRepository
Return OAuth2AuthenticationToken
There are providers used by AuthenticationManager for OAuth2
OAuth2LoginAuthenticationProvider
OidcAuthorizationCodeAuthenticationProvider
If the scope contains “openid” then OidcAuthorizationCodeAuthenticationProvider will be used to process the authentication. If not, then OAuth2LoginAuthenticationProvider will be used.
We will analyze OAuth2LoginAuthenticationProvider class only.
OAuth2LoginAuthenticationProvider
An implementation of an AuthenticationProvider for OAuth 2.0 Login, which leverages the OAuth 2.0 Authorization Code Grant Flow.
@Override public Authentication authenticate(Authentication authentication)throws AuthenticationException { OAuth2LoginAuthenticationTokenauthorizationCodeAuthentication= (OAuth2LoginAuthenticationToken) authentication;
// Section 3.1.2.1 Authentication Request - https://openid.net/specs/openid-connect-core-1_0.html#AuthRequest // scope // REQUIRED. OpenID Connect requests MUST contain the "openid" scope value. if (authorizationCodeAuthentication.getAuthorizationExchange() .getAuthorizationRequest().getScopes().contains("openid")) { // This is an OpenID Connect Authentication Request so return null // and let OidcAuthorizationCodeAuthenticationProvider handle it instead returnnull; }
this.accessTokenResponseClient.getTokenResponse(...) will take the Authorization Code and exchange with Authorization Server to get the access token.
UserService(DefaultOAuth2UserService in this case) will call UserInfo endpoint and then create the user and put it in Authentication object.
DefaultOAuth2UserService
DefaultOAuth2UserService is an implementation of UserService. Its loadUser method calls UserInfo Endpoint and retrieve user info. Finally create a new OAuth2User and return it.