自定义注解鉴权

导读:本篇文章讲解 自定义注解鉴权,希望对大家有帮助,欢迎收藏,转发!站点地址:www.bmabk.com

自定义注解鉴权

编写注解

@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(value = ElementType.METHOD)
public @interface BlogAuthentication {

    String[] value();

}

编写配置拦截规则

@Component
public class WebConfig implements WebMvcConfigurer {

    @Override
    public void addCorsMappings(CorsRegistry registry) {
        registry.addMapping("/**")
                .allowedOriginPatterns("*")
                .allowedHeaders("*")
                .allowedMethods("GET", "POST", "DELETE", "PUT")
                .allowCredentials(true)
                .maxAge(3600);
    }

    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        // 添加放行的路径
        String[] addPath = {"/**"};
        String[] excludePath = {"/user/login",
                "/static/**","/css/*.css",
                "/fonts/**","*.html","/*.html","*.ico","/*.ico/",
                "/js/**","/img/**","/*.ico","/*.css","/images/**"
        };
        registry.addInterceptor(new BlogConfig()).addPathPatterns(addPath).excludePathPatterns(excludePath);
    }


    private CorsConfiguration buildConfig() {
        CorsConfiguration corsConfiguration = new CorsConfiguration();
        corsConfiguration.addAllowedOrigin("*");
        corsConfiguration.addAllowedHeader("*");
        corsConfiguration.addAllowedMethod("*");
        corsConfiguration.addExposedHeader("token");
        return corsConfiguration;
    }

    @Bean
    public CorsFilter corsFilter() {
        UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
        source.registerCorsConfiguration("/**", buildConfig());
        return new CorsFilter(source);
    }
}

开始鉴权

@Component
@Slf4j
public class BlogConfig  implements HandlerInterceptor {


    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        String token = request.getHeader("token");
        Map<String,Object> infoMap = new HashMap<>();
        boolean state = false;
        try{
            //token验证
            DecodedJWT tokenInfo = JwtUtil.getTokenInfo(token);
            String userId = tokenInfo.getClaim("userId").asString();
            BlogUserServiceImpl blogUserService = InterceptorBeanUtil.getBean(BlogUserServiceImpl.class, request);
            BlogUser blogUser = blogUserService.getById(userId);
            // 鉴权
            state = authentication(infoMap,blogUser,handler,blogUserService);
        }catch (SignatureVerificationException e){
            e.printStackTrace();
            infoMap.put("code", BlogResult.ERROR);
            infoMap.put("msg","网站签名验证异常");
        }catch (TokenExpiredException e){
            infoMap.put("code", BlogResult.ERROR);
            infoMap.put("msg","token已过期");
        }catch (AlgorithmMismatchException e){
            infoMap.put("code", BlogResult.ERROR);
            infoMap.put("msg","算法不一致");
        }catch (Exception e){
            infoMap.put("code", BlogResult.ERROR);
            infoMap.put("msg","程序异常");
        }
        if (state){
            return true;
        }else {
            response.setCharacterEncoding("UTF-8");
            response.setContentType("application/json; charset=utf-8");
            PrintWriter out = response.getWriter();
            out.write(JSONUtil.parse(infoMap).toString());
            out.flush();
            out.close();
            return false;
        }
    }


    private boolean authentication(Map<String,Object> infoMap, BlogUser blogUser, Object handler,BlogUserServiceImpl blogUserService){
        //添加返回信息
        if (handler instanceof HandlerMethod){
            HandlerMethod method = (HandlerMethod) handler;
            BlogAuthentication methodAnnotation = method.getMethodAnnotation(BlogAuthentication.class);

            if (blogUser.getUserType() == 1){
                if (blogUser.getSurvivalTime().getTime() < new Date().getTime()) {
                    blogUserService.lambdaUpdate().set(BlogUser::getUserStatus,2).eq(BlogUser::getUid,blogUser.getUid()).update();
                    infoMap.put("code", BlogResult.USER_ERROR);
                    infoMap.put("msg","当前卡密已失效");
                    return false;
                }
            }

            // 禁用和失效
            if (blogUser.getUserStatus() == 0){
                infoMap.put("code", BlogResult.ERROR);
                infoMap.put("msg","当前卡密已禁用");
                return false;
            }
            if (blogUser.getUserStatus() == 2){
                infoMap.put("code", BlogResult.ERROR);
                infoMap.put("msg","当前卡密已失效");
                return false;
            }

            if (methodAnnotation == null){
                // 没有当前注解则都可以访问
                infoMap.put("code", BlogResult.SUCCESS_CODE);
                infoMap.put("msg","验证成功");
                return true;
            }else {
                // userType = 0
                Integer userType = blogUser.getUserType();
                boolean contains = Arrays.stream(methodAnnotation.value()).collect(Collectors.toList()).contains(String.valueOf(userType));
                if (contains){
                    infoMap.put("code", BlogResult.SUCCESS_CODE);
                    infoMap.put("msg","验证成功");
                    return true;
                }else {
                    infoMap.put("code", BlogResult.ERROR);
                    infoMap.put("msg","当前卡密权限不足");
                    return false;
                }
            }
        }
        return false;
    }

}

工具类

public class InterceptorBeanUtil<T> {


    public static <T> T getBean(Class<T> cls, HttpServletRequest request){
        WebApplicationContext applicationContext = WebApplicationContextUtils.getRequiredWebApplicationContext(request.getServletContext());
        return applicationContext.getBean(cls);
    }

}

public class JwtUtil {

    //properties
    private static final String SIGN="asd0asdkak~dasdkaowppaldpw;-dlak";

    public static String genereteToken(Map<String,String> mapinfo){
        Calendar instance = Calendar.getInstance();
        //有效期为24小时
        instance.add(Calendar.MINUTE,60*24);
        //map用户存储claim——声明的信息
        Map<String,Object> map=new HashMap<>();
        //生成token
        JWTCreator.Builder builder = JWT.create();
        //添加payload
        mapinfo.forEach((k,v)->{
            builder.withClaim(k,v);
        });
        //指定令牌过期时间
        builder.withExpiresAt(instance.getTime());
        //指定算法-生成token
        String token = builder.sign(Algorithm.HMAC256(SIGN));
        return token;
    }

    /**
     * 验证token的合法性
     * @param token token令牌值
     * throw 抛出异常-表示验证失败
     */
    public synchronized static void decodeToken(String token){
        JWT.require(Algorithm.HMAC256(SIGN)).build().verify(token);
    }

    /**
     * 获取token信息的方法
     * @param token token令牌值
     * @return DecodedJWT对象
     * throw 抛出异常-表示验证失败
     */
    public synchronized static DecodedJWT getTokenInfo(String token){
        DecodedJWT decodedJWT = JWT.require(Algorithm.HMAC256(SIGN)).build().verify(token);
        return decodedJWT;
    }

    public static String getUserId(HttpServletRequest request){
        String token = request.getHeader("token");
        return getTokenInfo(token).getClaim("userId").asString();
    }

}

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/112561.html

(0)
Java光头强的头像Java光头强

相关推荐

发表回复

登录后才能评论
极客之音——专业性很强的中文编程技术网站,欢迎收藏到浏览器,订阅我们!