Based on the demo application created last time in "Try using OAuth 2.0 Login supported by Spring Security 5 with Spring Boot" I would like to see if Spring Security 5 realizes OAuth 2.0 Login in the flow. (This time, we will limit the processing flow to the Servlet Filter particle size → Please look forward to the story of what class is used in each Servlet Filter for processing !!)
When investigating the mechanism of Spring Security, enabling the debug log of Spring Secuirty makes it easier to understand the behavior of the Security Filters of Spring Security.
src/main/resources/application.properties
logging.level.org.springframework.security=debug
When you start the demo application, the following log is output, and you can confirm that the Spring Security Servlet Filter (springSecurityFilterChain) is applied to all requests (/ *
).
2017-11-23 21:40:39.451 INFO 66053 --- [ost-startStop-1] o.s.b.w.servlet.FilterRegistrationBean : Mapping filter: 'characterEncodingFilter' to: [/*]
2017-11-23 21:40:39.451 INFO 66053 --- [ost-startStop-1] o.s.b.w.servlet.FilterRegistrationBean : Mapping filter: 'hiddenHttpMethodFilter' to: [/*]
2017-11-23 21:40:39.451 INFO 66053 --- [ost-startStop-1] o.s.b.w.servlet.FilterRegistrationBean : Mapping filter: 'httpPutFormContentFilter' to: [/*]
2017-11-23 21:40:39.451 INFO 66053 --- [ost-startStop-1] o.s.b.w.servlet.FilterRegistrationBean : Mapping filter: 'requestContextFilter' to: [/*]
+2017-11-23 21:40:39.452 INFO 66053 --- [ost-startStop-1] .s.DelegatingFilterProxyRegistrationBean : Mapping filter: 'springSecurityFilterChain' to: [/*]
If you start the demo application with the Spring Security debug log enabled, the following log will be output, and you can check the application status of the Spring Security Security Filter (actually Servlet Filter) for each path pattern. I will. (Although line breaks are made for readability, they are actually output on one line)
2017-11-23 21:40:40.691 INFO 66053 --- [ main] o.s.s.web.DefaultSecurityFilterChain : Creating filter chain: org.springframework.security.web.util.matcher.AnyRequestMatcher@1,
[org.springframework.security.web.context.request.async.WebAsyncManagerIntegrationFilter@3cae7b8b,
org.springframework.security.web.context.SecurityContextPersistenceFilter@20e6c4dc,
org.springframework.security.web.header.HeaderWriterFilter@327c7bea,
org.springframework.security.web.csrf.CsrfFilter@5246a3b3,
org.springframework.security.web.authentication.logout.LogoutFilter@151db587,
org.springframework.security.oauth2.client.web.OAuth2AuthorizationRequestRedirectFilter@26f7cdf8,
org.springframework.security.oauth2.client.web.OAuth2LoginAuthenticationFilter@681adc8f,
org.springframework.security.web.authentication.ui.DefaultLoginPageGeneratingFilter@4682eba5,
org.springframework.security.web.savedrequest.RequestCacheAwareFilter@4d2a1da3,
org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter@68c87fc3,
org.springframework.security.web.authentication.AnonymousAuthenticationFilter@184dbacc,
org.springframework.security.web.session.SessionManagementFilter@6c65860d,
org.springframework.security.web.access.ExceptionTranslationFilter@3f672204,
org.springframework.security.web.access.intercept.FilterSecurityInterceptor@18eec010]
Let me briefly introduce the role of Security Filter (Servlet Filter) related to this entry (OAuth 2.0 Login).
Security Filter | Description |
---|---|
SecurityContextPersistenceFilter |
SecurityContext (Area to hold authentication information)A Servlet Filter that provides a mechanism for sharing the data across requests. The default behavior is for sharing between requestsHttpSession To use. |
OAuth2AuthorizationRequestRedirectFilter |
OAuth 2.0(OpenID Connect 1.0)Provider authorization endpoint(Endpoint to get permission to access user information of resource owner)A Servlet Filter that provides an endpoint for redirecting to. The default behavior is "/oauth2/authorization/{registrationId} Is the endpoint path. |
OAuth2LoginAuthenticationFilter |
OAuth 2.0(OpenID Connect 1.0)The endpoint for logging in to the demo app (the endpoint used when returning to the demo app after authorization on the provider side) using the token endpoint (endpoint for acquiring the access token) of Provide Servlet Filter. The default behavior is "/login/oauth2/code/{registrationId} Is the endpoint path. |
DefaultLoginPageGeneratingFilter |
A Servlet Filter that provides an endpoint to generate a default login page. The default behavior is "GET /login Is the endpoint path. If the login page is specified, this Servlet Filter will not be applied. |
ExceptionTranslationFilter |
Servlet Filter for handling authorization errors and providing error response. The default behavior is to redirect to the endpoint to display the login page when login is required, and respond "403 Forbidden" if logged in (AccessDeniedHandler Can be customized to any error response). |
FilterSecurityInterceptor |
Servlet Filter that performs authorization processing based on the specified access policy. |
Note:
In this entry, I will omit the basic mechanism of Spring Secuirty, so if you want to know the basic mechanism of Spring Security, please read @ opengl-8080's "[Spring Security Usage Memo Series](https: /) /qiita.com/opengl-8080/items/032ed0fa27a239bdc1cc) ”is recommended! !!
Here, we will look at the operation when a request to display a secure page ("index screen") is made without logging in.
Process flow |
---|
The resource owner makes a "index screen display request" via the user agent.(GET / )"I do. |
FilterSecurityInterceptor Performs authorization processing for the "index screen display request". In the demo application, the access policy of "authenticated" is defined for "request to display index screen", so a request from a user agent who is not logged in will result in an authorization error. |
ExceptionTranslationFilter Is an authorization error(AccessDeniedException )And redirect to the login screen. Before redirecting, cache the request information that caused an authorization error (default implementation isHttpSession By storing it in (stored in), the index screen can be displayed after successful login. |
The user agent requests "Login screen display request"(GET /login )"I do. |
DefaultLoginPageGeneratingFilter Responds to the login screen for logging in via the provider (GitHub in the demo app). |
Here, let's see the operation when a request to display the authorization screen provided by the provider is made from the login screen generated by DefaultLoginPageGeneratingFilter
.
Process flow |
---|
The resource owner presses the link displayed on the login screen and clicks the "Authorization screen display request (GET /oauth2/authorization/{registrationId} )"I do. The demo application uses GitHub as the provider, soregistrationId Isgithub become. |
OAuth2AuthorizationRequestRedirectFilter Is the client registration information(ClientRegistration )Refer to and redirect to the authorization endpoint provided by the provider. |
GitHub displays the authorization screen after authenticating the resource owner. |
Here, let's see the operation when an authorization request is made on the authorization screen of GitHub.
Process flow |
---|
The resource owner is allowed to log in to the demo application using the user information of the provider by pressing the "authorization button" displayed on the authorization screen. |
GitHub assigns an authorization code to the transition destination (URL for accessing the endpoint that performs authentication processing) specified by the demo application and redirects. |
The user agent is "Authentication processing request (GET /login/oauth2/code/{registrationId} )"I do. The demo application uses GitHub as the provider, soregistrationId Isgithub become. |
OAuth2LoginAuthenticationFilter Makes a request to the token endpoint provided by the provider and obtains the access token corresponding to the authorization code received from the provider. |
OAuth2LoginAuthenticationFilter Uses the access token obtained from the provider to make a request to the user information endpoint and obtain the user information of the source owner. |
OAuth2LoginAuthenticationFilter Generates credentials using acquisition from token endpoints and user information endpoints,SecurityContextHolder Set to. (It will be authenticated here) |
OAuth2LoginAuthenticationFilter Refers to the request information cached at the time of authorization error and makes an "index screen display request (redirect)". |
SecurityContextPersistenceFilter Will generate the credentials when the authentication is successfulSecurityContextHolder Take out fromHttpSession Save to. |
The user agent requests "index screen display request (GET / )"I do. |
SecurityContextPersistenceFilter IsHttpSession Get credentials fromSecurityContextHolder Set to. By performing this process, the authentication information can be shared across requests (= the authenticated state can be maintained). |
FilterSecurityInterceptor Performs authorization processing for the "index screen display request". At this point, since it is in the authenticated state, authorization is OK and subsequent processing (index screen display processing) is executed. |
DemoController Performs a process corresponding to the "index screen display request" and responds to the index screen. |
The mechanism of OAuth 2.0 Login provided by Spring Security 5 is realized by adding two Security Filters, ʻOAuth2AuthorizationRequestRedirectFilter and ʻOAuth2LoginAuthenticationFilter
, to the Security Filter group provided before Spring Security 4. I think you understand.
ʻOAuth2AuthorizationRequestRedirectFilter is completely OAuth 2.0 Login's own Security Filter, but ʻOAuth2LoginAuthenticationFilter
plays the same role as ʻUsernamePasswordAuthenticationFilter in forms authentication. ʻUsernamePasswordAuthenticationFilter
uses the" username "and" password "entered on the login screen for authentication, while ʻOAuth2LoginAuthenticationFilter` uses the" authorization code "issued by the provider (authorization server) for authentication. The difference between these two Security Filters (authentication filters) is that
Next time, I would like to introduce what kind of classes ʻOAuth2AuthorizationRequestRedirectFilter and ʻOAuth2LoginAuthenticationFilter
use for processing.
Recommended Posts