by emanjusaka from ​ https://www.emanjusaka.top/archives/11 彼岸花开可奈何

本文欢迎分享与聚合,全文转载请留下原文地址。

Shiro权限框架认证失败默认是重定向页面的,这对于前后端分离的项目及其不友好,可能会造成请求404的问题。现在我们自定义过滤器实现认证失败返回json数据。

拦截器就是一道道的关卡,每一道关卡都有各自的职责。

实现思路

由于Shiro默认的过滤器认证失败后是进行重定向操作的,所以我们考虑自定义过滤器重写它的逻辑。

  1. 设置 ShiroShiroFilterFactoryBean拦截请求进行认证并配置自定义的拦截器。

  2. 实现自定义的拦截器,重写认证失败后的逻辑。

实现过程

  1. 配置 ShiroShiroFilterFactoryBean设置拦截请求进行认证

    @Bean
    public ShiroFilterFactoryBean shiroFilterFactoryBean(SecurityManager securityManager) {
    ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();
    shiroFilterFactoryBean.setSecurityManager(securityManager);
    Map<String, String> map = new LinkedHashMap<>();
    //登出
    map.put("/logout", "logout");
    // 登录
    map.put("/login","anon");
    //对所有用户认证
    map.put("/**", "authc");
    Map<String, Filter> filterMap = new HashMap<>();
    // 自定义的拦截器
    filterMap.put("authc",new ShiroLoginFilter());
    shiroFilterFactoryBean.setFilters(filterMap);
    shiroFilterFactoryBean.setFilterChainDefinitionMap(map);
    return shiroFilterFactoryBean;
    }

上面配置对登录接口进行了放行,对其他接口都要进行认证,这个可以根据自己的实际需要去配置。同时还要配置我们的自定义拦截器,拦截器Map 的key要和配置的认证authc一致,否则会不生效。

  1. 实现自定义的拦截器,重写认证失败后的逻辑。

    package com.icms.shiro.filter;
    
    import com.alibaba.fastjson.JSON;
    import com.icms.enu.ExceptionCodeEnum;
    import com.icms.exception.CustomException;
    import com.icms.page.Result;
    import org.apache.shiro.web.filter.authc.FormAuthenticationFilter;
    import org.camunda.bpm.model.bpmn.impl.instance.From; import javax.servlet.ServletRequest;
    import javax.servlet.ServletResponse;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    import java.io.PrintWriter; /**
    * @Author emanjusaka
    * @Date 2023/10/25 14:42
    * @Version 1.0
    */
    public class ShiroLoginFilter extends FormAuthenticationFilter {
    @Override
    protected boolean onAccessDenied(ServletRequest request, ServletResponse response) throws Exception {
    HttpServletResponse httpResponse = (HttpServletResponse) response;
    HttpServletRequest httpRequest = (HttpServletRequest) request;
    httpResponse.setStatus(200);
    httpResponse.setContentType("application/json;charset=utf-8");
    //解决跨域问题
    if ("OPTIONS".equals(httpRequest.getMethod())){
    httpResponse.setStatus(HttpServletResponse.SC_NO_CONTENT);;
    return true;
    }
    httpResponse.getWriter().print(JSON.toJSONString(new Result(ExceptionCodeEnum.STATUS_CODE_NO_LOGIN)));
    httpResponse.getWriter().flush();
    httpResponse.getWriter().close();
    return false;
    }
    }

    这里自定义拦截器继承FormAuthenticationFilter 重写了 onAccessDenied 方法。在onAccessDenied 方法中我们可以返回我们需要的 json 数据,也可以记录日志执行我们自己的方法。这里返回的数据是我自定义的Result 类,里面包含了错误码和错误信息。

    认证失败是我们的业务逻辑的错误而不是网络请求的错误,所以我们把HTTP的状态码设置成了 200 ,通过我们自己定义的Result来返回实际的错误信息。

    注意:Shiro本身是没有解决跨域问题的,我们要自己实现解决Shiro的跨域问题。

    例如/user/getUserInfo接口,没有配置过滤,就会被拦截,这个时候无论是在Controller上还是在接口实现上配置@CrossOrigin,都不会生效。这个时候需要做如下配置:

    //解决跨域问题
    if ("OPTIONS".equals(httpRequest.getMethod())){
    httpResponse.setStatus(HttpServletResponse.SC_NO_CONTENT);
    return true;
    }

    自己实现拦截器设置允许跨域也是可以的,这里使用的上述的方法。

扩展知识

Shiro中的拦截器

  1. authc拦截器:主要用于实现基于表单的身份验证,它会拦截用户登录表单提交的路径,并在拦截器工厂中配置该路径。此外,它负责创建登录认证所需的Token令牌,并触发登录认证流程。如果用户已经登录,那么将直接进入要访问的路径;如果用户未登录,则访问会被拒绝,并自动跳转到登录页面。

  2. authcBasic拦截器:主要用于实现基于HTTP基本认证的身份验证。

  3. logout拦截器:主要用于处理用户的注销请求。

  4. user拦截器:充当了整个安全管理器的入口,主要负责拦截需要安全控制的请求并进行处理。

  5. anon拦截器:这种拦截器允许不需要登录就能访问的资源,通常用于静态资源或者移动端接口。

  6. roles拦截器:主要负责用户的角色校验。

  7. perms拦截器和roles拦截器:这两个拦截器主要与授权相关,用于处理用户角色和权限相关的请求。

  8. port拦截器:它主要拦截网络请求,验证用户是否具有访问特定端口的权限。

  9. rest拦截器:用于在Web应用程序中对HTTP请求的请求方法(HTTP method)进行权限过滤和控制。它的作用是限制用户对某些HTTP请求方法的访问权限,例如GET、POST、PUT、DELETE等。通过该过滤器,您可以根据需要来控制某些请求方法的访问权限,并且可以根据不同的请求方法,对不同的用户或用户组进行特定的授权设置。

  10. ssl拦截器:主要用于处理SSL协议相关的请求。

  11. noSessionCreation拦截器:用于处理无状态会话的过滤器。

public enum DefaultFilter{
anno(AnonymousFilter.class),
authc(FormAuthenticationFilter.class),
authcBasic(BasicHttpAuthenticationFilter.class),
logout(LogoutFilter.class),
noSessionCreation(NoSessionCreationFilter.class),
perms(PermissionsAuthorizationFilter.class),
port(PortFilter.class),
rest(HttpMethodPermissionFilter.class),
roles(RolesAuthorizationFilter.class),
ssl(SslFilter.class),
user(UserFilter.class);
}

与身份验证相关的拦截器

  • authc(FormAuthenticationFilter)

    基于表单的拦截器;如“/**=authc”,如果没有登录会跳转到相应的登录页面登录。

    主要属性:

    usernameParam:表单提交的用户名参数名(username)。

    passwordParam:表单提交的密码参数名(password)。

    rememberMeParam:表单提交的记住我参数名(rememberMe)。

    loginUrl:登录页面地址(/login.jsp)。

    successUrl:登录成功后的默认重定向地址。

    failureKeyAttribute:登录失败后错误信息存储Key(shiroLoginFailure)。

  • authcBasic(BasicHttpAuthenticationFilter)

    Basic HTTP身份验证拦截器,主要属性:

    applicationName:弹出登录框显示的信息(application)。

  • logout(LogoutFilter)

    退出拦截器,主要属性:

    redirectUrl:退出成功后重定向的地址(/)。

    示例:“/logout=logout”

  • user(UserFilter)

    用户拦截器,用户已经身份验证/记住我登录的都可。

    示例:“/**=user”

  • anon(AnnonymousFilter)

    匿名拦截器,即不需要登录即可访问,一般用于静态资源过滤或者需要在登录之前进行的请求。

    示例:“/static/**=anon”

与授权相关的拦截器

  • roles(RolesAuthorizationFilter)

    角色授权拦截器,验证用户是否拥有所有角色。主要属性:

    loginUrl:登录页面地址(/login.jsp)。

    unauthorizedUrl:未授权后重定向的地址。

    示例:“/admin/**=roles[admin]”

  • perms(PermissionsAuthorizationFilter)

    权限授权拦截器,验证用户是否拥有所有权限,属性和roles一样。

    示例:“/user/**=perms[“user:create”]”

  • port(PortFilter)

    端口拦截器,主要属性:

    port(80):可以通过的端口。

    示例:“/test=port[80]”,如果用户访问该页面是非80端口,将自动将端口改为80并重定向到该80端口,其他路径/参数等都一样。

  • rest(HttpMethodPermissionFilter)

    rest风格拦截器,自动根据请求方法构建权限字符串(GET=read,POST=create,PUT=update,DELETE=delete,HEAD=read,TRACE=read,OPTIONS=read,MKCOL=create)构建权限字符串。

    示例:“/users=rest[user]”,会自动拼出“user:read,user:create,user:update,user:delete”权限字符串进行权限匹配(所有都得匹配,isPermittedAll)。

  • ssl(SslFilter)

    SSL拦截器,只有请求协议是https才能通过,否则自动跳转到https端口(443),其他和port拦截器一样。

其他拦截器

  • noSessionCreation(NoSessionCreationFilter)

    不创建会话拦截器,调用subject.getSession(false)不会有问题,但是如果subject.getSession(true)将抛出异常。

本文原创,才疏学浅,如有纰漏,欢迎指正。如果本文对您有所帮助,欢迎点赞,并期待您的反馈交流,共同成长。

原文地址: https://www.emanjusaka.top/archives/11

微信公众号:emanjusaka的编程栈

自定义过滤器配置 Shiro 认证失败返回 json 数据的更多相关文章

  1. Shiro 认证失败返回JSON

    Shiro框架默认认证失败后会返回到登录页面,在前后端分离项目中,需要返回JSON数据,以便前端或者app端解析处理. 实现方式: 1. 扩展shiro框架的UserFilter类,重写redirec ...

  2. 【转】ASP.NET Core WebAPI JWT Bearer 认证失败返回自定义数据 Json

    应用场景:当前我们给微信小程序提供服务接口,接口中使用了权限认证这一块,当我使用 JWT Bearer 进行接口权限认证的时候,返回的结果不是我们客户端想要的,其它我们想要给客户端返回统一的数据结构, ...

  3. shiro异步请求返回JSON响应

    shiro异步请求返回JSON响应 需求1:当shiro请求资源,但是没有进行认证时,默认是进行重定向,现在需要返回JSON响应.注意异步请求,服务器重定向后,ajax拿到的是浏览器重定向后的到的页面 ...

  4. SpringBoot+SpringSecurity+Thymeleaf认证失败返回错误信息踩坑记录

    Spring boot +Spring Security + Thymeleaf认证失败返回错误信息踩坑记录 步入8102年,现在企业开发追求快速,Springboot以多种优秀特性引领潮流,在众多使 ...

  5. springMvc配置xml使ResponseBody返回Json

    @ResponseBody 在返回的数据不是html标签的页面,而是其他某种格式的数据时(如json.xml等)使用: 不在springMvc中配置json的处理的话,我们通常会在Controller ...

  6. 配置完aop不能返回json

    遇到一个bug,配置了记录controller层的aop,后来发现是因为我aop是写在controller层(在springmvc的容器中)而开启aop配置却写在spring中,所以不起作用,需要在s ...

  7. struts2 的验证框架validation如何返回json数据 以方便ajax交互

    struts2 的验证框架validation简单,好用,但是input只能输出到jsp页面通过struts2的标签<s:fielderror  />才能取出,(EL应该也可以). 如果使 ...

  8. spingmvc 返回json数据日期格式化方法

    第一种: json 用的是这个依赖 <!-- JSON lib 开发包 以及它的依赖包 --> <dependency> <groupId>com.fasterxm ...

  9. Spring MVC 3.0 返回JSON数据的方法

    Spring MVC 3.0 返回JSON数据的方法1. 直接 PrintWriter 输出2. 使用 JSP 视图3. 使用Spring内置的支持// Spring MVC 配置<bean c ...

  10. idea+springmvc+spring+mybatis+maven整合返回json数据webapi

    首先看一张目录结构图: : 创建步骤: 1.创建maven  webapp工程, 创建完后的目录结构为: 2.添加项目依赖(添加jar包) 需要的jar包: spring-webmvc, spring ...

随机推荐

  1. 2023郑州轻工业大学校赛邀请赛wh

    在这里,很感谢程立老师的帮助和选择我,我以后会跟着程老师,既然热爱,就要走下去! 2022年4月2号,我代表河南工业大学与郑州17所高校在郑州轻工业大学举办的"卓见杯"郑州轻工业大 ...

  2. Java List集合根据某字段去重

    去重方法 单个字段为条件去重 /** * 单字段去重 * @param jackpotList1 新集合 * @param jackpotList 需要去重的集合 * @return */ priva ...

  3. PostgreSQL 10 文档: 系统表

    第 51 章 系统目录 目录 51.1. 概述 51.2. pg_aggregate 51.3. pg_am 51.4. pg_amop 51.5. pg_amproc 51.6. pg_attrde ...

  4. git: 解决每次操作git时都要输入账户、密码

    解决方案 $ git config --global credential.helper store 使用该命令即可解决问题

  5. 如何用 ModelScope 实现 “AI 换脸” 视频

    前言 当下,视频内容火爆,带有争议性或反差大的换脸视频总能吸引人视线.虽然 AI 换脸在市面上已经流行了许久,相关制作工具或移动应用也是数不胜数.但是多数制作工具多数情况下不是会员就是收费,而且替换模 ...

  6. #Powerbi 1分钟学会,RANK函数,多字段排名函数.

    一:思维导图&数据源示例 1.1思维导图 1.2示例数据源 二:参数构成 三:案例度量值 基础度量值 总销量 = CALCULATE(SUM('数据源'[销量])) 总销售额 = CALCUL ...

  7. AI绘画StableDiffusion实操教程:月光下的美人(含高清图片)

    本教程收集于:AIGC从入门到精通教程汇总 今天继续分享AI绘画实操教程,如何用lora包生成超真实好看质感超强的人物图片. 放大高清图已放到教程包内,需要的可以自取. 出图效果: 更多图片资源访问查 ...

  8. 破局DevOps|8大北极星指标指引研发效能方向

    放弃那些动辄就上百个的研发度量指标吧,8大北极星指标指引你的研发效能方向,1个北极星指标公式让你清晰了解​公司研发效能现状. 每当研发效能/DevOps业务做规划的时候,有的人就会毫无头绪,不知道如何 ...

  9. 【krpano】 ASP浏览量插件

    简述 这是一个Asp版krpano统计访问量案例,运用asp代码控制增值来实现的功能:现将案例上传网站供大家学习研究,希望对大家有所帮助. 功能 用户进入网页增值或刷新增值. 案例展示 所有文件如下图 ...

  10. 【规范】SpringBoot接口返回结果及异常统一处理,这样封装才优雅

    前言 缘由 博友的需求就是我最大的动力 博友一说话,本狗笑哈哈.博友要我写啥,我就写啥. 特来一篇关于SpringBoot接口返回结果及异常统一处理,虽说封不封装都能用,但咱后端也得给前端小姐姐留个好 ...