SpringBoot中shiro过滤器重写与配置的方法
发表于:2024-09-23 作者:千家信息网编辑
千家信息网最后更新 2024年09月23日,本篇内容介绍了"SpringBoot中shiro过滤器重写与配置的方法"的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读
千家信息网最后更新 2024年09月23日SpringBoot中shiro过滤器重写与配置的方法
本篇内容介绍了"SpringBoot中shiro过滤器重写与配置的方法"的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!
问题
遇到问题:在前后端分离跨域访问的项目中shiro进行权限拦截失效 (即使有正确权限的访问也会被拦截) 时造成302重定向错误等问题
报错:Response for preflight is invalid (redirect)
1.302原因:使用ajax访问后端项目时无法识别重定向操作
2.shiro拦截失效原因:跨域访问时有一种带预检访问的跨域,即访问时先发出一条methods为OPTIONS的的访问,这种访问不带cookie等信息。造成shiro误判断为无权限访问。
3.一般使用的访问methods都是:get,post,put,delete
解决方案
1.让shiro不对预检访问拦截
2. 改变shiro中无权限,未登录拦截的重定向,这就需要重写几个过滤器
3. 将重写的过滤器进行配置
实现代码
1.重写shiro 登录 过滤器
过滤器运行机制:
(1)shiro是否拦截访问 以 isAccessAllowed返回值为准
(2)如果isAccessAllowed 方法返回false会进入onAccessDenied方法重定向至 登录 or 无权限 页面
package com.yaoxx.base.shiro;import java.io.PrintWriter;import javax.servlet.ServletRequest;import javax.servlet.ServletResponse;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;import org.apache.commons.lang3.StringUtils;import org.apache.shiro.web.filter.authc.FormAuthenticationFilter;import org.apache.shiro.web.util.WebUtils;import org.springframework.http.HttpStatus;/*** * @version: 1.0* @since: JDK 1.8.0_91* @Description:* 未登录过滤器,重写方法为【跨域的预检访问】放行*/public class MyAuthenticationFilter extends FormAuthenticationFilter { @Override protected boolean isAccessAllowed(ServletRequest request, ServletResponse response, Object mappedValue) { boolean allowed = super.isAccessAllowed(request, response, mappedValue); if (!allowed) { // 判断请求是否是options请求 String method = WebUtils.toHttp(request).getMethod(); if (StringUtils.equalsIgnoreCase("OPTIONS", method)) { return true; } } return allowed; } @Override protected boolean onAccessDenied(ServletRequest request, ServletResponse response) throws Exception { if (isLoginRequest(request, response)) { // 判断是否登录 if (isLoginSubmission(request, response)) { // 判断是否为post访问 return executeLogin(request, response); } else { // sessionID已经注册,但是并没有使用post方式提交 return true; } } else { HttpServletRequest req = (HttpServletRequest) request; HttpServletResponse resp = (HttpServletResponse) response; /* * 跨域访问有时会先发起一条不带token,不带cookie的访问。 * 这就需要我们抓取这条访问,然后给他通过,否则只要是跨域的访问都会因为未登录或缺少权限而被拦截 * (如果重写了isAccessAllowed,就无需下面的判断) */// if (req.getMethod().equals(RequestMethod.OPTIONS.name())) {// resp.setStatus(HttpStatus.OK.value());// return true;// } /* * 跨域的第二次请求就是普通情况的request了,在这对他进行拦截 */ String ajaxHeader = req.getHeader(CustomSessionManager.AUTHORIZATION); if (StringUtils.isNotBlank(ajaxHeader)) { // 前端Ajax请求,则不会重定向 resp.setHeader("Access-Control-Allow-Origin", req.getHeader("Origin")); resp.setHeader("Access-Control-Allow-Credentials", "true"); resp.setContentType("application/json; charset=utf-8"); resp.setCharacterEncoding("UTF-8"); resp.setStatus(HttpStatus.UNAUTHORIZED.value());//设置未登录状态码 PrintWriter out = resp.getWriter();// Mapresult = new HashMap<>();// result.put("MESSAGE", "未登录用户"); String result = "{"MESSAGE":"未登录用户"}"; out.println(result); out.flush(); out.close(); } else { // == 如果是普通访问重定向至shiro配置的登录页面 == // saveRequestAndRedirectToLogin(request, response); } } return false; }}
2.重写role权限 过滤器
package com.yaoxx.base.shiro;import java.io.IOException;import java.io.PrintWriter;import javax.servlet.ServletRequest;import javax.servlet.ServletResponse;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;import org.apache.commons.lang3.StringUtils;import org.apache.shiro.web.filter.authz.RolesAuthorizationFilter;import org.apache.shiro.web.util.WebUtils;import org.springframework.http.HttpStatus;import org.springframework.web.bind.annotation.RequestMethod;/*** * @author: yao_x_x* @since: JDK 1.8.0_91* @Description: role的过滤器*/public class MyAuthorizationFilter extends RolesAuthorizationFilter { @Override public boolean isAccessAllowed(ServletRequest request, ServletResponse response, Object mappedValue) throws IOException { boolean allowed =super.isAccessAllowed(request, response, mappedValue); if (!allowed) { String method = WebUtils.toHttp(request).getMethod(); if (StringUtils.equalsIgnoreCase("OPTIONS", method)) { return true; } } return allowed; } @Override protected boolean onAccessDenied(ServletRequest request, ServletResponse response) throws IOException { HttpServletRequest req = (HttpServletRequest) request; HttpServletResponse resp = (HttpServletResponse) response; if (req.getMethod().equals(RequestMethod.OPTIONS.name())) { resp.setStatus(HttpStatus.OK.value()); return true; } // 前端Ajax请求时requestHeader里面带一些参数,用于判断是否是前端的请求 String ajaxHeader = req.getHeader(CustomSessionManager.AUTHORIZATION); if (StringUtils.isNotBlank(ajaxHeader)) { // 前端Ajax请求,则不会重定向 resp.setHeader("Access-Control-Allow-Origin", req.getHeader("Origin")); resp.setHeader("Access-Control-Allow-Credentials", "true"); resp.setContentType("application/json; charset=utf-8"); resp.setCharacterEncoding("UTF-8"); PrintWriter out = resp.getWriter(); String result = "{"MESSAGE":"角色,权限不足"}"; out.println(result); out.flush(); out.close(); return false; } return super.onAccessDenied(request, response); }}
3.配置过滤器
@Configurationpublic class ShiroConfiguration { @Autowired private RoleService roleService; @Autowired private PermissionService permissionService; @Bean("shiroFilter") public ShiroFilterFactoryBean shiroFilter(@Qualifier("securityManager")SecurityManager manager) { ShiroFilterFactoryBean bean = new ShiroFilterFactoryBean(); bean.setSecurityManager(manager); /* 自定义filter注册 */ Mapfilters = bean.getFilters(); filters.put("authc", new MyAuthenticationFilter()); filters.put("roles", new MyAuthorizationFilter()); Map filterChainDefinitionMap =new LinkedHashMap<>(); filterChainDefinitionMap.put("/login", "anon");// filterChainDefinitionMap.put("/*", "authc");// filterChainDefinitionMap.put("/admin", "authc,roles[ADMIN]"); bean.setFilterChainDefinitionMap(filterChainDefinitionMap); return bean; }
"SpringBoot中shiro过滤器重写与配置的方法"的内容就介绍到这里了,感谢大家的阅读。如果想了解更多行业相关的知识可以关注网站,小编将为大家输出更多高质量的实用文章!
过滤器
登录
权限
方法
配置
前端
问题
普通
内容
原因
情况
更多
用户
知识
页面
项目
UTF-8
不对
实用
学有所成
数据库的安全要保护哪些东西
数据库安全各自的含义是什么
生产安全数据库录入
数据库的安全性及管理
数据库安全策略包含哪些
海淀数据库安全审计系统
建立农村房屋安全信息数据库
易用的数据库客户端支持安全管理
连接数据库失败ssl安全错误
数据库的锁怎样保障安全
双线服务器托管价格
计算机数据库专排
12306的服务器与系统
博客算数据库吗
软件测试数据库笔试题
预约上门按摩养生软件开发
阿里和百度哪个服务器多
免费von服务器地址
美国国家车辆管理数据库
网络安全委员会成立文件
联合国商品数据库使用教程
世界互联网大会黑科技无线电
从事软件开发销售工作
银川软件开发培训
教员学生层次数据库模型
山东服务器虚拟化建设
lol闪退服务器乱码
炎颂科技软件互联网
沂南软件开发培训哪家好
网络安全培训机制
预约上门按摩养生软件开发
安卓服务器构建
怀柔区定制软件开发
道闸系统无数据库
软件开发期间如何保密
刺激战场在哪个服务器上下载
如何提升网络安全分析
软件开发前期设计
万豪集团的网络安全策略
bbin挂机软件开发