Search code examples
spring-securityoauth-2.0keycloakspring-cloudapi-gateway

Why permitAll doesnt work with keycloak and oauth2 cloud gateway (auth redirect me to login page)


I have problem with keycloak and oauth2 when i do request by cloud gateway. I have resource config class that permit all requests.

@EnableWebSecurity
@Configuration
public class SecurityConfig {

    /**
     * For the backend-resources, I indicate that all the endpoints are protected.
     * To request any endpoint, the OAuth2 protocol is necessary, using the server configured and with the given scope.
     * Thus, a JWT will be used to communicate between the backend-resources and backend-auth when backend-resources
     * needs to validate the authentication of a request.
     */
    @Bean
    public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
        http.authorizeRequests()
            .anyRequest()
            .permitAll()
            .and()
            .oauth2ResourceServer()
            .jwt();
        return http.build();
    }
}

So when I try http://localhost:8082/messages all works, but when I try to do api gateway request http://localhost:8083/messages keycloak auto redirect me to login page, but I have permit all. How can I reslove this problem. This is gateway prop file

server:
  port: 8083

spring:
  application.name: backend-gateway-client
  cloud:
    gateway:
      routes:
        - id: resources
          uri: http://localhost:8082/messages
          predicates:
            Path=/messages/**
          filters:
            TokenRelay=
  security:
    oauth2:
      client:
        registration:
          gateway:
            provider: my-provider
            client-id: quiz-client
            client-secret: 348b07b5-3cee-43cb-898c-33cde9dd38b4
            authorization-grant-type: authorization_code
            redirect-uri: "http://localhost:8083/login/oauth2/code/{registrationId}"
            scope: openid, message.read
        provider:
          my-provider:
            issuer-uri: http://localhost:8080/auth/realms/quiz-realm


Solution

  • Assuming that you have

    • http://localhost:8082/messages (your backend service)
    • http://localhost:8083/messages (your spring cloud gateway that will route to your backend service)

    and you don't want a redirect to the login page when accessing http://localhost:8083/messages, you will need to ensure that your spring cloud gateway security config has a permitAll on /messages.

    That way spring cloud gateway will route your request to the underlying service (running on http://localhost:8082/messages). At that point your backend service security configuration will kick in and will give you a 401 error when you don't present a valid jwt / bearer token.

    You always need to take into account the 2 levels of security

    • The spring cloud gateway will protect its resources (routes) using the oauth2 authorization code (causing redirects to login pages
    • The backend service will protect its resources as an oauth2 resource server (expecting a jwt / bearer token)