登录鉴权简单实现 您所在的位置:网站首页 java鉴权 登录鉴权简单实现

登录鉴权简单实现

2023-05-28 16:54| 来源: 网络整理| 查看: 265

这是我参与「第五届青训营 」伴学笔记创作活动的第 9 天

作为一个用户系统,登录是必不可少的,登录除了记录用户外,也是分辨用户进行鉴权的必不可少的一步。今天来简单记录一下我学习到的一种鉴权思路。

注解定义 @NoNeedLogin:该注解用在方法上,有该注解的方法意味着不用登录就可以直接访问 @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.METHOD) public @interface NoNeedLogin { } @NoValidPrivilege:该注解用在方法上,有该注解的方法意味着不用鉴权就可以直接访问。 @Retention(RetentionPolicy.RUNTIME) public @interface NoValidPrivilege { } @NotOpen:该注解用在方法上,有该注解的方法意味着停止访问。 @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.METHOD) public @interface NotOpen { } 登录拦截器 @Slf4j @Component public class SmartAuthenticationInterceptor extends HandlerInterceptorAdapter { public static final String TOKEN_NAME = "request-token"; @Value("${access-control-allow-origin}") private String accessControlAllowOrigin; @Autowired private LoginTokenService loginTokenService; @Autowired private RedisService redisService; @Autowired private PageOptionService pageOptionService; /** * 拦截服务器端响应处理ajax请求返回结果 * * @param request * @param response * @param handler * @return * @throws Exception */ @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { //跨域设置 this.crossDomainConfig(response); boolean isHandlerMethod = handler instanceof HandlerMethod; if (! isHandlerMethod) { return true; } //不开放的注解 boolean isNotOpen = ((HandlerMethod) handler).getMethodAnnotation(NotOpen.class) != null; if (isNotOpen){ this.outputResult(response,ResponseCodeConst.NOT_OPEN); return false; } //不需要登录的注解 Boolean isNoNeedLogin = ((HandlerMethod) handler).getMethodAnnotation(NoNeedLogin.class) != null; if (isNoNeedLogin) { return true; } //放行的Uri前缀 String uri = request.getRequestURI(); String contextPath = request.getContextPath(); String target = uri.replaceFirst(contextPath, ""); if (CommonConst.CommonCollection.contain(CommonConst.CommonCollection.IGNORE_URL, target)) { return true; } //需要做token校验, 消息头的token优先于请求query参数的token String xHeaderToken = request.getHeader(TOKEN_NAME); String xRequestToken = request.getParameter(TOKEN_NAME); String xAccessToken = null != xHeaderToken ? xHeaderToken : xRequestToken; if (null == xAccessToken) { this.outputResult(response, ResponseCodeConst.NOT_LOGIN); return false; } //根据token获取登录用户 Long uid = loginTokenService.getUidByToken(xAccessToken); //token无效或token过期 if(Objects.isNull(uid)){ this.outputResult(response,ResponseCodeConst.NOT_LOGIN); return false; } //根据uid从缓存获取用户数据 RequestUserData requestUserData = redisService.getObject(RedisConstants.LOGIN_USER_REQUEST_DATA + uid, RequestUserData.class); if (Objects.isNull(requestUserData)){ //redis过期也是无效登录 this.outputResult(response,ResponseCodeConst.NOT_LOGIN); return false; } //判断账号是否被停用 if(requestUserData.getStatus().equals(StatusEnum.DISABLED)){ this.outputResult(response,new ResponseCodeConst("账号已被管理员停止使用!")); return false; } //判断接口权限 String methodName = ((HandlerMethod) handler).getMethod().getName(); String className = ((HandlerMethod) handler).getBeanType().getName(); List list = SmartStringUtil.splitConvertToList(className, "\."); String controllerName = list.get(list.size() - 1); Method m = ((HandlerMethod) handler).getMethod(); Class cls = ((HandlerMethod) handler).getBeanType(); boolean isClzAnnotation = cls.isAnnotationPresent(NoValidPrivilege.class); boolean isMethodAnnotation = m.isAnnotationPresent(NoValidPrivilege.class); NoValidPrivilege noValidPrivilege = null; if (isClzAnnotation) { noValidPrivilege = cls.getAnnotation(NoValidPrivilege.class); } else if (isMethodAnnotation) { noValidPrivilege = m.getAnnotation(NoValidPrivilege.class); } //绕过权限验证 if(true) { SmartRequestTokenUtil.setUser(requestUserData); return true; } //不需验证权限 if (noValidPrivilege != null) { SmartRequestTokenUtil.setUser(requestUserData); return true; } //需要验证权限 boolean privilegeValidPass = pageOptionService.checkRoleHavePrivilege(requestUserData.getRoleId(), controllerName,methodName); if (!privilegeValidPass) { this.outputResult(response, ResponseCodeConst.NOT_HAVE_PRIVILEGES); return false; } SmartRequestTokenUtil.setUser(requestUserData); return true; } /** * 配置跨域 * * @param response */ private void crossDomainConfig(HttpServletResponse response) { response.setHeader("Access-Control-Allow-Origin", accessControlAllowOrigin); response.setHeader("Access-Control-Allow-Credentials", "true"); response.setHeader("Access-Control-Allow-Methods", "POST, GET, PUT, OPTIONS, DELETE, PATCH"); response.setHeader("Access-Control-Expose-Headers", "*"); response.setHeader("Access-Control-Allow-Headers", "Authentication,Origin, X-Requested-With, Content-Type, " + "Accept, x-access-token"); response.setHeader("Cache-Control", "no-cache"); response.setHeader("Pragma", "no-cache"); response.setHeader("Expires ", "-1"); } /** * 错误输出 * * @param response * @param responseCodeConst * @throws IOException */ private void outputResult(HttpServletResponse response, ResponseCodeConst responseCodeConst) throws IOException { ResponseDTO error = ResponseDTO.error(responseCodeConst); String msg = JSONObject.toJSONString(error); response.setContentType("application/json;"); response.getWriter().write(msg); response.flushBuffer(); } @Override public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception { SmartRequestTokenUtil.removeUser(); } } 鉴权方法 public boolean checkRoleHavePrivilege(Integer roleId,String controllerName,String methodName) { if(roleId == null) { return false; } ConcurrentMap map = rolePrivilegeMap.get(roleId); if(map == null) { return false; } List methodList = map.get(controllerName); if(CollectionUtils.isEmpty(methodList)) { return false; } return methodList.contains(methodName); }


【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

    专题文章
      CopyRight 2018-2019 实验室设备网 版权所有