You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
62 lines
4.9 KiB
62 lines
4.9 KiB
[[oauth2resourceserver]] |
|
= OAuth 2.0 Resource Server |
|
:figures: servlet/oauth2 |
|
|
|
Spring Security supports protecting endpoints by using two forms of OAuth 2.0 https://tools.ietf.org/html/rfc6750.html[Bearer Tokens]: |
|
|
|
* https://tools.ietf.org/html/rfc7519[JWT] |
|
* Opaque Tokens |
|
|
|
This is handy in circumstances where an application has delegated its authority management to an https://tools.ietf.org/html/rfc6749[authorization server] (for example, Okta or Ping Identity). |
|
This authorization server can be consulted by resource servers to authorize requests. |
|
|
|
This section details how Spring Security provides support for OAuth 2.0 https://tools.ietf.org/html/rfc6750.html[Bearer Tokens]. |
|
|
|
[NOTE] |
|
==== |
|
Working samples for both {gh-samples-url}/servlet/spring-boot/java/oauth2/resource-server/jwe[JWTs] and {gh-samples-url}/servlet/spring-boot/java/oauth2/resource-server/opaque[Opaque Tokens] are available in the {gh-samples-url}[Spring Security Samples repository]. |
|
==== |
|
|
|
Now we can consider how Bearer Token Authentication works within Spring Security. |
|
First, we see that, as with xref:servlet/authentication/passwords/basic.adoc#servlet-authentication-basic[Basic Authentication], the https://tools.ietf.org/html/rfc7235#section-4.1[WWW-Authenticate] header is sent back to an unauthenticated client: |
|
|
|
.Sending WWW-Authenticate Header |
|
[.invert-dark] |
|
image::{figures}/bearerauthenticationentrypoint.png[] |
|
|
|
The figure above builds off our xref:servlet/architecture.adoc#servlet-securityfilterchain[`SecurityFilterChain`] diagram. |
|
|
|
image:{icondir}/number_1.png[] First, a user makes an unauthenticated request to the `/private` resource for which the user is not authorized. |
|
|
|
image:{icondir}/number_2.png[] Spring Security's xref:servlet/authorization/authorize-http-requests.adoc[`AuthorizationFilter`] indicates that the unauthenticated request is _Denied_ by throwing an `AccessDeniedException`. |
|
|
|
image:{icondir}/number_3.png[] Since the user is not authenticated, xref:servlet/architecture.adoc#servlet-exceptiontranslationfilter[`ExceptionTranslationFilter`] initiates _Start Authentication_. |
|
The configured xref:servlet/authentication/architecture.adoc#servlet-authentication-authenticationentrypoint[`AuthenticationEntryPoint`] is an instance of javadoc:org.springframework.security.oauth2.server.resource.web.BearerTokenAuthenticationEntryPoint[], which sends a `WWW-Authenticate` header. |
|
The `RequestCache` is typically a `NullRequestCache` that does not save the request, since the client is capable of replaying the requests it originally requested. |
|
|
|
When a client receives the `WWW-Authenticate: Bearer` header, it knows it should retry with a bearer token. |
|
The following image shows the flow for the bearer token being processed: |
|
|
|
[[oauth2resourceserver-authentication-bearertokenauthenticationfilter]] |
|
.Authenticating Bearer Token |
|
[.invert-dark] |
|
image::{figures}/bearertokenauthenticationfilter.png[] |
|
|
|
The figure builds off our xref:servlet/architecture.adoc#servlet-securityfilterchain[`SecurityFilterChain`] diagram. |
|
|
|
image:{icondir}/number_1.png[] When the user submits their bearer token, the `BearerTokenAuthenticationFilter` creates a `BearerTokenAuthenticationToken` which is a type of xref:servlet/authentication/architecture.adoc#servlet-authentication-authentication[`Authentication`] by extracting the token from the `HttpServletRequest`. |
|
|
|
image:{icondir}/number_2.png[] Next, the `HttpServletRequest` is passed to the `AuthenticationManagerResolver`, which selects the `AuthenticationManager`. The `BearerTokenAuthenticationToken` is passed into the `AuthenticationManager` to be authenticated. |
|
The details of what `AuthenticationManager` looks like depends on whether you're configured for xref:servlet/oauth2/resource-server/jwt.adoc#oauth2resourceserver-jwt-minimalconfiguration[JWT] or xref:servlet/oauth2/resource-server/opaque-token.adoc#oauth2resourceserver-opaque-minimalconfiguration[opaque token]. |
|
|
|
image:{icondir}/number_3.png[] If authentication fails, then __Failure__ |
|
|
|
* The xref:servlet/authentication/architecture.adoc#servlet-authentication-securitycontextholder[SecurityContextHolder] is cleared out. |
|
* The `AuthenticationEntryPoint` is invoked to trigger the WWW-Authenticate header to be sent again. |
|
|
|
image:{icondir}/number_4.png[] If authentication is successful, then __Success__. |
|
|
|
* Any already-authenticated `Authentication` in the xref:servlet/authentication/architecture.adoc#servlet-authentication-securitycontextholder[`SecurityContextHolder`] is loaded and its |
|
authorities are added to the returned xref:servlet/authentication/architecture.adoc#servlet-authentication-authentication[`Authentication`]. |
|
* The xref:servlet/authentication/architecture.adoc#servlet-authentication-authentication[Authentication] is set on the xref:servlet/authentication/architecture.adoc#servlet-authentication-securitycontextholder[SecurityContextHolder]. |
|
* The `BearerTokenAuthenticationFilter` invokes `FilterChain.doFilter(request,response)` to continue with the rest of the application logic.
|
|
|