SpringBoot2.0 整合 Shiro 框架,实现用户权限管理
程序员文章站
2023-11-12 08:50:16
一、Shiro简介 1、基础概念 Apache Shiro是一个强大且易用的Java安全框架,执行身份验证、授权、密码和会话管理。作为一款安全框架Shiro的设计相当巧妙。Shiro的应用不依赖任何容器,它不仅可以在JavaEE下使用,还可以应用在JavaSE环境中。 2、核心角色 1)Subjec ......
github源码地址:知了一笑 https://github.com/cicadasmile/middle-ware-parent
一、shiro简介
1、基础概念
apache shiro是一个强大且易用的java安全框架,执行身份验证、授权、密码和会话管理。作为一款安全框架shiro的设计相当巧妙。shiro的应用不依赖任何容器,它不仅可以在javaee下使用,还可以应用在javase环境中。
2、核心角色
1)subject:认证主体
代表当前系统的使用者,就是用户,在shiro的认证中,认证主体通常就是username和password,或者其他用户相关的唯一标识。
2)securitymanager:安全管理器
shiro架构中最核心的组件,通过它可以协调其他组件完成用户认证和授权。实际上,securitymanager就是shiro框架的控制器。
3)realm:域对象
定义了访问数据的方式,用来连接不同的数据源,如:关系数据库,配置文件等等。
3、核心理念
shiro自己不维护用户和权限,通过subject用户主体和realm域对象的注入,完成用户的认证和授权。
二、整合springboot2框架
1、核心依赖
<dependency> <groupid>org.apache.shiro</groupid> <artifactid>shiro-core</artifactid> <version>1.4.0</version> </dependency> <dependency> <groupid>org.apache.shiro</groupid> <artifactid>shiro-spring</artifactid> <version>1.4.0</version> </dependency>
2、shiro核心配置
@configuration public class shiroconfig { /** * session manager:会话管理 * 即用户登录后就是一次会话,在没有退出之前,它的所有信息都在会话中; * 会话可以是普通javase环境的,也可以是如web环境的; */ @bean("sessionmanager") public sessionmanager sessionmanager(){ defaultwebsessionmanager sessionmanager = new defaultwebsessionmanager(); //设置session过期时间 sessionmanager.setglobalsessiontimeout(60 * 60 * 1000); sessionmanager.setsessionvalidationschedulerenabled(true); // 去掉shiro登录时url里的jsessionid sessionmanager.setsessionidurlrewritingenabled(false); return sessionmanager; } /** * securitymanager:安全管理器 */ @bean("securitymanager") public securitymanager securitymanager(userrealm userrealm, sessionmanager sessionmanager) { defaultwebsecuritymanager securitymanager = new defaultwebsecuritymanager(); securitymanager.setsessionmanager(sessionmanager); securitymanager.setrealm(userrealm); return securitymanager; } /** * shirofilter是整个shiro的入口点,用于拦截需要安全控制的请求进行处理 */ @bean("shirofilter") public shirofilterfactorybean shirofilter(securitymanager securitymanager) { shirofilterfactorybean shirofilter = new shirofilterfactorybean(); shirofilter.setsecuritymanager(securitymanager); shirofilter.setloginurl("/userlogin"); shirofilter.setunauthorizedurl("/"); map<string, string> filtermap = new linkedhashmap<>(); filtermap.put("/userlogin", "anon"); shirofilter.setfilterchaindefinitionmap(filtermap); return shirofilter; } /** * 管理shiro中一些bean的生命周期 */ @bean("lifecyclebeanpostprocessor") public lifecyclebeanpostprocessor lifecyclebeanpostprocessor() { return new lifecyclebeanpostprocessor(); } /** * 扫描上下文,寻找所有的advistor(通知器) * 将这些advisor应用到所有符合切入点的bean中。 */ @bean public defaultadvisorautoproxycreator defaultadvisorautoproxycreator() { defaultadvisorautoproxycreator proxycreator = new defaultadvisorautoproxycreator(); proxycreator.setproxytargetclass(true); return proxycreator; } /** * 匹配所有加了 shiro 认证注解的方法 */ @bean public authorizationattributesourceadvisor authorizationattributesourceadvisor(securitymanager securitymanager) { authorizationattributesourceadvisor advisor = new authorizationattributesourceadvisor(); advisor.setsecuritymanager(securitymanager); return advisor; } }
3、域对象配置
@component public class userrealm extends authorizingrealm { @resource private sysusermapper sysusermapper ; @resource private sysmenumapper sysmenumapper ; /** * 授权(验证权限时调用) * 获取用户权限集合 */ @override public authorizationinfo dogetauthorizationinfo (principalcollection principals) { sysuserentity user = (sysuserentity)principals.getprimaryprincipal(); if(user == null) { throw new unknownaccountexception("账号不存在"); } list<string> permslist; //默认用户拥有最高权限 list<sysmenuentity> menulist = sysmenumapper.selectlist(); permslist = new arraylist<>(menulist.size()); for(sysmenuentity menu : menulist){ permslist.add(menu.getperms()); } //用户权限列表 set<string> permsset = new hashset<>(); for(string perms : permslist){ if(stringutils.isempty(perms)){ continue; } permsset.addall(arrays.aslist(perms.trim().split(","))); } simpleauthorizationinfo info = new simpleauthorizationinfo(); info.setstringpermissions(permsset); return info; } /** * 认证(登录时调用) * 验证用户登录 */ @override protected authenticationinfo dogetauthenticationinfo( authenticationtoken authtoken) throws authenticationexception { usernamepasswordtoken token = (usernamepasswordtoken)authtoken; //查询用户信息 sysuserentity user = sysusermapper.selectone(token.getusername()); //账号不存在 if(user == null) { throw new unknownaccountexception("账号或密码不正确"); } //账号锁定 if(user.getstatus() == 0){ throw new lockedaccountexception("账号已被锁定,请联系管理员"); } simpleauthenticationinfo info = new simpleauthenticationinfo (user, user.getpassword(), bytesource.util.bytes(user.getsalt()), getname()); return info; } @override public void setcredentialsmatcher(credentialsmatcher credentialsmatcher) { hashedcredentialsmatcher shacredentialsmatcher = new hashedcredentialsmatcher(); shacredentialsmatcher.sethashalgorithmname(shiroutils.hashalgorithmname); shacredentialsmatcher.sethashiterations(shiroutils.hashiterations); super.setcredentialsmatcher(shacredentialsmatcher); } }
4、核心工具类
public class shiroutils { /** 加密算法 */ public final static string hashalgorithmname = "sha-256"; /** 循环次数 */ public final static int hashiterations = 16; public static string sha256(string password, string salt) { return new simplehash(hashalgorithmname, password, salt, hashiterations).tostring(); } // 获取一个测试账号 admin public static void main(string[] args) { // 3743a4c09a17e6f2829febd09ca54e627810001cf255ddcae9dabd288a949c4a system.out.println(sha256("admin","123")) ; } /** * 获取会话 */ public static session getsession() { return securityutils.getsubject().getsession(); } /** * subject:主体,代表了当前“用户” */ public static subject getsubject() { return securityutils.getsubject(); } public static sysuserentity getuserentity() { return (sysuserentity)securityutils.getsubject().getprincipal(); } public static long getuserid() { return getuserentity().getuserid(); } public static void setsessionattribute(object key, object value) { getsession().setattribute(key, value); } public static object getsessionattribute(object key) { return getsession().getattribute(key); } public static boolean islogin() { return securityutils.getsubject().getprincipal() != null; } public static void logout() { securityutils.getsubject().logout(); } }
5、自定义权限异常提示
@restcontrolleradvice public class shiroexception { @exceptionhandler(authorizationexception.class) public string authorizationexception (){ return "抱歉您没有权限访问该内容!"; } @exceptionhandler(exception.class) public string handleexception(exception e){ return "系统异常!"; } }
三、案例演示代码
1、测试接口
@restcontroller public class shirocontroller { private static logger logger = loggerfactory.getlogger(shirocontroller.class) ; @resource private sysmenumapper sysmenumapper ; /** * 登录测试 * http://localhost:7011/userlogin?username=admin&password=admin */ @requestmapping("/userlogin") public void userlogin ( @requestparam(value = "username") string username, @requestparam(value = "password") string password){ try{ subject subject = shiroutils.getsubject(); usernamepasswordtoken token = new usernamepasswordtoken(username, password); subject.login(token); logger.info("登录成功"); }catch (exception e) { e.printstacktrace(); } } /** * 服务器每次重启请求该接口之前必须先请求上面登录接口 * http://localhost:7011/menu/list 获取所有菜单列表 * 权限要求:sys:user:shiro */ @requestmapping("/menu/list") @requirespermissions("sys:user:shiro") public list list(){ return sysmenumapper.selectlist() ; } /** * 用户没有该权限,无法访问 * 权限要求:ccc:ddd:bbb */ @requestmapping("/menu/list2") @requirespermissions("ccc:ddd:bbb") public list list2(){ return sysmenumapper.selectlist() ; } /** * 退出测试,退出后没有任何权限 */ @requestmapping("/userlogout") public string logout (){ shiroutils.logout(); return "success" ; } }
2、测试流程
1)、登录后取得权限 http://localhost:7011/userlogin?username=admin&password=admin 2)、访问有权限接口 http://localhost:7011/menu/list 3)、访问无权限接口 http://localhost:7011/menu/list2 4)、退出登录 http://localhost:7011/userlogout
四、源代码地址
github地址:知了一笑 https://github.com/cicadasmile/middle-ware-parent 码云地址:知了一笑 https://gitee.com/cicadasmile/middle-ware-parent
下一篇: Ai简单绘制质感的app图标
推荐阅读
-
SpringBoot2.0 整合 Shiro 框架,实现用户权限管理
-
SpringBoot2.0 整合 SpringSecurity 框架,实现用户权限安全管理
-
jwt,spring security ,feign,zuul,eureka 前后端分离 整合 实现 简单 权限管理系统 与 用户认证的实现
-
shiro学习三(spring boot整合shiro读取数据库数据实现用户登录,权限认证)
-
ASP.NET MVC+EF框架+EasyUI实现权限管理系列(12)-实现用户异步登录和T4模板
-
springboot+shiro实现用户登录认证和权限管理(二)
-
SpringBoot+Shiro(用户角色权限管理的后端代码实现)
-
SpringBoot2.0 整合 SpringSecurity 框架,实现用户权限安全管理
-
SpringBoot2.0 整合 Shiro 框架,实现用户权限管理
-
ASP.NET MVC+EF框架+EasyUI实现权限管理系列(12)-实现用户异步登录和T4模板