4 微服务之间认证 4.1 需求分析
前边章节已经实现了用户携带身份令牌和JWT令牌访问微服务,微服务获取jwt并完成授权。 当微服务访问微服务,此时如果没有携带JWT则微服务会在授权时报错。
测试课程预览:
1、将课程管理服务和CMS全部添加授权配置
2、用户登录教学管理前端,进入课程发布界面,点击课程发布,观察课程管理服务端报错如下:
[AppleScript] 纯文本查看 复制代码 feign.FeignException: status 401 reading CmsPageClient#save(CmsPage); content: {"error":"unauthorized","error_description":"Full authentication is required to access this
resource"}
分析原因:
由于课程管理访问CMS时没有携带JWT令牌导致。
解决方案:
微服务之间进行调用时需携带JWT。 4.2 Feign 拦截器
4.2.1 定义Feign拦截器
微服务之间使用feign进行远程调用,采用feign拦截器实现远程调用携带JWT。 在common工程添加依赖:
[AppleScript] 纯文本查看 复制代码 <dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring‐cloud‐starter‐openfeign</artifactId>
</dependency>
在Common工程定义拦截器如下:
[AppleScript] 纯文本查看 复制代码 package com.xuecheng.framework.interceptor;
public class FeignClientInterceptor implements RequestInterceptor {
@Override
public void apply(RequestTemplate requestTemplate) {
try {
//使用RequestContextHolder工具获取request相关变量
ServletRequestAttributes attributes = (ServletRequestAttributes)
RequestContextHolder.getRequestAttributes();
if(attributes!=null){
//取出request
HttpServletRequest request = attributes.getRequest();
Enumeration<String> headerNames = request.getHeaderNames();
if (headerNames != null) {
while (headerNames.hasMoreElements()) {
String name = headerNames.nextElement();
String values = request.getHeader(name);
if(name.equals("authorization")){
//System.out.println("name="+name+"values="+values);
requestTemplate.header(name, values);
}
}
}
}
}catch (Exception e) {
e.printStackTrace();
}
} }
4.2.2 使用Feign拦截器
本例子中课程管理调用cms需要携带jwt,所以需要在课程管理中定义Feign拦截器bean,在启动类中定义bean如 下:
[AppleScript] 纯文本查看 复制代码 @Bean public FeignClientInterceptor feignClientInterceptor(){ return new FeignClientInterceptor(); }
4.2.3 测试
执行课程发布,提示发布成功。
|