Spring Cloud Gateway OAuth2 with Keycloak

Spring Cloud Gateway OAuth2 with Keycloak

Spring Cloud Gateway OAuth2 support is a key part of the microservices security process. Of course, the main reason for using an API gateway pattern is to hide services from the external client. However, when we set about hiding our services, we didn’t secure them. In this article, I’m going to show you how to set up Spring Cloud Gateway OAuth2 with Spring Security and Keycloak.

Spring Cloud Gateway is a very useful product. You may take an advantage of the many interesting features it provides. One of them is rate-limiting. You may read more about that in the article Rate Limiting in Spring Cloud Gateway with Redis. It is also worth learning about a circuit breaking and fault tolerance. You may find interesting pieces of information about it in the articles Circuit Breaking in Spring Cloud Gateway with Resilience4j and Timeouts and Retries in Spring Cloud Gateway.

Source code

If you would like to try it by yourself, you may always take a look at my source code. In order to do that you need to clone my repository sample-spring-security-microservices. Then you should go to the gateway directory, and just follow my instructions 🙂 If you are interested in more details about Spring Security you should read its documentation.

Enable OAuth2 in Spring Cloud Gateway

To enable OAuth2 support for the Spring Cloud Gateway application we need to add some dependencies. Of course, the spring-cloud-starter-gateway dependency is required to enable the gateway feature. We also need to include spring-boot-starter-oauth2-client enabling Spring Security’s client support for OAuth 2.0 Authorization Framework and OpenID Connect Core 1.0. Finally, we have to add spring-cloud-starter-security to activate the TokenRelay filter.

<dependency>
   <groupId>org.springframework.boot</groupId>
   <artifactId>spring-boot-starter-oauth2-client</artifactId>
</dependency>
<dependency>
   <groupId>org.springframework.cloud</groupId>
   <artifactId>spring-cloud-starter-gateway</artifactId>
</dependency>
<dependency>
   <groupId>org.springframework.cloud</groupId>
   <artifactId>spring-cloud-starter-security</artifactId>
</dependency>

In the next step, we need to provide the configuration settings for the OAuth2 client. Because we are integrating with Keycloak we should set the name of registrationId (spring.security.oauth2.client.provider.[registrationId]) to keycloak. Then we need to set the uris of token, authorization and userinfo endpoints. On the other hand, we can set a value for a single issuer endpoint. The last important property in that section is user-name-attribute. Keycloak is returning user login inside the preferred_username attribute.

We will define two different clients for authorization. The first of them spring-cloud-gateway contains the scope allowed by our test method, while the second spring-cloud-gateway-2 does not.

spring:
  security:
    oauth2:
      client:
        provider:
          keycloak:
            token-uri: http://localhost:8080/auth/realms/master/protocol/openid-connect/token
            authorization-uri: http://localhost:8080/auth/realms/master/protocol/openid-connect/auth
            userinfo-uri: http://localhost:8080/auth/realms/master/protocol/openid-connect/userinfo
            user-name-attribute: preferred_username
        registration:
          keycloak-with-test-scope:
            provider: keycloak
            client-id: spring-with-test-scope
            client-secret: c6480137-1526-4c3e-aed3-295aabcb7609
            authorization-grant-type: authorization_code
            redirect-uri: "{baseUrl}/login/oauth2/code/keycloak"
          keycloak-without-test-scope:
            provider: keycloak
            client-id: spring-without-test-scope
            client-secret: f6fc369d-49ce-4132-8282-5b5d413eba23
            authorization-grant-type: authorization_code
            redirect-uri: "{baseUrl}/login/oauth2/code/keycloak"

In the last step, we need to configure Spring Security. Since Spring Cloud Gateway is built on top of Spring WebFlux, we need to annotate the configuration bean with @EnableWebFluxSecurity. Inside the springSecurityFilterChain method we are going to enable authorization for all the exchanges. We will also set OAuth2 as a default login method and finally disable CSRF.

@Configuration
@EnableWebFluxSecurity
public class SecurityConfig {

   @Bean
   public SecurityWebFilterChain springSecurityFilterChain(ServerHttpSecurity http) {
      http.authorizeExchange(exchanges -> exchanges.anyExchange().authenticated())
         .oauth2Login(withDefaults());
      http.csrf().disable();
      return http.build();
   }

}

Run and configure Keycloak

We are running Keycloak on a Docker container. By default, Keycloak exposes API and a web console on port 8080. However, that port number must be different than the Spring Cloud Gateway application port, so we are overriding it with 8888. We also need to set a username and password to the admin console.

$ docker run -d --name keycloak -p 8888:8080 \
   -e KEYCLOAK_USER=spring \
   -e KEYCLOAK_PASSWORD=spring123 \
   jboss/keycloak

Then we need to create two clients with the same names as defined inside the gateway configuration. Both of them need to have confidential in the “Access Type” section, a valid redirection URI set. We may use a simple wildcard while setting the redirection address as shown below.

The client spring-with-test-scope will have the scope TEST assigned. In contrast, the second client spring-without-test-scope will not have the scope TEST assigned.

spring-cloud-gateway-oauth2-clientscope

Enable OAuth2 Resourse in Spring Cloud Gateway

Now, we may proceed to the implementation of the downstream application. In order to run it, you need to switch to the callme directory in the source code. First, we need to include some Maven dependencies. The spring-boot-starter-web starter provides web support for Spring Boot application. With spring-boot-starter-security we enable Spring Security for our microservice. The spring-security-oauth2-resource-server contains Spring Security’s support for OAuth 2.0 Resource Servers. It is also used to protect APIs via OAuth 2.0 Bearer Tokens. Finally, the spring-security-oauth2-jose module contains Spring Security’s support for the JOSE (Javascript Object Signing and Encryption) framework. The JOSE framework provides a method to securely transfer claims between parties. It supports JWT and JWS (JSON Web Signature).

<dependencies>
   <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-web</artifactId>
   </dependency>
   <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-security</artifactId>
   </dependency>
   <dependency>
      <groupId>org.springframework.security</groupId>
      <artifactId>spring-security-oauth2-resource-server</artifactId>
   </dependency>
   <dependency>
      <groupId>org.springframework.security</groupId>
      <artifactId>spring-security-oauth2-jose</artifactId>
   </dependency>
</dependencies>

In the next step, we need to configure a connection to the authorization server. A resource server will use the property spring.security.oauth2.resourceserver.jwt.issuer-uri to discover the authorization server public keys and then validate incoming JWT tokens.

spring:
  application:
    name: callme
  security:
    oauth2:
      resourceserver:
        jwt:
          issuer-uri: http://localhost:8080/auth/realms/master

We should also provide a Spring Security configuration. First, we need to annotate the Configuration bean with @EnableWebSecurity. Then, we should enable annotation-based security for the controller methods. It allows simple role-based access with @PreAuthorize and @PostAuthorize. In order to enable a method security feature we need to use annotation @EnableGlobalMethodSecurity. Finally, we just need to configure Spring Security to authorize all the incoming requests and validate JWT tokens.

@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class SecurityConfig extends WebSecurityConfigurerAdapter {

   protected void configure(HttpSecurity http) throws Exception {
      http.authorizeRequests(authorize -> authorize.anyRequest().authenticated())
            .oauth2ResourceServer(OAuth2ResourceServerConfigurer::jwt);
   }
}

Finally, let’s take a look at the implementation of the REST controller class. It a single ping method. That method may be accessed only by the client with the TEST scope. It returns a list of assigned scopes from the Authentication bean.

@RestController
@RequestMapping("/callme")
public class CallmeController {

   @PreAuthorize("hasAuthority('SCOPE_TEST')")
   @GetMapping("/ping")
   public String ping() {
      SecurityContext context = SecurityContextHolder.getContext();
      Authentication authentication = context.getAuthentication();
      return "Scopes: " + authentication.getAuthorities();
   }
}

Configure routing on Spring Cloud Gateway

The last step before proceeding to the tests is to configure routing on the Spring Cloud Gateway application. Since the downstream service (callme) is running on port 8040 we need to set the uri to http://127.0.0.1:8040. In order to forward the access token to the callme-service we have to enable a global filter TokenRelay. Just to be sure that everything works as expected, we will remove the Cookie with the session id. The session id is generated on the gateway after performing OAuth2Login.

spring:
  application:
    name: gateway
  cloud:
    gateway:
      default-filters:
        - TokenRelay
      routes:
        - id: callme-service
          uri: http://127.0.0.1:8040
          predicates:
            - Path=/callme/**
          filters:
            - RemoveRequestHeader=Cookie

Finally, let’s take a look at the gateway main class. I added there two useful endpoints. First of them GET / is returning the HTTP session id. The second of them GET /token will return the current JWT access token. After the successful Spring Cloud Gateway OAuth2 login, you will see the result from the index method.

@SpringBootApplication
@RestController
public class GatewayApplication {

   private static final Logger LOGGER = LoggerFactory.getLogger(GatewayApplication.class);

   public static void main(String[] args) {
      SpringApplication.run(GatewayApplication.class, args);
   }

   @GetMapping(value = "/token")
   public Mono<String> getHome(@RegisteredOAuth2AuthorizedClient OAuth2AuthorizedClient authorizedClient) {
      return Mono.just(authorizedClient.getAccessToken().getTokenValue());
   }

   @GetMapping("/")
   public Mono<String> index(WebSession session) {
      return Mono.just(session.getId());
   }

}

Spring Cloud Gateway OAuth2 testing scenario

First, let’s take a look at the picture that illustrates our use case. We are calling POST /login endpoint on the gateway (1). After receiving the login request Spring Cloud Gateway try to obtain the access token from the authorization server (2). Then Keycloak is returning the JWT access token. As a result, Spring Cloud Gateway is calling the userinfo endpoint (3). After receiving the response it is creating a web session and Authentication bean. Finally, the gateway application is returning a session id to the external client (4). The external client is using a cookie with session-id to authorize requests. It calls GET ping from the callme application (5). The gateway application is forwarding the request to the downstream service (6). However, it removes the cookie and replaces it with a JWT access token. The callme application verifies an incoming token (7). Finally, it returns 200 OK response if the client is allowed to call endpoint (8). Otherwise, it returns 403 Forbidded.

spring-cloud-gateway-oauth2-login

We may start testing in the web browser. First, let’s call the login endpoint. We have to available clients keycloak-with-test-scope and keycloak-without-test-scope. We will use the client keycloak-with-test-scope.

spring-cloud-gateway-oauth2-login

Then, the gateway redirects us to the Keycloak login page. We can use the credentials provided during the creation of the Keycloak container.

After a successful login, the gateway will perform the OAuth2 authorization procedure. Finally, it redirects us to the main page. The main page is just a method index inside the controller. It is returning the current session id.

We can also use another endpoint implemented on the gateway – GET /token. It is returning the current JWT access token.

$ curl http://localhost:8080/token -H "Cookie: SESSION=9bf852f1-6e00-42f8-a9a2-3cbdced33993"
eyJhbGciOiJSUzI1NiIsInR5cCIgOiAiSldUIiwia2lkIiA6ICI0RWpwdkVtQ1ZDZ1VDUm41Y2NJeXRiank0RnR0RXpBRXVrMURoZDRTT0RFIn0.eyJleHAiOjE2MDIyMzM5MTksImlhdCI6MTYwMjIz
MzAxOSwiYXV0aF90aW1lIjoxNjAyMjMzMDE5LCJqdGkiOiIyYWQzYjczNy1mZTdhLTQ3NGUtODhhYy01MGZjYzEzOTlhYTQiLCJpc3MiOiJodHRwOi8vbG9jYWxob3N0OjgwODAvYXV0aC9yZWFsbXMv
bWFzdGVyIiwiYXVkIjpbIm1hc3Rlci1yZWFsbSIsImFjY291bnQiXSwic3ViIjoiOWVhMDAyYmQtOTQ4Ni00Njk0LWFhYzUtN2IyY2QwNzc2MTZiIiwidHlwIjoiQmVhcmVyIiwiYXpwIjoic3ByaW5n
LWNsb3VkLWdhdGV3YXkiLCJzZXNzaW9uX3N0YXRlIjoiMDRhNzQ4YzUtOTA1My00ZmZmLWJjYzctNWY5MThjMzYwZGE4IiwiYWNyIjoiMSIsInJlYWxtX2FjY2VzcyI6eyJyb2xlcyI6WyJjcmVhdGUt
cmVhbG0iLCJST0xFX1RFTExFUiIsIm9mZmxpbmVfYWNjZXNzIiwiYWRtaW4iLCJURUxMRVIiLCJ1bWFfYXV0aG9yaXphdGlvbiJdfSwicmVzb3VyY2VfYWNjZXNzIjp7Im1hc3Rlci1yZWFsbSI6eyJy
b2xlcyI6WyJ2aWV3LWlkZW50aXR5LXByb3ZpZGVycyIsInZpZXctcmVhbG0iLCJtYW5hZ2UtaWRlbnRpdHktcHJvdmlkZXJzIiwiaW1wZXJzb25hdGlvbiIsImNyZWF0ZS1jbGllbnQiLCJtYW5hZ2Ut
dXNlcnMiLCJxdWVyeS1yZWFsbXMiLCJ2aWV3LWF1dGhvcml6YXRpb24iLCJxdWVyeS1jbGllbnRzIiwicXVlcnktdXNlcnMiLCJtYW5hZ2UtZXZlbnRzIiwibWFuYWdlLXJlYWxtIiwidmlldy1ldmVu
dHMiLCJ2aWV3LXVzZXJzIiwidmlldy1jbGllbnRzIiwibWFuYWdlLWF1dGhvcml6YXRpb24iLCJtYW5hZ2UtY2xpZW50cyIsInF1ZXJ5LWdyb3VwcyJdfSwiYWNjb3VudCI6eyJyb2xlcyI6WyJtYW5h
Z2UtYWNjb3VudCIsIm1hbmFnZS1hY2NvdW50LWxpbmtzIiwidmlldy1wcm9maWxlIl19fSwic2NvcGUiOiJwcm9maWxlIGVtYWlsIFRFU1QiLCJlbWFpbF92ZXJpZmllZCI6ZmFsc2UsInByZWZlcnJl
ZF91c2VybmFtZSI6InBpb21pbiJ9.X8XfIHiAiR1YMjiJza75aC294qLwi83RrUU2phorM7FP4phq3h-lx80Zu5xqTrMqMC1-RbHBnX-oUTbs4ViS3DziZlDvoRajdkrh6UTiK5oWgoRW-4qsH5L4X1W
bRfoBZgyHFRSnhaCO4CLgjCyEgeLUR5A-JWY-OMYQIOAxxHB2GwE3MNFfLWeqpmS1AWU8fL0giFFXFDfa1_XZEKgnqe1S75Ps_z8B1sfNfvNpz8daJ8omzXrt6I6TSa0FE3iiZ7Qx18mtkbx-iPuFqDD
RT6DGU-Hing9LnGuOt3Yas-WYdN7PKBigvIZv0LyvRFcilRJQBjOdVfEddL3OQ0rmEg

Just to check, you can decode a JWT token on the https://jwt.io site.

spring-cloud-gateway-jwt-decoded

Finally, let’s call the endpoint exposed by the callme application. We are setting session Cookie in the request header. The endpoint is returning a list of scopes assigned to the current user. Only user with scope TEST is allowed to call the method.

$ curl http://localhost:8080/callme/ping -H "Cookie: SESSION=9bf852f1-6e00-42f8-a9a2-3cbdced33993"
Scopes: [SCOPE_profile, SCOPE_email, SCOPE_TEST]

Conclusion

In this article we were discussing important aspects related to microservices security. I showed you how to enable Spring Cloud Gateway OAuth2 support and integrate it with Keycloak. We were implementing such mechanisms like OAuth2 login, token relay, and OAuth2 resource server. The token relay mechanisms will be completely migrated from Spring Cloud Security to Spring Cloud Gateway. Enjoy 🙂

58 COMMENTS

comments user
andriykalashnykovgmailcom

Piotr, great article!

There are couple of thing you can automate – creation of Clients and Client Scops. You can either run Keycloak docker image and execute kcadm.sh commands against it:

# script – begin
docker run -d –rm –name keycloak -p 8888:8080 -e KEYCLOAK_USER=spring -e KEYCLOAK_PASSWORD=spring123 jboss/keycloak:11.0.2&
sleep 60
docker exec -it keycloak /opt/jboss/keycloak/bin/kcadm.sh config credentials –server http://localhost:8080/auth –realm master –user spring –password spring123 && \
docker exec -it keycloak /opt/jboss/keycloak/bin/kcadm.sh create -x “client-scopes” -r master -s name=TEST -s protocol=openid-connect && \
docker exec -it keycloak /opt/jboss/keycloak/bin/kcadm.sh create clients -r master -s clientId=spring-without-test-scope -s enabled=true -s clientAuthenticatorType=client-secret -s secret=79a93cb3-b460-40c8-8c96-c8c8bfe47d39 -s ‘redirectUris=[“*”]’ && \
docker exec -it keycloak /opt/jboss/keycloak/bin/kcadm.sh create clients -r master -s clientId=spring-with-test-scope -s enabled=true -s clientAuthenticatorType=client-secret -s secret=b129f0c2-a46a-4bdb-a059-4eca03639767 -s ‘redirectUris=[“*”]’ -s ‘defaultClientScopes=[“TEST”, “web-origins”, “profile”, “roles”, “email”]’
# script end

or you can create Client and Client Scopes with command line or from Keycloak web UI, export them into json and the run Keycloak image with imported realm. Though importing realm works fin for realm names other’s then Master. Let’s say you create realm Test and add your Clients and Client scope, but you need to modify application.yaml file where it references http://localhost:8888/auth/realms/master/ and use http://localhost:8888/auth/realms/test/ instead

# script – begin
# import test reaml
# docker run -d –rm –name keycloak -p 8888:8080 -e KEYCLOAK_USER=spring -e KEYCLOAK_PASSWORD=spring123 -e KEYCLOAK_MIGRATION_STRATEGY=OVERWRITE_EXISTING -e KEYCLOAK_IMPORT=/opt/jboss/keycloak/imports/realm-test.json -v $(pwd):/opt/jboss/keycloak/imports jboss/keycloak:11.0.2
# script – end

I’ve forked you repo and will provide scripts about soon (https://github.com/AndriyKalashnykov/sample-spring-security-microservices)

    comments user
    piotr.minkowski

    Ok. Thanks for the tips 🙂

comments user
Vishnu Prakash

how logout can be handled?

    comments user
    piotr.minkowski

    You can configure it using `HttpSecurity` object

comments user
galih

sir, i implemented this one and this works cool article but however i want to try to call the secured api from frontend, in this case i have reactjs spa separated from spring cloud gateway, how can i achieve this?

    comments user
    piotr.minkowski

    Unfortunately, I’m not good at reactjs…

comments user
B. Taxi

Thanks for the great article & videos! One (beginner) question … why do the HTTP endpoint methods in the Gateway return Mono’s, but the endpoint in the callme Controller returns a String? Thanks!

    comments user
    piotr.minkowski

    Because the gateway is based on WebFlux and Reactor, while application on Spring MVC.

comments user
Gan

Thank you for your article, although some parts are not well understood, I look forward to more keycloak tutorials

    comments user
    piotr.minkowski

    Which of them is not well understood?

comments user
rokko11

Thank you, Piotr, for this great tutorial! Everything worked instantly! 🙂 (except keycloak port 8888 vs 8080 in application.yml)

comments user
Robert Vialonic

Thank you for this great tutorial! Sadly something changed in Spring Boot version 2.4.x, but for the moment 2.3.x is ok for me 🙂

Another question: I changed the Authorization Annotation to

@PreAuthorize(value = “hasRole(‘TESTROLE’)”)

but it seems that the roles do not pass the gateway. Do you know how to solve this?

    comments user
    piotr.minkowski

    Did add a new role in Keycloak?

comments user
Duy

Thank you for your article.
Sorry my English is pretty bad, But I’m having trouble getting the HA keycloak on kubernetes, when I increase the number of GATEWAY’s PODs the app can’t log in, the same problem happened when I increased the number of PODs of other business SERIVCEs.

    comments user
    piotr.minkowski

    Well, I didn’t test with multiple pods. Do you any errors or warnings in the logs?

comments user
Ashish Kumar

I am getting the below error:
Caused by: java.lang.IllegalArgumentException: Unable to find GatewayFilterFactory with name TokenRelay

    comments user
    piotr.minkowski

    When do you get it? During startup?

comments user
Anto Bernad

Hi piotr,

The blog was useful and I was able to achieve the same. Yet is there way to pass JWT token as bearer token if same api-gateway endpoint is called from UI/ postman

Can you reply on the same. Thanks in advance

comments user
springlearner

How can we make the POST request bu sending OAuth2 token?

comments user
Sujith G

How can we pass this jwt token to our API instead of session id

comments user
Predrag

Thank you for this article. But I wanted to try something different, can a gateway actually accept the JWT issued by Keycloak and on Gateway to be authentication, not on the service?

    comments user
    piotr.minkowski

    Yes, it can

comments user
Panikiran

Thanks for the nice article. I have a slightly different requirement. Could you let me know if its possible.

I have two clients.Lets say C1 and C2. C1 is using authorization_code flow and C2 is using password(DirectAccessGrant in Keycloak) flow. How can i configure this in cloud gateway yml file. C2 is passing me the token(which it got from keycloak). I need toj ust validate this and forward the request to downstream application
For C1 I need to redirect the user to keycloak login page.

comments user
Eric

Thank for the nice blog. It is very helpful.
Is it a good practice to maintain a logic in gateway to manager token(instead of the auto generated session-id) for web and mobile application?
Generally, after login keycloak, gateway generate an uuid token to map with keycloak jwt token. The mapping info can be stored in redis. Bese on the uuid token TTL, gateway decide to refresh token or login again in Keycloak.

    comments user
    piotr.minkowski

    Weel, we can send JWT token in Authorization header as a bearer token

comments user
Eric

How can the gateway redirect user to Keycloak login page when the JWT is expired? Not it just show 401 without redirect.

    comments user
    piotr.minkowski

    Should it redirect the user in that case?

comments user
Eric Bu

Hello, Is it able to avoid the oauth2 login screen with the registration list?

comments user
tigersoft

Excellent article! Could you please extend it explaining how to consume this API via web application (i.e. Angular)? This may cause problems from configuration perspective to set up CORS settings and pass token obtained from public keycloak client to API gateway, to have all things work together. That would be great, thank you in advance.

    comments user
    piotr.minkowski

    Thanks. I’ll try to do the in the near future. Thanks for the suggestion.

comments user
Hassen

Thank you for your interesting article.
i have an angular application running in a different domain when i try to call my spring gateway i have a cors problem knowing that if i remove keyclaok as well as spring-boot-starter-oauth2-client from pom. xml I can access my gateway without any cors problems.
thanks in advance for your help

    comments user
    piotr.minkowski

    You can change the CORS configuration with `CorsConfigurationSource` bean:

    @Configuration
    @EnableWebFluxSecurity
    public class SecurityConfig {

    @Bean
    public SecurityWebFilterChain springSecurityFilterChain(ServerHttpSecurity http) {
    ...
    http.cors()...;
    return http.build();
    }

    @Bean
    CorsConfigurationSource corsConfigurationSource() {
    CorsConfiguration configuration = new CorsConfiguration();
    configuration.setAllowedOrigins(Arrays.asList("https://example.com"));
    configuration.setAllowedMethods(Arrays.asList("GET","POST"));
    UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
    source.registerCorsConfiguration("/**", configuration);
    return source;
    }

    }

comments user
sam

i want to secure my resource server with keycloak (client credentials) and also spring OAuth2 authorization server. My resource server should be able to process token either from keycloack or Spring’s Oauth2 auth server. How can i achieve this?

comments user
Sai

Can we replace keycloak with Google/GitHub OAuth2 provider? By doing so we no need to relay on traditional username & password authentication.

    comments user
    piotr.minkowski

    Yes, we can integrate it with many other OAuth providers including google, GitHub, or e.g. okta.

comments user
Lahcen Hayane

How can we make the POST request bu sending OAuth2 token?

    comments user
    piotr.minkowski

    You just need to set it inside the `Authorization` header: `Bearer …`

comments user
Suraj Kalloli

Hi,
i am using cloud keycloak for the test and for userinfo end point i am getting 502 bad gateway nginx

    comments user
    piotr.minkowski

    Strange. How do you run keycloak?

comments user
Deepak

How to configure the client id and client secret from database rather than configure at properties level.

    comments user
    piotr.minkowski

    But client secret and client id are configured in keycloak. The app just using this client to interact with keycloak

comments user
alex

How relevant is your article at the moment? The Spring developers have greatly changed the Spring-Security module. Are you planning to modify it to a new stack?

    comments user
    piotr.minkowski

    Yes, i’m thinkink about it. Until now, I didn’t update it, so it is based on the old version of ss

comments user
alex

I understand that you have implemented an option when Gateway acts as a client?

    comments user
    piotr.minkowski

    Yes

comments user
vikasdevelopermenon

Hi Piotr,
Thanks for this article. Is there a way can we skip the login page of keycloak with a multi realm approach ?

    comments user
    piotr.minkowski

    Well, you can obtain a token directly from keycloak with the following command and then use it as abearer token:
    “`
    curl -X POST http://localhost:8080/realms/demo/protocol/openid-connect/token \
    -d “grant_type=password” \
    -d “client_id=spring-with-test-scope” \
    -d “client_secret=IWLSnakHG8aNTWNaWuSj0a11UY4lzxd9” \
    -d “username=spring” \
    -d “password=Spring_123”
    “`

comments user
Vikas

Can you show same concept with github oauth2 apps

    comments user
    piotr.minkowski

    It would be a very similar implementation. It doesn’t bring anything additional

comments user
Beniton

Hi

Very nice article. Is there a way we can support multitenancy ? Means if i have more than one realms in Keycloak. What we might need to change to bring that support in Gateway.

Thanks,
Beniton

    comments user
    piotr.minkowski

    Yes, of course, you may create several keycloak providers in that case and switch between them

comments user
Long

Hello,
You’re using session in spring cloud gateway and deploy it in kubernetes.

When it scale to multiple pod. how you assure your request will be routed in the same pod? (Because if you get session in 1 pod, you cant use this session to get token in another pod)

    comments user
    piotr.minkowski

    Thwre are the ways on kubernetes how you can have a sticky session to a particular pod throught the ingress. However, in this article, I’m deploying anything on kubernetes

Leave a Reply