方法授权要完成的是资源服务根据jwt令牌完成对方法的授权,具体流程如下:
1、生成Jwt令牌时在令牌中写入用户所拥有的权限
我们给每个权限起个名字,例如某个用户拥有如下权限:
course_find_list:课程查询
course_pic_list:课程图片查询
2、在资源服务方法上添加注解PreAuthorize,并指定此方法所需要的权限
例如下边是课程管理接口方法的授权配置,它就表示要执行这个方法需要拥有course_find_list权限
@PreAuthorize("hasAuthority('course_pic_list')")
@Override
@GetMapping("/coursepic/list/{courseId}")
public CoursePic findCoursePic(@PathVariable("courseId") String courseId) {
return courseService.findCoursePic(courseId);
}
3、当请求有权限的方法时正常访问
4、当请求没有权限的方法时则拒绝访问
在服务的配置文件里面填叫@EnableGlobalMethodSecurity(prePostEnabled = true, securedEnabled = true)//激活方法上的,说明这个服务被调用需要授权
@Configuration
@EnableResourceServer
@EnableGlobalMethodSecurity(prePostEnabled = true, securedEnabled = true)//激活方法上的
public class ResourceServerConfig extends ResourceServerConfigurerAdapter {
//公钥
private static final String PUBLIC_KEY = "publickey.txt";
// get http://localhost:31200/course/coursepic/list/4028e58161bd3b380161bd3bcd2f0000
// 请求时没有携带令牌则报错
//定义JwtTokenStore,使用jwt令牌
@Bean
public TokenStore tokenStore(JwtAccessTokenConverter jwtAccessTokenConverter) {
return new JwtTokenStore(jwtAccessTokenConverter);
}
//定义JJwtAccessTokenConverter,使用jwt令牌
@Bean
public JwtAccessTokenConverter jwtAccessTokenConverter() {
JwtAccessTokenConverter converter = new JwtAccessTokenConverter();
converter.setVerifierKey(getPubKey());
return converter;
}
/**
* 获取非对称加密公钥 Key
*
* @return 公钥 Key
*/
private String getPubKey() {
Resource resource = new ClassPathResource(PUBLIC_KEY);
try {
InputStreamReader inputStreamReader = new
InputStreamReader(resource.getInputStream());
BufferedReader br = new BufferedReader(inputStreamReader);
return br.lines().collect(Collectors.joining("\n"));
} catch (IOException ioe) {
return null;
}
}
//Http安全配置,对每个到达系统的http请求链接进行校验
@Override
public void configure(HttpSecurity http) throws Exception {
//所有请求必须认证通过
http.authorizeRequests()
.antMatchers("/v2/api-docs","/swagger-resources/configuration/ui",
"/swagger-resources","/swagger-resources/configuration/security",
"/swagger-ui.html","/webjars/**","/course/coursepic/list/**","/**").permitAll()//,"/course/courseview/**"
.anyRequest().authenticated();
}
}
xc_user:用户表,存储了系统用户信息,用户类型包括:学生、老师、管理员等
xc_role:角色表,存储了系统的角色信息,学生、老师、教学管理员、系统管理员等。
xc_user_role:用户角色表,一个用户可拥有多个角色,一个角色可被多个用户所拥有
xc_menu:模块表,记录了菜单及菜单下的权限
xc_permission:角色权限表,一个角色可拥有多个权限,一个权限可被多个角色所拥有
导入依赖
org.springframework.cloud
spring-cloud-starter-openfeign
利用feign拦截器来实现
创建一个类实现RequestInterceptor接口
public class FeignClientInterceptor implements RequestInterceptor {
@Override
public void apply(RequestTemplate requestTemplate) {
ServletRequestAttributes requestAttributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
if (requestAttributes!=null){
HttpServletRequest request = requestAttributes.getRequest();
//取出当前请求的header,找到jwt令牌
Enumeration headerNames = request.getHeaderNames();
if (headerNames!=null){
while (headerNames.hasMoreElements()){
String headerName = headerNames.nextElement();
String headerValue = request.getHeader(headerName);
requestTemplate.header(headerName,headerValue);
}
}
}
// 将jwt令牌向下传递
}
}
将需要调用其他服务的服务的启动类注入Bean
@Bean
public FeignClientInterceptor getFeignClientInterceptor(){
return new FeignClientInterceptor();
}