Spring Security的方法授权 用户授权 Fegin拦截器的使用

1 业务流程

方法授权要完成的是资源服务根据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、当请求没有权限的方法时则拒绝访问

2 服务授权

在服务的配置文件里面填叫@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();
    }
}

4 权限的数据模型

Spring Security的方法授权 用户授权 Fegin拦截器的使用_第1张图片

xc_user:用户表,存储了系统用户信息,用户类型包括:学生、老师、管理员等
xc_role:角色表,存储了系统的角色信息,学生、老师、教学管理员、系统管理员等。
xc_user_role:用户角色表,一个用户可拥有多个角色,一个角色可被多个用户所拥有
xc_menu:模块表,记录了菜单及菜单下的权限
xc_permission:角色权限表,一个角色可拥有多个权限,一个权限可被多个角色所拥有

5 微服务之间运用Feign实现带着jwt远程调用

导入依赖

        
            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();
    }

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

你可能感兴趣的:(Spring Security的方法授权 用户授权 Fegin拦截器的使用)