最全Shiro教程,一篇学会Shiro权限管理 |
您所在的位置:网站首页 › shiro缓存管理 › 最全Shiro教程,一篇学会Shiro权限管理 |
声明:本文是博主观看bilibili上Java涛哥视频学习的Shiro框架所整理笔记,学完思路清晰,原文代码大致相同,原视频链接附上,方便以后学习查看。 本文项目源码加数据库 https://download.csdn.net/download/qq_45299673/69324339 Shiro 一、权限管理1.1 基于主页的权限管理1.2 基于用户和权限的权限管理1.3 基于角色的访问控制(RBAC) 二、Shiro2.1 认证和授权2.2 常见的安全框架2.3 shrio核心功能2.4 Shiro核心组件2.5 shiro的使用2.6 shrio认证流程 三、SpringBoot整合Shiro3.1 导入依赖application.yml配置 3.2 Shiro配置3.3 测试3.4 内置JDBCRealm作为数据源JdbcRealm规定的表结构 3.5 shiro的标签的使用常用标签 四、自定义Realm实现权限管理4.1 数据库设计4.2 创建DAO层4.3 application.yml4.4 pom.xml4.5 自定义Realm配置类4.6 shiro配置4.7 shiro业务层4.8 Controller层4.9 整合layUI 五、加密5.1 Shiro加密5.2 密码认证 六、Shiro的退出登录七、授权7.1 HTML授权7.2 过滤器授权7.3 注解授权7.4 手动授权 Apache Shiro是一个强大且易用的Java安全框架,执行身份验证、授权、密码和会话管理。Shiro 可以非常容易的开发出足够好的应用,其不仅可以用在 JavaSE 环境,也可以用在 JavaEE 环境。 一、权限管理不同身份的人进入系统所完成的操作不同,如下图,当一个系统包含左侧所有菜单功能时,要求不同人员登录展示不同权限下的菜单,这时候就需要学习权限管理,看完本文就可轻松掌握。 设计多种页面,当不同权限的用户访问时,跳转不同的用户,如下图,用户1登录跳转到index1.html,用户2登录跳转到index2.html,缺陷比较大且繁琐,不建议使用。 缺点:适用于用户级别较少的,不能动态分配权限 1.2 基于用户和权限的权限管理利用用户表、用户权限表、权限表三张表,每个用户在中间表分配权限 创建用户表、角色表、权限表和两张中间表用户角色表、角色权限表五张表,每次新加用户时只需要授予角色就可获得相对的权限。 Anthentication 认证,验证用户是否有相应的身份 登录认证 Authorization 授权,权限验证,通过认证的用户检查是否有权限或者角色 Session Management 会话管理,用户在认证成功后创建会话,在没有退出之前,当前用户的所有信息都会保存在这个会话中 Cryptograsphy 加密,对敏感信息加密 支持的特性: 1.Web Support Shrio提供了过滤器,可以通过过滤器拦截web请求来处理web应用的访问控制 2.Caching 缓存支持,shiro可以缓存用户信息以及用户的角色权限信息,可以提高执行效率 3.concurrency shiro支持多线程应用 4.Run As 允许一个用户以另一种身份去访问 5.Remeber Me 记住密码 6.Testing 提供测试支持 Shiro是一个安全框架,不提供用户、权限的维护,用户的权限管理需要我们去设计 2.4 Shiro核心组件
![]() 1.添加maven依赖 org.apache.shiro shiro-core 1.4.12.创建shiro的配置文件 在resource下创建ini后缀文件 [users] zhangsan=123456,seller lisi=123123,ckmgr admin=admin,admin [roles] admin=* seller=order-add,order-del,order-list ckmgr=ck-add,ck-del,ck-list3.使用测试 public class ShiroTest { public static void main(String[] args) { Scanner sc=new Scanner(System.in); System.out.println("请输入账号:"); String username = sc.next(); System.out.println("请输入密码:"); String password = sc.next(); //1.创建安全管理器 DefaultSecurityManager securityManager=new DefaultSecurityManager(); //2.创建realm IniRealm iniRealm=new IniRealm("classpath:shiro.ini"); //3.将realm设置给安全管理器 securityManager.setRealm(iniRealm); //4.将Realm设置给SecurityUtil工具 SecurityUtils.setSecurityManager(securityManager); //5.通过SecurityUtil工具类获取subject对象 Subject subject=SecurityUtils.getSubject(); //认证流程 //将认证账号和密码封装到token中 UsernamePasswordToken token=new UsernamePasswordToken(username,password); //通过subject对象调用login方法进行认证 boolean flag=false; try{ subject.login(token); flag=true; }catch (IncorrectCredentialsException e){ flag=false; } System.out.println(flag?"登录成功":"登录失败"); //授权 //判断是否有某个角色 System.out.println(subject.hasRole("seller")); //判断是否有某个权限 System.out.println(subject.isPermitted("order-del")); } } 2.6 shrio认证流程SpringBoot没有提供对Shiro的自动配置,因为Spring家族有自己的安全框架 config/shiroConfig.java import org.apache.shiro.realm.text.IniRealm; import org.apache.shiro.spring.web.ShiroFilterFactoryBean; import org.apache.shiro.web.mgt.DefaultWebSecurityManager; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import java.util.HashMap; import java.util.Map; @Configuration public class ShiroConfig { @Bean public IniRealm getIniRealm(){ IniRealm iniRealm=new IniRealm("classpath:shiro.ini"); return iniRealm; } @Bean public DefaultWebSecurityManager getDefaultWebSecurityManager(IniRealm iniRealm){ DefaultWebSecurityManager securityManager=new DefaultWebSecurityManager(); //securityManager要完成校验,需要realm securityManager.setRealm(iniRealm); return securityManager; } @Bean public ShiroFilterFactoryBean getShiroFilterFactoryBean(DefaultWebSecurityManager defaultWebSecurityManager){ ShiroFilterFactoryBean filter=new ShiroFilterFactoryBean(); filter.setSecurityManager(defaultWebSecurityManager); //设置shiro的拦截规则 //anon 匿名用户可访问 authc 认证用户可访问 //user 使用RemeberMe的用户可访问 perms 对应权限可访问 //role 对应的角色可访问 Map filterMap=new HashMap(); filterMap.put("/","anon"); filterMap.put("/login.html","anon"); filterMap.put("/register.html","anon"); filterMap.put("/user/login","anon"); filterMap.put("/user/register","anon"); filterMap.put("/static/**","anon"); filterMap.put("/**","authc"); filter.setFilterChainDefinitionMap(filterMap); filter.setLoginUrl("/login.html"); //设置未授权页面跳转到登录页面 filter.setUnauthorizedUrl("/login.html"); return filter; } } 3.3 测试 UserServiceImpl.java@Service public class UserServiceImpl { public void checkLogin(String username,String Password) throws Exception{ Subject subject= SecurityUtils.getSubject(); UsernamePasswordToken token=new UsernamePasswordToken(username,Password); subject.login(token); } } UserController.java@Controller @RequestMapping("/user") public class UserController { @Autowired UserServiceImpl userService; @RequestMapping("/login") public String login(String username,String password){ try { userService.checkLogin(username,password); return "index"; } catch (Exception e) { System.out.println("密码错误"); return "login"; } } } login.html DOCTYPE html> Title login页面 账号: 密码:通过shiro.ini定义正确的登录密码 [user] admin=admin
用户信息表:users create table users( id int primary key auto_increment, username varchar(60) not null unique, password varchar(20) not null, password_salt varchar(20) );角色信息表: user_roles create table user_roles( id int primary key auto_increment, username varchar(60) not null, role_name varchar(100) not null );权限信息表:roles_permissions create table roles_permissions( id int primary key auto_increment, role_name varchar(100) not null, permission varchar(100) not null );
步骤 创建SpringBoot整合Mybatis 添加shiro依赖 配置Shiro @Configuration public class ShiroConfig { @Bean public JdbcRealm getJDBCRealm(DataSource dataSource){ JdbcRealm jdbcRealm=new JdbcRealm(); //JdbcRealm会自行从数据库查询用户及权限数据(数据库表结构必须符合JdbcRealm规范) jdbcRealm.setDataSource(dataSource); //JdbcRealm默认开启认证功能,需要手动开启授权功能 jdbcRealm.setPermissionsLookupEnabled(true); return jdbcRealm; } @Bean public DefaultWebSecurityManager getDefaultWebSecurityManager(JdbcRealm jdbcRealm){ DefaultWebSecurityManager securityManager=new DefaultWebSecurityManager(); //securityManager要完成校验,需要realm securityManager.setRealm(jdbcRealm); return securityManager; } @Bean public ShiroFilterFactoryBean getShiroFilterFactoryBean(DefaultWebSecurityManager defaultWebSecurityManager){ ShiroFilterFactoryBean filter=new ShiroFilterFactoryBean(); filter.setSecurityManager(defaultWebSecurityManager); //设置shiro的拦截规则 //anon 匿名用户可访问 authc 认证用户可访问 //user 使用RemeberMe的用户可访问 perms 对应权限可访问 //role 对应的角色可访问 Map filterMap=new HashMap(); filterMap.put("/","anon"); filterMap.put("/login.html","anon"); filterMap.put("/register.html","anon"); filterMap.put("/user/login","anon"); filterMap.put("/user/register","anon"); filterMap.put("/static/**","anon"); filterMap.put("/**","authc"); filter.setFilterChainDefinitionMap(filterMap); filter.setLoginUrl("/login.html"); //设置未授权页面跳转到登录页面 filter.setUnauthorizedUrl("/login.html"); return filter; } }测试结果同上 当用户认证进入到主页之后,需要显示用户信息及当前用户的权限信息,shiro提供了一套标签用于在页面来进行权限数据的呈现 Shiro提供了可供JSP使用的标签以及Thymeleaf标签 JSP页面中引用 Thymeleaf模板中引用 在pom.xml中导入thymeleaf模板对shiro标签的支持依赖 com.github.theborakompanioni thymeleaf-extras-shiro 2.0.0 在ShiroConfig中配置Shiro的方言支持 @Configuration public class ShiroConfig { @Bean public ShiroDialect getShiroDialect(){ return new ShiroDialect(); } } Thymeleaf模板中引入shiro的命名空间 常用标签 标签,登录后不显示,游客状态下显示 标签 ,登录后显示 显示登录用户的用户名 ## 显示用户角色 ## 显示用户权限具体用法如下: 数据库添加如下信息 当游客身份登录 当要使用自己定义的数据结构表,就需要告诉Realm,更改为自己设计的数据源 4.1 数据库设计SQL语句 SET FOREIGN_KEY_CHECKS=0; -- ---------------------------- -- Table structure for `tb_permissions` -- ---------------------------- DROP TABLE IF EXISTS `tb_permissions`; CREATE TABLE `tb_permissions` ( `permission_id` int NOT NULL AUTO_INCREMENT, `permission_code` varchar(60) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL, `permission_name` varchar(60) DEFAULT NULL, PRIMARY KEY (`permission_id`) ) ENGINE=InnoDB AUTO_INCREMENT=13 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci; -- ---------------------------- -- Records of tb_permissions -- ---------------------------- INSERT INTO `tb_permissions` VALUES ('1', 'sys:c:save', '入库'); INSERT INTO `tb_permissions` VALUES ('2', 'sys:c:delete', '出库'); INSERT INTO `tb_permissions` VALUES ('3', 'sys:c:update', '修改'); INSERT INTO `tb_permissions` VALUES ('4', 'sys:c:find', '查询'); INSERT INTO `tb_permissions` VALUES ('5', 'sys:x:save', '新增订单'); INSERT INTO `tb_permissions` VALUES ('6', 'sys:x:delete', '删除订单'); INSERT INTO `tb_permissions` VALUES ('7', 'sys:x:update', '修改订单'); INSERT INTO `tb_permissions` VALUES ('8', 'sys:x:find', '查询订单'); INSERT INTO `tb_permissions` VALUES ('9', 'sys:k:save', '新增客户'); INSERT INTO `tb_permissions` VALUES ('10', 'sys:k:delete', '删除客户'); INSERT INTO `tb_permissions` VALUES ('11', 'sys:k:update', '修改客户'); INSERT INTO `tb_permissions` VALUES ('12', 'sys:k:find', '查询客户'); -- ---------------------------- -- Table structure for `tb_roles` -- ---------------------------- DROP TABLE IF EXISTS `tb_roles`; CREATE TABLE `tb_roles` ( `role_id` int NOT NULL AUTO_INCREMENT, `role_name` varchar(60) NOT NULL, PRIMARY KEY (`role_id`) ) ENGINE=InnoDB AUTO_INCREMENT=6 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci; -- ---------------------------- -- Records of tb_roles -- ---------------------------- INSERT INTO `tb_roles` VALUES ('1', 'admin'); INSERT INTO `tb_roles` VALUES ('2', 'cmanager'); INSERT INTO `tb_roles` VALUES ('3', 'xmanager'); INSERT INTO `tb_roles` VALUES ('4', 'kmanager'); INSERT INTO `tb_roles` VALUES ('5', 'zmanager'); -- ---------------------------- -- Table structure for `tb_roles_permission` -- ---------------------------- DROP TABLE IF EXISTS `tb_roles_permission`; CREATE TABLE `tb_roles_permission` ( `rid` int NOT NULL, `pid` int NOT NULL, KEY `FK_pid` (`pid`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci; -- ---------------------------- -- Records of tb_roles_permission -- ---------------------------- INSERT INTO `tb_roles_permission` VALUES ('2', '1'); INSERT INTO `tb_roles_permission` VALUES ('2', '2'); INSERT INTO `tb_roles_permission` VALUES ('2', '3'); INSERT INTO `tb_roles_permission` VALUES ('2', '4'); INSERT INTO `tb_roles_permission` VALUES ('3', '5'); INSERT INTO `tb_roles_permission` VALUES ('3', '6'); INSERT INTO `tb_roles_permission` VALUES ('3', '7'); INSERT INTO `tb_roles_permission` VALUES ('3', '8'); INSERT INTO `tb_roles_permission` VALUES ('3', '9'); INSERT INTO `tb_roles_permission` VALUES ('3', '10'); INSERT INTO `tb_roles_permission` VALUES ('3', '11'); INSERT INTO `tb_roles_permission` VALUES ('3', '12'); INSERT INTO `tb_roles_permission` VALUES ('3', '4'); INSERT INTO `tb_roles_permission` VALUES ('4', '11'); INSERT INTO `tb_roles_permission` VALUES ('4', '12'); INSERT INTO `tb_roles_permission` VALUES ('5', '4'); INSERT INTO `tb_roles_permission` VALUES ('5', '8'); INSERT INTO `tb_roles_permission` VALUES ('5', '12'); -- ---------------------------- -- Table structure for `tb_users` -- ---------------------------- DROP TABLE IF EXISTS `tb_users`; CREATE TABLE `tb_users` ( `user_id` int NOT NULL AUTO_INCREMENT, `username` varchar(20) NOT NULL, `password` varchar(20) NOT NULL, `password_salt` varchar(60) DEFAULT NULL, PRIMARY KEY (`user_id`) ) ENGINE=InnoDB AUTO_INCREMENT=6 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci; -- ---------------------------- -- Records of tb_users -- ---------------------------- INSERT INTO `tb_users` VALUES ('1', 'zhangsan', '123456', null); INSERT INTO `tb_users` VALUES ('2', 'lisi', '123456', null); INSERT INTO `tb_users` VALUES ('3', 'wangwu', '123456', null); INSERT INTO `tb_users` VALUES ('4', 'zhaoliu', '123456', null); INSERT INTO `tb_users` VALUES ('5', 'chenqi', '123456', null); -- ---------------------------- -- Table structure for `tb_users_roles` -- ---------------------------- DROP TABLE IF EXISTS `tb_users_roles`; CREATE TABLE `tb_users_roles` ( `uid` int NOT NULL, `rid` int NOT NULL, KEY `FK_role` (`rid`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci; -- ---------------------------- -- Records of tb_users_roles -- ---------------------------- INSERT INTO `tb_users_roles` VALUES ('1', '1'); INSERT INTO `tb_users_roles` VALUES ('2', '2'); INSERT INTO `tb_users_roles` VALUES ('3', '3'); INSERT INTO `tb_users_roles` VALUES ('4', '4'); INSERT INTO `tb_users_roles` VALUES ('5', '5'); INSERT INTO `tb_users_roles` VALUES ('1', '2'); INSERT INTO `tb_users_roles` VALUES ('1', '3'); INSERT INTO `tb_users_roles` VALUES ('1', '4'); INSERT INTO `tb_users_roles` VALUES ('1', '5');
一个人可以关联多个角色,权限取多个角色的并集 4.2 创建DAO层 //UserDao.java //根据用户名查询用户信息 @Mapper public interface UserDao { User getUserByUsername(String username); } //RoleDao.java //根据用户名查询角色 @Mapper public interface RoleDao { Set getRoleNamesByUsername(String username); } //PermissionDao.java //根据用户明查询权限 @Mapper public interface PermissionDao { Set getPermissionByUsername(String username); }编写Mapper映射 UserMapper.xml select * from tb_users where username=#{username}RoleMapper.xml select role_name from tb_users inner join tb_users_roles on user_id=uid inner join tb_roles on rid=role_id where username=#{username}PermissionMapper.xml select permission_code from tb_users inner join tb_users_roles on user_id=uid inner join tb_roles on tb_users_roles.rid=role_id inner join tb_roles_permission on role_id=tb_roles_permission.rid inner join tb_permissions on pid=permission_id where username=#{username} 4.3 application.yml spring: datasource: druid: driver-class-name: com.mysql.cj.jdbc.Driver url: jdbc:mysql://localhost:3306/shiro?useUnicode=true&characterEncoding=utf8 username: root password: 123456 initial-size: 1 min-idle: 1 max-active: 20 mybatis: type-aliases-package: com/zx/shiro2/beans mapper-locations: classpath:mappers/*.xml 4.4 pom.xml 4.0.0 org.springframework.boot spring-boot-starter-parent 2.6.1 com.zx shiro2 0.0.1-SNAPSHOT shiro2 Demo project for Spring Boot 1.8 org.springframework.boot spring-boot-starter-thymeleaf org.springframework.boot spring-boot-starter-web org.projectlombok lombok true org.springframework.boot spring-boot-starter-test test com.alibaba druid-spring-boot-starter 1.1.10 org.mybatis.spring.boot mybatis-spring-boot-starter 1.1.1 mysql mysql-connector-java org.apache.shiro shiro-spring 1.4.1 com.github.theborakompanioni thymeleaf-extras-shiro 2.0.0 junit junit test 4.5 自定义Realm配置类要使用自己设计的权限数据库,这个时候的Realm就要继承AuthorizingRealm类使它成为一个Realm类。 在config配置包里创建MyRealm.java /** * 1.创建一个类继承AuthorizingRealm类(实现了Realm接口类) * 2.重写doGetAuthorizationInfo和doGetAuthenticationInfo方法 * 3.重写getName方法返回当前realm的自定义名称 */ public class MyRealm extends AuthorizingRealm { @Resource private UserDao userDao; @Resource private RoleDao roleDao; @Resource private PermissionDao permissionDao; @Override public String getName() { return "myRealm"; } /** * 获取授权数据(角色权限信息) * @param principalCollection * @return */ @Override protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) { //获取用户的用户名 String username = (String) principalCollection.iterator().next(); //根据用户名查询用户角色 Set roles = roleDao.getRoleNamesByUsername(username); //根据用户名查询用户权限 Set permissions = permissionDao.getPermissionByUsername(username); SimpleAuthorizationInfo info=new SimpleAuthorizationInfo(); info.setRoles(roles); info.setStringPermissions(permissions); return info; } /** * 获取认证的安全数据(从数据库查询到的用户正确数据) * @param authenticationToken * @return * @throws AuthenticationException */ @Override protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException { //参数authenticationToken就是传递的 subject.login(token) UsernamePasswordToken token= (UsernamePasswordToken) authenticationToken; //从token中获取用户名 String username = token.getUsername(); //根据用户名从数据库查询用户安全数据 User user = userDao.getUserByUsername(username); AuthenticationInfo info=new SimpleAuthenticationInfo(username,user.getPassword(),getName()); return info; } } 4.6 shiro配置ShiroConfig.java @Configuration public class ShiroConfig { //Shiro的方言 @Bean public ShiroDialect getShiroDialect(){ return new ShiroDialect(); } //自定义Realm @Bean public MyRealm getMyRealm(){ MyRealm myRealm=new MyRealm(); return myRealm; } //SecurityManager安全管理器 @Bean public DefaultWebSecurityManager getDefaultWebSecurityManager(MyRealm myRealm){ DefaultWebSecurityManager securityManager=new DefaultWebSecurityManager(); //securityManager要完成校验,需要realm securityManager.setRealm(myRealm); return securityManager; } //过滤器 @Bean public ShiroFilterFactoryBean getShiroFilterFactoryBean(DefaultWebSecurityManager defaultWebSecurityManager){ ShiroFilterFactoryBean filter=new ShiroFilterFactoryBean(); filter.setSecurityManager(defaultWebSecurityManager); //设置shiro的拦截规则 //anon 匿名用户可访问 authc 认证用户可访问 //user 使用RemeberMe的用户可访问 perms 对应权限可访问 //role 对应的角色可访问 Map filterMap=new HashMap(); filterMap.put("/","anon"); filterMap.put("/login.html","anon"); filterMap.put("/register.html","anon"); filterMap.put("/user/login","anon"); filterMap.put("/user/register","anon"); filterMap.put("/static/**","anon"); filterMap.put("/**","authc"); filter.setFilterChainDefinitionMap(filterMap); filter.setLoginUrl("/login.html"); //设置未授权页面跳转到登录页面 filter.setUnauthorizedUrl("/login.html"); return filter; } } 4.7 shiro业务层 @Service public class UserServiceImpl { public void checkLogin(String username,String Password){ Subject subject= SecurityUtils.getSubject(); UsernamePasswordToken token=new UsernamePasswordToken(username,Password); subject.login(token); } } 4.8 Controller层 @Controller @RequestMapping("/user") public class UserController { @Autowired UserServiceImpl userService; @RequestMapping("/login") public String login(String username,String password){ try { userService.checkLogin(username,password); return "index"; } catch (Exception e) { System.out.println("密码错误"); return "login"; } } } 4.9 整合layUI导入layui包,官网复制后台框架代码 DOCTYPE html> Shiro管理系统 菜单显示 nav 1 nav 2 nav 3 nav groups menu 11 menu 22 menu 33 Your Profile Settings Sign out 仓库管理 入库 出库 修改 查询 订单管理 新增订单 删除订单 修改订单 查询订单 客户管理 新增客户 删除客户 修改客户 查询客户 内容主体区域。记得修改 layui.css 和 js 的路径 底部固定区域 //JS layui.use(['element', 'layer', 'util'], function(){ var element = layui.element ,layer = layui.layer ,util = layui.util ,$ = layui.$; //头部事件 util.event('lay-header-event', { //左侧菜单事件 menuLeft: function(othis){ layer.msg('展开左侧菜单的操作', {icon: 0}); } ,menuRight: function(){ layer.open({ type: 1 ,content: '处理右侧面板的操作' ,area: ['260px', '100%'] ,offset: 'rt' //右上角 ,anim: 5 ,shadeClose: true }); } }); });实现不同权限的管理员登录,展示的菜单不同 zhangsan 超级管理员 显示全部菜单 layui实现点击左边菜单,内容右边显示 用户密码在存储到数据库之前根据一定的加密规则加密为密文。加密规则可以自定义,在项目开发中通常使用BASE64和MD5编码方式进行加密 BASE64:可以反编码的编码方式。 MD5:不可逆的编码方式(网站上常见的MD5解密,只不过是列出常见密码的密文进行查询,密码一旦复杂就解密不出来了,为了防止暴力穷举破解,可以加盐加密) 在ShiroConfig中配置加密规则 修改上文的ShiroConfig.java,设置加密规则认证时就生效,没有设置加密规则,默认明文校验 . . . @Bean public HashedCredentialsMatcher getHashedCredentialsMatcher(){ HashedCredentialsMatcher matcher=new HashedCredentialsMatcher(); //matcher就是用来指定加密规则 //加密方式 matcher.setHashAlgorithmName("md5"); //hash次数,这里的hash次数要与存储时加密的hash次数保持一致 matcher.setHashIterations(1); return matcher; } //自定义Realm @Bean public MyRealm getMyRealm(HashedCredentialsMatcher matcher){ MyRealm myRealm=new MyRealm(); //设置加密规则 myRealm.setCredentialsMatcher(matcher); return myRealm; } . . .可以正常登录,如果密码加盐了,Realm在返回认证信息时需要返回盐数据,在自定义Realm中修改 ByteSource.Util.bytes(user.getPasswordSalt()),![]() ![]() 一般的授权方式有两种:一、HTML授权,即用户登录只显示自己权限的菜单,没有权限的菜单不显示。二、过滤器授权,对所有用户显示所有菜单功能,当用户点击菜单后再验证是否有此权限,无权限提示权限不足。 7.1 HTML授权 shiro标签 入库 7.2 过滤器授权当无权人员访问时会抛出AuthorizationException异常,可以配置全局异常类。 @ControllerAdvice public class GlobalException { @ExceptionHandler public String doException(Exception e){ if(e instanceof AuthorizationException){ return "error"; } return null; } } 7.4 手动授权在代码中进行权限校验,一般写在业务层 Subject subject=SecurityUtils.getSubject(); if(subject.isPermitted("sys:k:find")){ //业务逻辑 }else{ //无权限处理 } |
CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3 |