spring - Spring boot:Feign客户端休息调用不适用于oauth2,但可以在浏览器上使用
问题描述
有 2 个微服务,一个休息服务,一个是 websocket 服务。Websocket 服务有假装客户端与其余服务对话。
从浏览器工具(例如邮递员)调用休息服务时,调用正常工作。我们只传递Authorization
带有值的标头Bearer XXXXX
当从没有拦截器的 feign 调用时,我们会得到 401:未授权,这是正确的行为。
当将此拦截器添加到代码库时,因为 XXXXX 是真正的令牌,当然,我们会收到 403
@Component
public class FeignOauth2Interceptor implements RequestInterceptor {
private static final String AUTHORIZATION_HEADER = "Authorization";
@Override
public void apply(RequestTemplate template) {
SecurityContext securityContext = SecurityContextHolder.getContext();
Authentication authentication =
securityContext.getAuthentication();
template.header(AUTHORIZATION_HEADER, "Bearer XXXXX");
}
}
拦截器被调用,因为我们在添加后看到不同的错误代码,我们从 401 变为 403。
我们在这里缺少什么?
提前致谢
解决方案
我认为在拦截器中硬编码令牌不是一个好主意,您可以从OAuth2AuthenticationDetails获取令牌:
@Bean
public RequestInterceptor requestTokenBearerInterceptor() {
return new RequestInterceptor() {
@Override
public void apply(RequestTemplate requestTemplate) {
Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
if(authentication == null) return;
OAuth2AuthenticationDetails details = (OAuth2AuthenticationDetails) authentication.getDetails();
requestTemplate.header("Authorization", "Bearer " + details.getTokenValue());
}
};
}
此外,您可以使用OAuth2FeignRequestInterceptor,它从上下文中获取您的令牌并在需要时自行刷新它。在我看来,这是一个更好的解决方案。您可以在此处找到使用它的示例:https ://stackoverflow.com/a/53454703/10697598
推荐阅读
- typescript - 如何使数组仅包含具有匿名对象导出的数字?
- javascript - 如何停止物体的运动
- pandas - 如何仅选择偶数标题的特定列?
- reactjs - 如何使用 axios 上传带有 jodit-react 的图像
- python - 使用python3检查字符串是否是有效的回文
- string - 两列中每一对的 vsetdiff
- html - 导航栏折叠切换不起作用(Bootstrap5)
- javascript - 客户端 Javascript:是否可以在 DOM 中获取 HTML 元素的布局文本再现?
- ios - swiftui 在长按消息应用程序后将视图带到中心并模糊背景
- reactjs - 从 React Router v6 Navigate 检索状态