欢迎您访问 最编程 本站为您分享编程语言代码,编程技术文章!
您现在的位置是: 首页

Shiro 整合 JWT,实现身份验证和特权验证(实施过程清晰详细)

最编程 2024-04-28 07:36:47
...
public class JWTFilter extends BasicHttpAuthenticationFilter { /* * 过滤器执行流程: * isAccessAllowed()->isLoginAttempt()->executeLogin() */ // 是否允许访问 @Override protected boolean isAccessAllowed(ServletRequest request, ServletResponse response, Object mappedValue) { if (isLoginAttempt(request, response)) { // 有认证意愿 try { executeLogin(request, response); return true; } catch (Exception e) { // token错误 responseError(response,e.getMessage()); } } // 没有认证意愿(可能是登录行为或者为游客访问),放行 // 此处放行是因为有些操作不需要权限也可以执行,而对于那些需要权限才能执行的操作自然会因为没有token而在权限鉴定时被拦截 return true; } // 是否有认证意愿(即是否携带token) @Override protected boolean isLoginAttempt(ServletRequest request, ServletResponse response) { HttpServletRequest httpServletRequest = (HttpServletRequest) request; String token = httpServletRequest.getHeader("token"); return token != null; } // 执行认证 @Override protected boolean executeLogin(ServletRequest request, ServletResponse response) throws Exception { HttpServletRequest httpServletRequest = (HttpServletRequest) request; String token = httpServletRequest.getHeader("token"); JWTToken jwt = new JWTToken(token); // 使用自定义的JWTToken而不是默认的UsernamePasswordToken getSubject(request, response).login(jwt); // 调用了realm中的认证方法,没有出现异常则证明认证成功 return true; } @Override protected boolean preHandle(ServletRequest request, ServletResponse response) throws Exception { HttpServletRequest req= (HttpServletRequest) request; HttpServletResponse res= (HttpServletResponse) response; res.setHeader("Access-control-Allow-Origin", req.getHeader("Origin")); res.setHeader("Access-control-Allow-Methods", "GET,POST,OPTIONS,PUT,DELETE"); res.setHeader("Access-control-Allow-Headers", req.getHeader("Access-Control-Request-Headers")); // 跨域时会首先发送一个option请求,这里我们给option请求直接返回正常状态 if (req.getMethod().equals(RequestMethod.OPTIONS.name())) { res.setStatus(HttpStatus.OK.value()); // 返回true则继续执行拦截链,返回false则中断后续拦截,直接返回,option请求显然无需继续判断,直接返回 return false; } return super.preHandle(request, response); } // 非法请求跳转 private void responseError(ServletResponse response, String msg) { HttpServletResponse httpServletResponse = (HttpServletResponse) response; try { // msg封装为get请求的请求参数,即拼接在url后面,对于中文信息需要进行utf-8编码 msg = URLEncoder.encode(msg, StandardCharsets.UTF_8); // 跳转至控制器unauthorized httpServletResponse.sendRedirect("/unauthorized/" + msg); } catch (IOException e) { System.out.println(e.getMessage()); } } }