OAuth 2.0 Resource Server

Spring Security supports protecting endpoints by using two forms of OAuth 2.0 Bearer Tokens:

  • JWT

  • Opaque Tokens

This is handy in circumstances where an application has delegated its authority management to an 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 Bearer Tokens.

Working samples for both JWTs and Opaque Tokens are available in the Spring Security Samples repository.

Now we can consider how Bearer Token Authentication works within Spring Security. First, we see that, as with Basic Authentication, the WWW-Authenticate header is sent back to an unauthenticated client:

bearerauthenticationentrypoint
Figure 1. Sending WWW-Authenticate Header

The figure above builds off our SecurityFilterChain diagram.

number 1 First, a user makes an unauthenticated request to the /private resource for which the user is not authorized.

number 2 Spring Security’s AuthorizationFilter indicates that the unauthenticated request is Denied by throwing an AccessDeniedException.

number 3 Since the user is not authenticated, ExceptionTranslationFilter initiates Start Authentication. The configured AuthenticationEntryPoint is an instance of 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:

bearertokenauthenticationfilter
Figure 2. Authenticating Bearer Token

The figure builds off our SecurityFilterChain diagram.

number 1 When the user submits their bearer token, the BearerTokenAuthenticationFilter creates a BearerTokenAuthenticationToken which is a type of Authentication by extracting the token from the HttpServletRequest.

number 2 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 JWT or opaque token.

number 3 If authentication fails, then Failure

  • The SecurityContextHolder is cleared out.

  • The AuthenticationEntryPoint is invoked to trigger the WWW-Authenticate header to be sent again.

number 4 If authentication is successful, then Success.

  • The Authentication is set on the SecurityContextHolder.

  • The BearerTokenAuthenticationFilter invokes FilterChain.doFilter(request,response) to continue with the rest of the application logic.