在使用OAuth2的时候碰到的两个问题:

问题1

首先,不引入JWT的时候,为了单点登录,我们使用携带Token的方式去请求资源服务。但是我们的微服务是需要进行原程调用的,这时就会发现使用了Feign进行远程调用的服务报错了。正如标题所报的那样,因为就算我们携带了token去访问了该服务,但是由于远程调用的时候并没有携带token去请求对应的资源,导致请求失败了。解决的方法也简单,引入配置就行。

feign:
  oauth2:
    enabled: true
    load-balanced: true


问题2

引入了JWT之后,我发现使用了Feign的服务又不行了。后来各种搜索才发现,还是跟上面一样的问题。这里详细内容推荐查看: 跳转

我这边给出解决办法。

 首先在对应服务里面编写一个配置类,这个类实现RequestInterceptor接口。

class BearerTokenRequestInterceptor implements RequestInterceptor {
    private static final Pattern BEARER_TOKEN_HEADER_PATTERN = Pattern.compile("^Bearer (?<token>[a-zA-Z0-9-._~+/]+=*)$",
            Pattern.CASE_INSENSITIVE);//按照JWT的格式要求做匹配

    @Override
    public void apply(RequestTemplate template) {
        final String authorization = HttpHeaders.AUTHORIZATION;
        ServletRequestAttributes requestAttributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        if (Objects.nonNull(requestAttributes)) {
            String authorizationHeader = requestAttributes.getRequest().getHeader(HttpHeaders.AUTHORIZATION);
            Matcher matcher = BEARER_TOKEN_HEADER_PATTERN.matcher(authorizationHeader);
            if (matcher.matches()) {
                // 清除token头 避免传染
                template.header(authorization);
                template.header(authorization, authorizationHeader);
            }
        }
    }
}
编写完之后,我们讲这个类注册到IOC容器中。
@Configuration
public class WebConfig {


    @Bean
    public BearerTokenRequestInterceptor bearerTokenRequestInterceptor(){
        return new BearerTokenRequestInterceptor();
    }
}

此时我们使用postman,携带请求头的方式去发起请求(不能再用浏览器携带参数那个了,我们这边配置的就是从请求头中拿到令牌)

 

添加完之后发起请求,大功告成。

 

Logo

权威|前沿|技术|干货|国内首个API全生命周期开发者社区

更多推荐