How @EnableResourceServer Configures OAuth2 Token Validation in Spring Security
This article breaks down the internal workflow of Spring Security’s @EnableResourceServer, explaining how OAuth2 tokens are extracted, validated, and turned into authentication objects through ResourceServerSecurityConfigurer, OAuth2AuthenticationProcessingFilter, OAuth2AuthenticationManager, and related components.
@EnableResourceServer vs @EnableAuthorizationServer
The previous post covered token acquisition; this article focuses on the resource‑server side, i.e., how a request that carries a token is processed once @EnableResourceServer is activated. While @EnableAuthorizationServer configures the authentication server, @EnableResourceServer triggers a set of beans that protect the API endpoints.
ResourceServerSecurityConfigurer (core configuration)
The central class is ResourceServerConfigurerAdapter, which implements ResourceServerConfigurer. It delegates to ResourceServerSecurityConfigurer for security‑specific settings and to HttpSecurity for HTTP‑level configuration. The typical override looks like:
public class ResourceServerConfigurerAdapter implements ResourceServerConfigurer {
@Override
public void configure(ResourceServerSecurityConfigurer resources) throws Exception {
// configure token services, authentication entry point, etc.
}
@Override
public void configure(HttpSecurity http) throws Exception {
http.authorizeRequests().anyRequest().authenticated();
}
}Key points highlighted in the source:
Creation of OAuth2AuthenticationProcessingFilter (the core filter for protected resources).
Setting the AuthenticationManager to an OAuth2AuthenticationManager instance.
Optionally wiring an AuthenticationEntryPoint and AccessDeniedHandler.
OAuth2AuthenticationProcessingFilter (the core filter)
This filter extracts the token from the incoming request, builds an Authentication object, and delegates to the authentication manager. A simplified version of its doFilter method is:
public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) {
HttpServletRequest request = (HttpServletRequest) req;
HttpServletResponse response = (HttpServletResponse) res;
try {
Authentication authentication = tokenExtractor.extract(request);
if (authentication == null) {
chain.doFilter(request, response);
return;
}
// add token details to request attributes
request.setAttribute(OAuth2AuthenticationDetails.ACCESS_TOKEN_VALUE,
authentication.getPrincipal());
if (authentication instanceof AbstractAuthenticationToken) {
((AbstractAuthenticationToken) authentication)
.setDetails(authenticationDetailsSource.buildDetails(request));
}
Authentication authResult = authenticationManager.authenticate(authentication);
eventPublisher.publishAuthenticationSuccess(authResult);
SecurityContextHolder.getContext().setAuthentication(authResult);
chain.doFilter(request, response);
} catch (OAuth2Exception failed) {
// delegate to configured authentication entry point
}
}The filter relies on two collaborators: TokenExtractor – extracts the raw token string. AuthenticationManager – validates the token and builds an OAuth2Authentication object.
OAuth2AuthenticationManager (token‑to‑authentication conversion)
The manager’s authenticate method obtains the token value from the incoming Authentication, then calls the configured ResourceServerTokenServices to load the full authentication details:
public Authentication authenticate(Authentication authentication) throws AuthenticationException {
String token = (String) authentication.getPrincipal();
OAuth2Authentication auth = tokenServices.loadAuthentication(token);
// optional client‑detail checks
if (authentication.getDetails() instanceof OAuth2AuthenticationDetails) {
auth.setDetails(((OAuth2AuthenticationDetails) authentication.getDetails()).getDetails());
}
auth.setAuthenticated(true);
return auth;
}The ResourceServerTokenServices interface defines two essential methods:
OAuth2Authentication loadAuthentication(String accessToken) throws AuthenticationException, InvalidTokenException;
OAuth2AccessToken readAccessToken(String accessToken);Implementations typically delegate to a TokenStore that retrieves the token data from a database, JWT, or remote introspection endpoint.
TokenExtractor – BearerTokenExtractor
The default implementation extracts the token from the Authorization header or a request parameter. Its logic can be summarised as:
public Authentication extract(HttpServletRequest request) {
String tokenValue = extractToken(request);
if (tokenValue != null) {
return new PreAuthenticatedAuthenticationToken(tokenValue, "");
}
return null;
}
protected String extractToken(HttpServletRequest request) {
String token = extractHeaderToken(request);
if (token == null) {
token = request.getParameter("access_token");
}
return token;
}The extractHeaderToken method parses the Authorization: Bearer <token> header, handling multiple header values safely.
Exception handling and token transmission methods
Resource‑server exception handling can be customised by providing your own AccessDeniedHandler or AuthenticationEntryPoint beans; the @EnableResourceServer adapter will replace the defaults. Tokens may be sent in three common ways:
In the Authorization header: Authorization: Bearer <token> As a query parameter: GET /resource?access_token=<token> As a form field in a POST request:
access_token=<token>Summary
The Spring Security OAuth2 resource‑server flow consists of three layers: the ResourceServerConfigurerAdapter wires the filter chain, the OAuth2AuthenticationProcessingFilter extracts the token and delegates to the OAuth2AuthenticationManager, and the manager uses ResourceServerTokenServices to turn the token into a fully‑populated OAuth2Authentication. Understanding the top‑level interfaces and the design patterns (Adapter, Builder, Template) makes navigating the extensive source code far easier.
Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
Programmer DD
A tinkering programmer and author of "Spring Cloud Microservices in Action"
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
