title: Problem calling a "bearer-only" keycloak endpoint from a springboot (client app) to a also spring boot (bearer only app)
body: <p>Basically I'm trying to access a bearer-only endpoint from a client app which is using a "KeycloakRestTemplate". </p>
  
  <p>I did follow this guidelines 1:1 (it is in German) : <a href="https://blog.codecentric.de/2017/09/keycloak-und-spring-security-teil-1-einrichtung-frontend/" rel="nofollow noreferrer">https://blog.codecentric.de/2017/09/keycloak-und-spring-security-teil-1-einrichtung-frontend/</a></p>
  
  <p>My problem is that when I see the logs, the authentication on the side of the bearer only endpoint seems successful, as shown bellow:</p>
  
  <pre><code> Found [1] values in authorization header, selecting the first value for Bearer.
  o.k.a.BearerTokenRequestAuthenticator    : Verifying access_token
  o.k.a.BearerTokenRequestAuthenticator    :  access_token: [LONG TOKEN HERE]
  o.k.a.RefreshableKeycloakSecurityContext : checking whether to refresh.
  org.keycloak.adapters.AdapterUtils       : use realm role mappings
  org.keycloak.adapters.AdapterUtils       : Setting roles: 
  org.keycloak.adapters.AdapterUtils       :    role: create_vouchers
  org.keycloak.adapters.AdapterUtils       :    role: public_realm_access
  org.keycloak.adapters.AdapterUtils       :    role: overview_orders
  org.keycloak.adapters.AdapterUtils       :    role: uma_authorization
  User 'c1500da2-855f-4306-ab65-662160558101' invoking 'http://localhost:8082/articles' on client 'articlesBearerOnlyService'
  o.k.adapters.RequestAuthenticator        : Bearer AUTHENTICATED
  .k.a.t.AbstractAuthenticatedActionsValve : AuthenticatedActionsValve.invoke /articles
  o.k.a.AuthenticatedActionsHandler        : AuthenticatedActionsValve.invoke http://localhost:8082/articles
  cors validation not needed as were not a secure session or origin header was null: {0}
  o.k.a.AuthenticatedActionsHandler        : Policy enforcement is disabled.
  </code></pre>
  
  <p>but then directly afterwards on the logs comes this:</p>
  
  <pre><code>o.k.adapters.PreAuthActionsHandler       : adminRequest http://localhost:8082/login
  o.k.adapters.PreAuthActionsHandler       : checkCorsPreflight http://localhost:8082/login
  .k.a.t.AbstractAuthenticatedActionsValve : AuthenticatedActionsValve.invoke /login
  o.k.a.AuthenticatedActionsHandler        : AuthenticatedActionsValve.invoke http://localhost:8082/login
  o.k.a.AuthenticatedActionsHandler        : Origin: null uri: http://localhost:8082/login
  o.k.a.AuthenticatedActionsHandler        : cors validation not needed as were not a secure session or origin header was null: {0}
  o.k.a.AuthenticatedActionsHandler        : Policy enforcement is disabled.
  </code></pre>
  
  <p>so, it tries to redirect to adminRequest <a href="http://localhost:8082/login" rel="nofollow noreferrer">http://localhost:8082/login</a>? why, and how could this be solved?</p>
  
  <p>I did also also tried with postman (getting the acces-token from the token end-point) and pasting it on the Authorization header of this "bearer-only" endpoint, and similarly by seeing the logs, the user seems authorized exacltly like in the first log block above, the diference is that is doesn't try to redirect anywhere but I receive a 401.</p>
  
  <blockquote>
    <p>{
        "timestamp": "2019-09-05T11:18:51.347+0000",
        "status": 401,
        "error": "Unauthorized",
        "message": "Unauthorized",
        "path": "/articles" }</p>
  </blockquote>
  
  <p>Could somebody please provide some guidance into a possible solution?</p>
  
  <p>Thanks in advance!</p>
  
  <p><strong>----------------------------------------</strong>
  <strong>EDITED</strong>
  <strong>----------------------------------------</strong></p>
  
  <p>here is the application properties file:</p>
  
  <pre><code>server.port = 8082
  spring.application.name = articleBearerOnlyService
  
  keycloak.auth-server-url=http://localhost:8080/auth
  keycloak.realm=[REALM]
  keycloak.resource=articlesBearerOnlyService
  keycloak.bearer-only=true
  keycloak.cors=true
  keycloak.credentials.secret=[SECRET]
  keycloak.ssl-required = external
  
  # access controlled through spring security
  #keycloak.security-constraints[0].auth-roles[0]=overview_orders
  #keycloak.security-constraints[0].security-collections[0].patterns[0]=/articles
  
  logging.level.org.keycloak=TRACE
  </code></pre>
  
  <p>and here the SecurityConfig :</p>
  
  <pre><code>@KeycloakConfiguration
  @EnableWebSecurity
  class SecurityConfig extends KeycloakWebSecurityConfigurerAdapter {
  
      private final KeycloakClientRequestFactory keycloakClientRequestFactory;
  
      public SecurityConfig(KeycloakClientRequestFactory keycloakClientRequestFactory) {
          this.keycloakClientRequestFactory = keycloakClientRequestFactory;
          //to use principal and authentication together with @async
          SecurityContextHolder.setStrategyName(SecurityContextHolder.MODE_INHERITABLETHREADLOCAL);
      }
  
      /* remove default spring "ROLE_" prefix appending to keycloak's roles*/
      @Autowired
      public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
          KeycloakAuthenticationProvider keycloakAuthenticationProvider = keycloakAuthenticationProvider();
          keycloakAuthenticationProvider.setGrantedAuthoritiesMapper(new SimpleAuthorityMapper());
          auth.authenticationProvider(keycloakAuthenticationProvider);
      }
  
      @Bean
      @Override
      protected SessionAuthenticationStrategy sessionAuthenticationStrategy() {
          // NullAuthenticatedSessionStrategy() for bearer-only services
          return new NullAuthenticatedSessionStrategy();
      }
  
      /* configure cors &amp; requests handling behaviour*/
      @Override
      protected void configure(HttpSecurity http) throws Exception {
          super.configure(http);
          http.cors()
                  .and()
                  .csrf()
                  .disable()
                  .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS)
                  .sessionAuthenticationStrategy(sessionAuthenticationStrategy())
                  .and()
                  .authorizeRequests()
                  .antMatchers("/articles").hasRole("overview_orders")
                  .anyRequest().permitAll();
      }
  
  
      // Spring boot integration
      @Bean
      public KeycloakConfigResolver keycloakConfigResolver() {
          return new KeycloakSpringBootConfigResolver();
      }
  
      // *************************** Avoid Bean redefinition ********************************
      @Bean
      public FilterRegistrationBean keycloakAuthenticationProcessingFilterRegistrationBean(
              KeycloakAuthenticationProcessingFilter filter) {
          FilterRegistrationBean registrationBean = new FilterRegistrationBean(filter);
          registrationBean.setEnabled(false);
          return registrationBean;
      }
  
      @Bean
      public FilterRegistrationBean keycloakPreAuthActionsFilterRegistrationBean(
              KeycloakPreAuthActionsFilter filter) {
          FilterRegistrationBean registrationBean = new FilterRegistrationBean(filter);
          registrationBean.setEnabled(false);
          return registrationBean;
      }
  
      @Bean
      public FilterRegistrationBean keycloakAuthenticatedActionsFilterBean(
              KeycloakAuthenticatedActionsFilter filter) {
          FilterRegistrationBean registrationBean = new FilterRegistrationBean(filter);
          registrationBean.setEnabled(false);
          return registrationBean;
      }
  
      @Bean
      public FilterRegistrationBean keycloakSecurityContextRequestFilterBean(
              KeycloakSecurityContextRequestFilter filter) {
          FilterRegistrationBean registrationBean = new FilterRegistrationBean(filter);
          registrationBean.setEnabled(false);
          return registrationBean;
      }
  
      @Bean
      @Override
      @ConditionalOnMissingBean(HttpSessionManager.class)
      protected HttpSessionManager httpSessionManager() {
          return new HttpSessionManager();
      }
  }
  </code></pre>