Search code examples
spring-securityoauth-2.0keycloakaccess-tokenspring-security-oauth2

Use Bearer Access Token in Spring 6 Server


I'm using Spring 6.0 to create an application that can be connected to via browser or a stand-alone application. It uses Keycloak as the OAuth2 authorization server, while the application should serve the data.

Access via browser works fine, but the stand-alone application gets an access token from keycloak (device authorization grant or password grant). When it passes the token to the Spring application, the call gets redirected to the keycloak login site instead of using the valid token.

My configuration is simple:

@Configuration
public class OAuth2Config
{

   /**
    * The primary client authentication manager.
    * 
    * @param clientRegistrationRepository
    * @param authorizedClientRepository
    * @return The authorized client manager
    */
   @Bean
   public OAuth2AuthorizedClientManager clientManager( 
         ClientRegistrationRepository clientRegistrationRepository, 
         OAuth2AuthorizedClientRepository authorizedClientRepository )
   {
      // Use the default OAuth client manager - configurations can be made in
      // the properties - and set the built provider.
      //
      DefaultOAuth2AuthorizedClientManager clientManager = new DefaultOAuth2AuthorizedClientManager(
            clientRegistrationRepository, authorizedClientRepository );

      return clientManager;

   }

}

But I'm clearly missing something. What else do I need to provide in the request or adjust my parameters so that my resource server will check the provided token and not redirect back to the login page?

The logs seem to indicate that it is not reading my token correctly - everything is anonymous, which it should not be.

2023-01-04T15:30:19.996-06:00 TRACE 9680 --- [nio-8081-exec-4] o.s.security.web.FilterChainProxy        : Trying to match request against DefaultSecurityFilterChain [RequestMatcher=any request, Filters=[org.springframework.security.web.session.DisableEncodeUrlFilter@6c6c93f8, org.springframework.security.web.context.request.async.WebAsyncManagerIntegrationFilter@38e88e13, org.springframework.security.web.context.SecurityContextHolderFilter@89178b4, org.springframework.security.web.header.HeaderWriterFilter@20ad64c, org.springframework.security.web.csrf.CsrfFilter@1512efe9, org.springframework.security.web.authentication.logout.LogoutFilter@7fa86ddd, org.springframework.security.oauth2.client.web.OAuth2AuthorizationRequestRedirectFilter@59509393, org.springframework.security.oauth2.client.web.OAuth2AuthorizationRequestRedirectFilter@7ec75228, org.springframework.security.oauth2.client.web.OAuth2LoginAuthenticationFilter@1d6dc2b8, org.springframework.security.web.authentication.ui.DefaultLoginPageGeneratingFilter@3314f179, org.springframework.security.web.authentication.ui.DefaultLogoutPageGeneratingFilter@3a720ae3, org.springframework.security.web.savedrequest.RequestCacheAwareFilter@64836643, org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter@42684d86, org.springframework.security.web.authentication.AnonymousAuthenticationFilter@1fe37d27, org.springframework.security.oauth2.client.web.OAuth2AuthorizationCodeGrantFilter@3fc7abf6, org.springframework.security.web.access.ExceptionTranslationFilter@600b3bee, org.springframework.security.web.access.intercept.AuthorizationFilter@565030b7]] (1/1)
2023-01-04T15:30:19.996-06:00 DEBUG 9680 --- [nio-8081-exec-4] o.s.security.web.FilterChainProxy        : Securing GET /users
2023-01-04T15:30:19.996-06:00 TRACE 9680 --- [nio-8081-exec-4] o.s.security.web.FilterChainProxy        : Invoking DisableEncodeUrlFilter (1/17)
:
:
2023-01-04T15:30:20.000-06:00 TRACE 9680 --- [nio-8081-exec-4] o.s.security.web.FilterChainProxy        : Invoking AuthorizationFilter (17/17)
2023-01-04T15:30:25.332-06:00 TRACE 9680 --- [nio-8081-exec-4] estMatcherDelegatingAuthorizationManager : Authorizing SecurityContextHolderAwareRequestWrapper[ org.springframework.security.web.header.HeaderWriterFilter$HeaderWriterRequest@60be86e5]
2023-01-04T15:30:25.332-06:00 TRACE 9680 --- [nio-8081-exec-4] estMatcherDelegatingAuthorizationManager : Checking authorization on SecurityContextHolderAwareRequestWrapper[ org.springframework.security.web.header.HeaderWriterFilter$HeaderWriterRequest@60be86e5] using org.springframework.security.authorization.AuthenticatedAuthorizationManager@3ba6b23
2023-01-04T15:30:25.332-06:00 TRACE 9680 --- [nio-8081-exec-4] w.c.HttpSessionSecurityContextRepository : No HttpSession currently exists
2023-01-04T15:30:25.332-06:00 TRACE 9680 --- [nio-8081-exec-4] .s.s.w.c.SupplierDeferredSecurityContext : Created SecurityContextImpl [Null authentication]
2023-01-04T15:30:25.333-06:00 TRACE 9680 --- [nio-8081-exec-4] .s.s.w.c.SupplierDeferredSecurityContext : Created SecurityContextImpl [Null authentication]
2023-01-04T15:30:25.333-06:00 TRACE 9680 --- [nio-8081-exec-4] o.s.s.w.a.AnonymousAuthenticationFilter  : Set SecurityContextHolder to AnonymousAuthenticationToken [Principal=anonymousUser, Credentials=[PROTECTED], Authenticated=true, Details=WebAuthenticationDetails [RemoteIpAddress=192.168.0.119, SessionId=null], Granted Authorities=[ROLE_ANONYMOUS]]
2023-01-04T15:30:25.334-06:00 TRACE 9680 --- [nio-8081-exec-4] o.s.s.w.a.ExceptionTranslationFilter     : Sending AnonymousAuthenticationToken [Principal=anonymousUser, Credentials=[PROTECTED], Authenticated=true, Details=WebAuthenticationDetails [RemoteIpAddress=192.168.0.119, SessionId=null], Granted Authorities=[ROLE_ANONYMOUS]] to authentication entry point since access is denied

Solution

  • A REST API is a resource-server, not a client.

    I guess you used spring-boot-starter-oauth2-client (or wrote quite some conf for spring-security 6 OAuth2 client) when you should use spring-boot-starter-oauth2-resource-server.

    If serving html pages in addition to REST endpoints, you'll need two security filter-chain: a resource-server one for REST endpoints and a client one for html pages.

    All that is already described in this SO answer "Use Keycloak Spring Adapter with Spring Boot 3"