Spring Boot实现OAuth 2.0(二)-- 自定义权限验证

自定义拦截器进行权限验证

涉及到的姿势:

  • 自定义注解
  • 拦截器
  • Spring Boot添加拦截器

文章目录:

自定义注解

@Target(ElementType.METHOD)//作用在方法
@Retention(RetentionPolicy.RUNTIME)//仅在运行时
@Documented
public @interface RoleAnnotation {

    /**
     * <b>“且”关系的Role</b>
     * <p>必须指定type</p>
     */
    public static String TYPE_AND = "and";

    /**
     * <b>“或”关系的Role</b>
     */
    public static String TYPE_OR = "or";

    /**
     * <b>“混合”关系的Role</b>
     * <p>必须指定type</p>
     */
    public static String TYPE_MIXED 
                            = "mixed";

    /**
     * <b>Role之间的关联方式</b>
     */
    String type() default 
                RoleAnnotation.TYPE_OR;

    /**
     * <b>“且”关系的Role</b>
     * <p>必须指定type</p>
     */
    String[] and() default {};

    /**
     * <b>“或”关系的Role</b>
     */
    @AliasFor("value")
    String[] or() default {};

    @AliasFor("or")
    String[] value() default {};

    /**
     * <b>“混合”关系的Role</b>
     * <p>必须指定type</p>
     */
    String mixed() default "";
    // ( (hr && fe) || admin )

}

在这里定义的是自定义注解,只相当于接口,还没有实现。
在下面的拦截器中,会出现自定义注解的实现。
在这里提两个姿势点:

  1. @AliasFor(“or”)是取别名,这样就可以让使用注解人,使用自己喜欢的注解关键字。
  2. value()方法是注解的默认方法,给value赋值的时候,@RoleAnnotation(value = “”) 可以直接写成@RoleAnnotation( “”)。再加上@AliasFor的作用,你就可以让自定义注解,将缺省值赋值给你想要的那个字段。

自定义拦截器

@Service("qiYunRoleInterceptor")
public class RoleInterceptor implements HandlerInterceptor {

    @Autowired
    private TokenStore tokenStore;

    @Override
    public boolean preHandle(
    HttpServletRequest request,
    HttpServletResponse response,
    Object handler)
            throws Exception {
        HandlerMethod handlerMethod =(HandlerMethod) handler;
        RoleAnnotation roleAnnotation = 
                handlerMethod.getMethodAnnotation(RoleAnnotation.class);// 在这里使用了自定义注解,也就相当于注解的实现类
        if (roleAnnotation == null) {
            return true;
        }

        String token = request.getParameter("access_token");
        if (StringUtils.isEmpty(token)) {
            noPermission(response);
            return false;
        }
        OAuth2Authentication auth = tokenStore.readAuthentication(token);
        Collection<GrantedAuthority> authorities = auth.getAuthorities();
        if (authorities.isEmpty()) {
            noPermission(response);
            return false;
        }

        Set<String> permissons = new HashSet<String>();
        for (GrantedAuthority authority : authorities) {
            permissons.add(authority.getAuthority());
        }

        boolean hasRole = false;
        String dealType = roleAnnotation.type();
        switch (dealType) {
            case RoleAnnotation.TYPE_OR :
                String[] orRoles = roleAnnotation.or();
                for (String orRole : orRoles) {
                    if (permissons.contains(orRole)) {
                        hasRole = true;
                        break;
                    }
                };
                break;
            case RoleAnnotation.TYPE_AND :
                String[] andRoles = roleAnnotation.and();
                Set<String> requireRoles = new HashSet<String>();
                for (String role : andRoles) {
                    requireRoles.add(role);
                }
                if (permissons.containsAll(requireRoles)) {
                    hasRole = true;
                }
                break;
            case RoleAnnotation.TYPE_MIXED :
                break;
        }

        if (!hasRole) {
            noPermission(response);
        }
        return hasRole;
    }

    private void noPermission(HttpServletResponse response) throws IOException {
        response.setContentType("application/json; charset=utf-8");  
        response.setCharacterEncoding("UTF-8");  

        JSONObject json = new JSONObject();
        json.put("error code", "500");
        json.put("description", "no permission");

        String error = json.toString();
        OutputStream out = response.getOutputStream();  
        out.write(error.getBytes("UTF-8"));  
        out.flush();  
        out.close();
    }

}

配置WebMvcConfigurer

@Configuration
public class MvcConfigurer implements WebMvcConfigurer {

    @Autowired
    @Qualifier("qiYunRoleInterceptor")
    private HandlerInterceptor interceptor;

    @Override
    public void addInterceptors(InterceptorRegistry registry) {
         registry.addInterceptor(interceptor).addPathPatterns("/api/**");
    }

}
  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值