title: Spring cloud gateway + keycloak is returning 404 (not found)
body: <p>I'm setting up a microservice architecture using spring boot. Hence I have a microservice &quot;poc-be&quot;, an &quot;api-gateway&quot; and a running instance of Keycloak for managing authentication and authorization.<br>
  I searched a lot and I've followed various examples, but I'm still getting a 404 error when calling the service through the api-gateway.<br>
  <strong>Keycloak</strong><br>
  keycloak is running on localhost:8080, I created a realm, a client, an user and a role:
  <a href="https://i.stack.imgur.com/a7gHZ.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/a7gHZ.png" alt="enter image description here" /></a></p>
  <p>Using Postman, I can obtain an access token calling http://localhost:8080/auth/realms/my_realm/protocol/openid-connect/token
  <a href="https://i.stack.imgur.com/ESCmA.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/ESCmA.png" alt="Postman call for getting access token" /></a></p>
  <p>I would use this jwt token for making another call to the api-gateway for accessing protected service.<br>
  <strong>API gateway</strong><br>
  The api gateway project has the following relevant dependencies:<br></p>
  <pre><code>&lt;dependencyManagement&gt;
          &lt;dependencies&gt;
              &lt;dependency&gt;
                  &lt;groupId&gt;org.springframework.cloud&lt;/groupId&gt;
                  &lt;artifactId&gt;spring-cloud-dependencies&lt;/artifactId&gt;
                  &lt;version&gt;${spring-cloud.version}&lt;/version&gt;
                  &lt;type&gt;pom&lt;/type&gt;
                  &lt;scope&gt;import&lt;/scope&gt;
              &lt;/dependency&gt;
  
              &lt;dependency&gt;
                  &lt;groupId&gt;org.keycloak.bom&lt;/groupId&gt;
                  &lt;artifactId&gt;keycloak-adapter-bom&lt;/artifactId&gt;
                  &lt;version&gt;11.0.0&lt;/version&gt;
                  &lt;type&gt;pom&lt;/type&gt;
                  &lt;scope&gt;import&lt;/scope&gt;
              &lt;/dependency&gt;
  
          &lt;/dependencies&gt;
      &lt;/dependencyManagement&gt;
  
      &lt;dependencies&gt;
        &lt;!-- Gateway functionality --&gt;
          &lt;dependency&gt;
              &lt;groupId&gt;org.springframework.cloud&lt;/groupId&gt;
              &lt;artifactId&gt;spring-cloud-starter-gateway&lt;/artifactId&gt;
          &lt;/dependency&gt;
          &lt;!-- keycloak Spring Boot Adapter --&gt;
          &lt;dependency&gt;
              &lt;groupId&gt;org.keycloak&lt;/groupId&gt;
              &lt;artifactId&gt;keycloak-spring-boot-starter&lt;/artifactId&gt;
          &lt;/dependency&gt;
          &lt;dependency&gt;
              &lt;groupId&gt;org.springframework.boot&lt;/groupId&gt;
              &lt;artifactId&gt;spring-boot-starter-security&lt;/artifactId&gt;
          &lt;/dependency&gt;
      &lt;/dependencies&gt;
  </code></pre>
  <p>I setup this configuration in application-dev.yml</p>
  <pre><code>server:
    port: 8082
  cluster:
    uri-local-be: http://localhost:8083
  keycloak:
    enabled: true
    realm: my_realm
    # The value we specify in keycloak.resource matches the client we named in the admin console
    resource: niuma-services
    auth-server-url: http://localhost:8080/auth
    bearer-only: true
    principal-attribute: preferred_username
    public-client: true
  spring:
    ...
    cloud:
      gateway:
        routes:
          - id: protected
            uri: ${cluster.uri-local-be}
            predicates:
            - Path=/api/hello/*
  </code></pre>
  <p>You can see the route for addressing the service (no service discovery at the time).
  I implemented a SecurityConfig class, as found on tutorials:</p>
  <pre><code>@Configuration
  @EnableWebSecurity(debug = true)
  @ComponentScan(basePackageClasses = KeycloakSecurityComponents.class)
  @Slf4j
  public class SecurityConfig extends KeycloakWebSecurityConfigurerAdapter {
      @Autowired
      public void configureGlobal(AuthenticationManagerBuilder auth) {
          log.info(&quot;SecurityConfig.configureGlobal&quot;);
          KeycloakAuthenticationProvider keycloakAuthenticationProvider = keycloakAuthenticationProvider();
          keycloakAuthenticationProvider.setGrantedAuthoritiesMapper(new SimpleAuthorityMapper());
          auth.authenticationProvider(keycloakAuthenticationProvider);
      }
  
      @Bean
      public KeycloakSpringBootConfigResolver KeycloakConfigResolver() {
          log.info(&quot;SecurityConfig.KeycloakConfigResolver&quot;);
          return new KeycloakSpringBootConfigResolver();
      }
  
      @Bean
      @Override
      protected SessionAuthenticationStrategy sessionAuthenticationStrategy() {
          log.info(&quot;SecurityConfig.sessionAuthenticationStrategy&quot;);
          return new NullAuthenticatedSessionStrategy();
      }
  
      @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;
      }
  
      @Override
      protected void configure(HttpSecurity http) throws Exception {
          log.info(&quot;SecurityConfig.configure&quot;);
          super.configure(http);
          http.authorizeRequests().antMatchers(&quot;/spi*&quot;).hasRole(&quot;user&quot;).anyRequest().permitAll();
      }
  
      @Bean
      public ServerCodecConfigurer serverCodecConfigurer() {
          return ServerCodecConfigurer.create();
      }
  </code></pre>
  <br>
  The microservice it's exposing an endpoint at localhost:8083/api/hello/secure returning a simple string.
  I achieved the desired behavior when calling directly localhost:8083/api/hello/secure/ :
  - unhauthorized when calling without access token
  - successfully respond when calling with access token
  <p>But I can't get the api gateway working with both the service and keycloak.
  If I call localhost:<strong>8082</strong>/api/hello/secure passing the access token as Authorization header, I get a 404 and I can't understand why:
  <a href="https://i.stack.imgur.com/YWjlj.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/YWjlj.png" alt="404 api gateway" /></a></p>
  <p>Reading the logs I see the authentication process occurs, but I can't explain the 404:</p>
  <pre><code>o.s.security.web.FilterChainProxy        : /error at position 1 of 15 in additional filter chain; firing Filter: 'WebAsyncManagerIntegrationFilter'
  o.s.security.web.FilterChainProxy        : /error at position 2 of 15 in additional filter chain; firing Filter: 'SecurityContextPersistenceFilter'
  Obtained a valid SecurityContext from SPRING_SECURITY_CONTEXT: 'org.springframework.security.core.context.SecurityContextImpl@7102dd3c: Authentication: org.keycloak.adapters.springsecurity.token.KeycloakAuthenticationToken@7102dd3c: Principal: ciro; Credentials: [PROTECTED]; Authenticated: true; Details: org.keycloak.adapters.springsecurity.account.SimpleKeycloakAccount@42a60ed1; Granted Authorities: ROLE_offline_access, ROLE_user, ROLE_uma_authorization'
  ...
  o.s.s.web.util.matcher.OrRequestMatcher  : Trying to match using Ant [pattern='/sso/login']
  o.s.s.w.u.matcher.AntPathRequestMatcher  : Checking match of request : '/error'; against '/sso/login'
  ...
  f.KeycloakAuthenticationProcessingFilter : Attempting Keycloak authentication
  o.k.a.BearerTokenRequestAuthenticator    : Found [1] values in authorization header, selecting the first value for Bearer.
  ...
  o.k.a.BearerTokenRequestAuthenticator    : successful authorized
  o.k.adapters.RequestAuthenticator        : User 'ciro' invoking 'http://localhost:8082/error' on client 'niuma-services'
  ...
  o.s.web.servlet.DispatcherServlet        : &quot;ERROR&quot; dispatch for GET &quot;/error&quot;, parameters={}, headers={masked} in DispatcherServlet 'dispatcherServlet'
  ...
  o.s.web.servlet.DispatcherServlet        : Exiting from &quot;ERROR&quot; dispatch, status 404, headers={masked}
  ...
  </code></pre>
  <p>Hoping I reported all information needed, I would ask some help getting authentication working using access token obtained from keycloak, calling the api gateway.</p>