11、Shiro入门学习
创始人
2025-05-28 03:41:05
0

1、权限管理概述

【简介】: 权限管理一般指的是系统设置的安全规则或安全策略,用户可以访问而且只能访问自己被授权的资源。在权限管理中使用最多的还是基于角色访问控制。

【基于角色访问控制图】:
在这里插入图片描述

2、Shiro概述

1、Shiro的功能

  • 认证
  • 授权
  • 加密
  • 会话管理
  • 与web集成
  • 缓存

2、Shiro架构图

在这里插入图片描述

  • Subject:访问系统的用户,主体可以是用户、程序等,进行认证的都被称为主体,Subject其实指的就是当前的操作用户。
  • SecurityManager:安全管理器,它是 shiro 功能实现的核心,负责与(认证器/授权器/缓存控制器)进行交互,实现 subject 委托的各种功能。
  • Realms:数据源,Realm 充当了 Shiro 与应用安全数据间的“桥梁”或者“连接器”。;可以把Realm 看成 DataSource,即安全数据源。执行认证(登录)和授权(访问控制)时,Shiro 会从应用配置的 Realm 中查找相关的比对数据。以确认用户是否合法,操作是否合理。
  • Authenticator(认证器): 用于认证,从 Realm 数据源取得数据之后进行执行认证流程处理。
  • Authorizer(授权器):用户访问控制授权,决定用户是否拥有执行指定操作的权限。
  • SessionManager (会话管理器):Shiro 与生俱来就支持会话管理,这在安全类框架中都是独一无二的功能。即便不存在 web 容器环境,shiro 都可以使用自己的会话管理机制,提供相同的会话 API。
  • CacheManager (缓存管理器):用于缓存认证授权信息等。
  • Cryptography(加密组件): Shiro 提供了一个用于加密解密的工具包。

3、Shiro认证流程

在这里插入代码片在这里插入图片描述

1、基于ini的认证

1、创建ini配置文件 shiro-authc.ini

#用户的身份、凭据
[users]
admin=admin
apple=ad123

2、 编写测试类完成认证

 @Testpublic void testLoginByIni() {// 1、创建安全管理器DefaultSecurityManager securityManager = new DefaultSecurityManager();// 2、创建IniRealm对象IniRealm iniRealm = new IniRealm("classpath:shiro/shiro-authc.ini");// 3、将realm设置到安全管理器中securityManager.setRealm(iniRealm);// 4、将安全管理器设置到上下文环境中SecurityUtils.setSecurityManager(securityManager);// 5、获取主体对象Subject subject = SecurityUtils.getSubject();// 6、创建令牌UsernamePasswordToken token = new UsernamePasswordToken("admin", "admin");// 7、进行登录认证subject.login(token);// 8、判断是否登录System.out.println("当前用户是否登录= " + subject.isAuthenticated());}

【错误解析】:

  • 账号错误 org.apache.shiro.authc.UnknownAccountException
  • 密码错误 org.apache.shiro.authc.IncorrectCredentialsException

3、认证流程分析

在这里插入图片描述

2、基于自定义realm的认证

1、创建数据库模拟数据

  • User类
@Data
@AllArgsConstructor
public class User {private String username;private String password;
}
  • UserMapper类
public class UserMapper {private static Map users = new HashMap<>();static {User user0 = new User("admin", "admin");User user1 = new User("admin123", "admin123");users.put(user0.getUsername(), user0);users.put(user1.getUsername(), user1);}/*** 根据用户名返回user对象** @param username 用户名* @return user*/public static User getUserByUserName(String username) {return users.get(username);}
}

2、自定义realm

  • UserRealm类
public class UserRealm extends AuthorizingRealm {// 授权@Overrideprotected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {return null;}// 认证@Overrideprotected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {/*** 获取用户传递的数据*/UsernamePasswordToken usernamePasswordToken = (UsernamePasswordToken) token;// 获取用户传递的用户名String username = usernamePasswordToken.getUsername();// 根据用户名获取对象User user = UserMapper.getUserByUserName(username);// 判断是否为空if (user == null) {return null;}// 不为空交给认证管理器进行认证/*** 参数1:存放user对象* 参数2:用户密码* 参数3:realm名称*/return new SimpleAuthenticationInfo(user, user.getPassword(), getName());}
}

3、编写测试类进行测试

    @Testpublic void testShiroRoleByRealm() {DefaultSecurityManager securityManager=new DefaultSecurityManager();UserRealm userRealm=new UserRealm();securityManager.setRealm(userRealm);SecurityUtils.setSecurityManager(securityManager);Subject subject = SecurityUtils.getSubject();UsernamePasswordToken token = new UsernamePasswordToken("admin", "admin");subject.login(token);System.out.println("当前用户是否登录= " + subject.isAuthenticated());}

4、认证流程分析

在这里插入图片描述

3、Web环境如何使用Shiro认证

在这里插入图片描述

4、Shiro鉴权流程

在这里插入图片描述

1、基于ini的鉴权

1、编写 ini 配置文件:shiro-author.ini

#用户的身份、凭据、角色
[users]
admin=admin,hr,seller
apple=ad123,seller
#角色与权限信息
[roles]
hr=user:list,user:delete
seller=customer:list,customer:save

2、编写测试类完成鉴权操作

 @Testpublic void testAuthorByIni() {DefaultSecurityManager securityManager = new DefaultSecurityManager();IniRealm iniRealm = new IniRealm("classpath:shiro/shiro-author.ini");securityManager.setRealm(iniRealm);SecurityUtils.setSecurityManager(securityManager);Subject subject = SecurityUtils.getSubject();UsernamePasswordToken usernamePasswordToken = new UsernamePasswordToken("admin", "admin");subject.login(usernamePasswordToken);// 登录成功之后开始判断是否拥有某个权限System.out.println("当前用户是否拥有用户列表权限 = " + subject.isPermitted("user:list"));System.out.println("当前用户是否拥有这两个权限中的一个 = " + Arrays.toString(subject.isPermitted("user:list", "user:delete")));}

2、基于自定义realm的鉴权

1、创建数据库模拟数据

  • User类
@Data
@AllArgsConstructor
public class User {private String username;private String password;
}
  • UserMapper类
public class UserMapper {private static Map users = new HashMap<>();//角色集合private static Map> roleData = new HashMap>();//权限集合private static Map> permissionData = new HashMap>();static {User user0 = new User("admin", "admin");User user1 = new User("admin123", "admin123");users.put(user0.getUsername(), user0);roleData.put(user0.getUsername(), Arrays.asList("seller"));permissionData.put(user0.getUsername(),Arrays.asList("customer:list", "customer:save"));users.put(user1.getUsername(), user1);roleData.put(user1.getUsername(), Arrays.asList("seller", "hr"));permissionData.put(user1.getUsername(),Arrays.asList("customer:list", "customer:save", "user:list", "user:delete"));}/*** 根据用户名返回user对象** @param username 用户名* @return user*/public static User getUserByUserName(String username) {return users.get(username);}public static List getRoleByName(String username){return roleData.get(username);}public static List getPermissionByName(String username){return permissionData.get(username);}
}

2、自定义realm

public class UserRealm extends AuthorizingRealm {// 授权@Overrideprotected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {// 获取当前上下文环境中的用户信息User user = (User) principals.getPrimaryPrincipal();String username = user.getUsername();// 获取权限列表List permissionList = UserMapper.getPermissionByName(username);// 获取角色列表List roleList = UserMapper.getRoleByName(username);// 封装info对象信息SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();info.addStringPermissions(permissionList);info.addRoles(roleList);return info;}// 认证@Overrideprotected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {/*** 获取用户传递的数据*/UsernamePasswordToken usernamePasswordToken = (UsernamePasswordToken) token;// 获取用户传递的用户名String username = usernamePasswordToken.getUsername();// 根据用户名获取对象User user = UserMapper.getUserByUserName(username);// 判断是否为空if (user == null) {return null;}// 不为空交给认证管理器进行认证/*** 参数1:存放user对象* 参数2:用户密码* 参数3:realm名称*/return new SimpleAuthenticationInfo(user, user.getPassword(), getName());}
}

3、编写测试类进行测试

 @Testpublic void testAuthorByRealm(){DefaultSecurityManager securityManager = new DefaultSecurityManager();UserRealm userRealm=new UserRealm();securityManager.setRealm(userRealm);SecurityUtils.setSecurityManager(securityManager);Subject subject = SecurityUtils.getSubject();UsernamePasswordToken usernamePasswordToken = new UsernamePasswordToken("admin", "admin");subject.login(usernamePasswordToken);// 登录成功之后开始判断是否拥有某个权限System.out.println("当前用户是否拥有用户列表权限 = " + subject.isPermitted("user:list"));System.out.println("当前用户是否拥有这两个权限中的一个 = " + Arrays.toString(subject.isPermitted("user:list", "user:delete")));}

5、Shiro加密

1、Shiro加密工具

  • 在 Shiro 中实现了 MD5 的算法,所以可以直接使用它来对密码进行加密。
    @Testpublic void testMD5() {Md5Hash md5Hash = new Md5Hash("123456");System.out.println(md5Hash.toString());}

2、Realm加盐加密

    @Testpublic void testMD5() {Md5Hash md5Hash = new Md5Hash("123456","abcd412e");System.out.println(md5Hash.toString());}

相关内容

热门资讯

AWSECS:访问外部网络时出... 如果您在AWS ECS中部署了应用程序,并且该应用程序需要访问外部网络,但是无法正常访问,可能是因为...
AWSElasticBeans... 在Dockerfile中手动配置nginx反向代理。例如,在Dockerfile中添加以下代码:FR...
银河麒麟V10SP1高级服务器... 银河麒麟高级服务器操作系统简介: 银河麒麟高级服务器操作系统V10是针对企业级关键业务...
北信源内网安全管理卸载 北信源内网安全管理是一款网络安全管理软件,主要用于保护内网安全。在日常使用过程中,卸载该软件是一种常...
AWR报告解读 WORKLOAD REPOSITORY PDB report (PDB snapshots) AW...
AWS管理控制台菜单和权限 要在AWS管理控制台中创建菜单和权限,您可以使用AWS Identity and Access Ma...
​ToDesk 远程工具安装及... 目录 前言 ToDesk 优势 ToDesk 下载安装 ToDesk 功能展示 文件传输 设备链接 ...
群晖外网访问终极解决方法:IP... 写在前面的话 受够了群晖的quickconnet的小水管了,急需一个新的解决方法&#x...
不能访问光猫的的管理页面 光猫是现代家庭宽带网络的重要组成部分,它可以提供高速稳定的网络连接。但是,有时候我们会遇到不能访问光...
Azure构建流程(Power... 这可能是由于配置错误导致的问题。请检查构建流程任务中的“发布构建制品”步骤,确保正确配置了“Arti...