简体   繁体   English

将 Spring Cloud 负载均衡与 KeycloakRestTemplate 集成

[英]Integrate Spring Cloud load balancing with KeycloakRestTemplate

I have a microservice landscape configured with Spring Cloud discovery so I'm able to access other service instances just using their id's:我有一个配置了 Spring Cloud 发现的微服务环境,因此我可以仅使用它们的 id 访问其他服务实例:

public class MyClass {

    @Autowired
    @LoadBalanced
    private RestTemplate restTemplate;

    public String doOtherStuff() {
        String results = restTemplate.getForObject("http://stores/stores", String.class);
        return results;
    }
}

Now I want to access a service which needs OAuth2 authorization.现在我想访问需要 OAuth2 授权的服务。 I use a Keycloak server in order to provide it and Keycloak already provides an adapter with an specific KeycloakRestTemplate .我使用 Keycloak 服务器来提供它,而 Keycloak 已经提供了一个带有特定KeycloakRestTemplate的适配器。 Anyway, how to enhance it with load balancing ?无论如何,如何通过负载平衡来增强它?

We need to create a specific KeycloakRestTemplate which will use a LoadBalancerInterceptor : 我们需要创建一个特定的KeycloakRestTemplate,它将使用LoadBalancerInterceptor

@Configuration
@EnableWebSecurity
@ComponentScan(basePackageClasses = KeycloakSecurityComponents.class)
public class SecurityConfig extends KeycloakWebSecurityConfigurerAdapter {

    @Bean
    @Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)
    @LoadBalanced
    public KeycloakRestTemplate keycloakRestTemplate(
            KeycloakClientRequestFactory keycloakClientRequestFactory,
            LoadBalancerInterceptor interceptor) {
        KeycloakRestTemplate result = new KeycloakRestTemplate(
            keycloakClientRequestFactory);
        // Add the interceptor for load balancing
        result.getInterceptors().add(interceptor);
        return result;
    }

    //More configurations for keycloak

}

So there's the chance of getting an Authorized / LoadBalanced template: 因此,有机会获得一个Authorized / LoadBalanced模板:

@Autowired
@LoadBalanced
protected KeycloakRestTemplate restTemplate;

See also: 也可以看看:

your solution is not realy good, because你的解决方案不是很好,因为

@Bean
@Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)
@LoadBalanced
public KeycloakRestTemplate keycloakRestTemplate(
        KeycloakClientRequestFactory keycloakClientRequestFactory,
        LoadBalancerInterceptor interceptor) {
    KeycloakRestTemplate result = new KeycloakRestTemplate(
        keycloakClientRequestFactory);
    // Add the interceptor for load balancing
    result.getInterceptors().add(interceptor);
    return result;
}

not has worked, becouse you have got exception没有工作,因为你有例外

The dependencies of some of the beans in the application context form a cycle:
...
┌─────┐
|  keycloakRestTemplate defined in class path resource [...]
↑     ↓
|  ribbonInterceptor defined in class path resource [org/springframework/cloud/client/loadbalancer/LoadBalancerAutoConfiguration$LoadBalancerInterceptorConfig.class]
↑     ↓
|  org.springframework.cloud.client.loadbalancer.LoadBalancerAutoConfiguration     (field private java.util.List org.springframework.cloud.client.loadbalancer.LoadBalancerAutoConfiguration.restTemplates)
└─────┘

What do you have to do?你必须做什么?

@Bean
@LoadBalanced
public KeycloakRestTemplate keycloakRestTemplate(
        KeycloakClientRequestFactory keycloakClientRequestFactory) {
    return new KeycloakRestTemplate(keycloakClientRequestFactory);
}

without @Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE) then you get singleton which you cane use like this没有@Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)那么你会得到单例,你可以像这样使用

@Autowired
protected KeycloakRestTemplate restTemplate;

or you can define restTemplate like prototype或者你可以像原型一样定义restTemplate

@Bean
@Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)
@LoadBalanced
public KeycloakRestTemplate keycloakRestTemplate(
        KeycloakClientRequestFactory keycloakClientRequestFactory) {
    return new KeycloakRestTemplate(keycloakClientRequestFactory);
}

and then use like this然后像这样使用

@Autowired
@LoadBalanced
protected KeycloakRestTemplate restTemplate;

Edit: The solution of Xtreme Biker has not worked with SpringBoot 2 and Keycloak 6 because of problem with cycle, my first proposition is not threads/sesions save, the second does not work because of been will be createing before run @LoadBalanced and the restTemplate wchich is created based on prototype is to without sets interceptor :|编辑:由于循环问题,Xtreme Biker 的解决方案没有与 SpringBoot 2 和 Keycloak 6 一起使用,我的第一个命题不是线程/会话保存,第二个不起作用,因为将在运行 @LoadBalanced 和restTemplate之前创建wchich是基于prototype创建的,不需要设置拦截器:|

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM