【问题标题】:feign client - retrieving jwt token from a service and setting it automatically in feign clientfeign 客户端 - 从服务中检索 jwt 令牌并在 feign 客户端中自动设置它
【发布时间】:2020-04-29 07:50:38
【问题描述】:

我正在使用 feign 客户端调用其他服务。 服务 A 需要联系服务 B 并且必须通过身份验证服务进行身份验证。

如果我不使用 feign,我会先使用 resttemplate 调用身份验证服务。获取令牌,将其添加到我要发送到服务 B 的 msg 的标头中。

是否可以配置为假装一个端点,他从那里获取令牌以便自动完成?

【问题讨论】:

    标签: spring jwt spring-cloud-feign feign


    【解决方案1】:

    考虑到您已经在身份验证服务中准备了 JWT 授权和身份验证,我可以这样举个例子:

    第一个使用OpenFeign的feign客户端(spring最新的feign实现)

    import org.springframework.cloud.openfeign.FeignClient;
    import org.springframework.http.ResponseEntity;
    import org.springframework.web.bind.annotation.GetMapping;
    import org.springframework.web.bind.annotation.PostMapping;
    import org.springframework.web.bind.annotation.RequestBody;
    
    // Must give a url to NOT use load balancer (we have a gateway)
    // Otherwise it will throw "did you forget load balancer?" error
    @FeignClient(url = "http://localhost:<port>/", name = "UserClient")
    public interface UserClient
    {
        @PostMapping(path = "login", consumes = "application/json")
        ResponseEntity<String> login(@RequestBody String user);
        
        @GetMapping(path = "hello")
        ResponseEntity<String> sayHello();
    }
    

    然后像这样获取jwt令牌:(这段代码可以在一些mvc项目中)

    String username = someuser
    String password = somepassword
    // I wasn't able to create a json but the below data would work with spring security
    String user = "{\"username\":\"" + username + "\",\"password\":\"" + password + "\"}";
    ResponseEntity<String> responseEntity = userClient.login(user);
    // your token could be like "<username> - <token>" kind of structure
    String token = responseEntity.getBody();
    

    然后用openfeign做一个认证请求,这段代码可以在mvc项目什么的

    // If you put the token in session
    String bearer = (String) req.getSession().getAttribute("Bearer");
    UserClient helloClient = Feign.builder().client(new Client.Default((SSLSocketFactory) SSLSocketFactory.getDefault(), null)).contract(new SpringMvcContract()).requestInterceptor(new RequestInterceptor()
    {
        @Override
        public void apply(RequestTemplate template)
        {
            System.err.println("This is adding jwt header to resttemplate of the feign");
            template.header("Authorization", "Bearer " + bearer);
        }
    }).decoder(new Decoder()
    {
        @Override
        public Object decode(Response response, Type type) throws IOException, DecodeException, FeignException
        {
            // If you have returned responseentity, feign client must be able to understand it
            return new ResponseEntity<>(response.body().toString(), HttpStatus.resolve(response.status()));
        }
    }).target(UserClient.class, "http://localhost:4441/hello/");
    // My responsebody is a simple string but it could be anything you want, as long as you have the decoder
    String response = helloClient.sayHello().getBody();
    

    Feign 客户端无法动态设置标头,尤其是来自 jwt 令牌,因为这些令牌来自另一个请求或会话中。这就是我使用 builder 设置动态标题的原因。如果你使用BasicAuthRequestInterceptor,你可以创建一个BasicAuthRequestInterceptor的@Bean,并在里面设置一个静态的用户名和密码。

    【讨论】:

      猜你喜欢
      • 2019-02-18
      • 2018-12-10
      • 2019-11-04
      • 1970-01-01
      • 2018-07-19
      • 2020-12-16
      • 2020-12-20
      • 2020-09-10
      • 1970-01-01
      相关资源
      最近更新 更多