shiro笔记
2022/4/8 23:23:28
本文主要是介绍shiro笔记,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!
shiro笔记
shiro简述
- Apache Shiro 是java的一个安全框架
- Shiro 可以做:认证、授权、加密、会话管理、Web集成、缓存等功能。
- 官网:http://shiro.apache.org/
功能介绍
- Authentication:身份认证/登录,验证用户是不是拥有相应的身份
- Authorization:授权,即权限验证,验证某个已认证的用户是否拥有某个权限;
- Session Manager:会话管理,即用户登录后就是一次会话,在没有退出之前,它的所有信息都在会话中;会话可以是普通 JavaSE 环境,也可以是 Web 环境的;
- Cryptography:加密,保护数据的安全性,如密码加密存储到数据库,而不是明文存储;
- Web Support:Web 支持,可以非常容易的集成到Web 环境;
- Caching:缓存,比如用户登录后,其用户信息、拥有的角色/权限不必每次去查,这样可以提高效率;
- Concurrency:Shiro 支持多线程应用的并发验证,即如在一个线程中开启另一个线程,能把权限自动传播过去;
- Testing: 提供 测试 支持
- Run As: 允许一个用户假装为另一个用户(如果他们允许)的身份进行访问;
- Remember Me:记住我,这个是非常常见的功能,即一次登录后,下次再来的话不用登录了
Shiro与Spring Security对比
共同点: 认证、授权、加密、会话、缓存、remember Me功能...
不同点: Shiro配置和使用比较简单,Spring Sccurity上手复杂.Shiro依赖性低,不需要任何框架和容器,可以独立运行,而Spring Security依赖于Spring容器.
Shiro四大核心功能
Authentication
- 身份认证:
一般用于登录:登陆时,验证用户是否拥有相应身份。
Authorization
- 访问控制:
验证已认证用户是否拥有某些权限,可以让他进行权限内的操作。
Cryptography
- 密码加密:
将密码加密储存到数据库,而不是明文储存,可以保护数据的安全性。
Session Management
- 会话管理:
用户登录后就是第一次会话,在会话结束(退出登录)前,他所有的信息都在会话中。
Shiro三个核心组件
Subject-主体:
应用代码直接交互的对象是Subject,也就是说Shiro的对外API核心是Subject。
Subject的所有交互都会委托给SecurityManager(实际的执行者)。
SecurityManager-安全管理器:
SecurityManager是Shiro的核心,负责与Shiro的其他组件进行交互,相当于SpringMVC中DispatcherServlet的角色。
它管理着所有 Subject、且负责进行认证和授权、及会话、缓存的管理,所有具体的交互都通过SecurityManager 进行控制。
SecurityManager是一个单例对象,一个应用中只需要一个SecurityManager.
Realm-域
Shiro从Realm获取安全数据(如用户、角色、权限),
就是说SecurityManager要验证用户身份,那么它需要从Realm获取相应的用户进行比较以确定用户身份是否合法;
也需要从Realm得到用户相应的角色/权限进行验证用户是否能进行操作;
可以把Realm看成DataSource,即安全数据源。
shiro中的认证
身份认证,就是判断一个用户是否为合法用户的处理过程。最常见的简单身份验证方式是通过核对用户输入的用户名和口令,看其是否与系统中存储的该用户的用户名和口令一致,来判断用户身份是否正确。
shiro中认证的关键对象
- Subject:主体
访问系统的用户,主体可以是用户、程序等。 - Principal:身份信息
是主体进行身份认证的标识,标识必须具有唯一性,如用户名、手机号、邮箱地址等。一个主体可以有多个身份,但是必须有一个主身份(Primary Principal)。 - credential:凭证信息
是只有主体自己知道的安全信息,如密码、证书等。
认证流程
认证的开发
- 创建Spring Boot项目
<dependency> <groupId>org.apache.shiro</groupId> <artifactId>shiro-core</artifactId> <version>1.5.3</version> </dependency>
- 引入shiro配置文件
配置文件:名称随意,以 .ini结尾,放在resources目录下。
注意:在实际的项目开发中并不会使用这种方式,这种方法可以用来初学时练手!
[users] king=123456 wang=123456
- 开发认证代码
public class ShiroDemo{ public static void main(String[] args){ //1.创建安全管理器对象 DefaultSecurityManager securityManager = new DefaultSecurityManager(); //2.给安全管理器设置realm securityManager.setRealm(new InitRealm("classpath:shiro.ini")); //3.SecurityUtils全局安全工具类设置安全管理器 SecurityUtils.setSecurityManager(securityManager); //4.关键对象subject主体 Subject subject = SecurityUtils.getSubject(); //5.创建令牌 UsernamePasswordToken token = new UsernamePasswordToken("king","123456"); try{ System.out.println("认证状态"+subject.isAuthenticated());//fasle //用户认证 subject.login(token); System.out.println("认证状态"+subject.isAuthenticated()); }catch(UnknownAccountException e){ e.printStackTrace(); System.out.println("认证失败,用户名不存在"); }catch(IncorrectCredentialsException e){ e.printStackTrace(); System.out.println("认证失败,密码错误"); } } }
- 常见的异常类型
- DisabledAccountException(帐号被禁用)
- LockedAccountException(帐号被锁定)
- ExcessiveAttemptsException(登录失败次数过多)
- ExpiredCredentialsException(凭证过期)等
自定义Realm
通过分析源码可得,
- 最终执行用户名比较的的是 在SimpleAccountRealm类 的doGetAuthenticationInfo 方法完成用户名校验。
- 最终密码校验是在 AuthenticatingRealm类 的 assertCredentialsMatch方法 中。
shiro提供的Realm
根据认证源码认证使用的是SimpleAccountRealm
public class SimpleAccountRealm extends AuthorizingRealm{ //......省略 protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException { UsernamePasswordToken upToken = (UsernamePasswordToken) token; SimpleAccount account = getUser(upToken.getUsername()); if (account != null) { if (account.isLocked()) { throw new LockedAccountException("Account [" + account + "] is locked."); } if (account.isCredentialsExpired()) { String msg = "The credentials for account [" + account + "] are expired"; throw new ExpiredCredentialsException(msg); } } return account; } protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) { String username = getUsername(principals); USERS_LOCK.readLock().lock(); try { return this.users.get(username); } finally { USERS_LOCK.readLock().unlock(); } } }
接下里,开始自定义realm!
/** * 自定义Realm */ public class CustomerRealm extends AuthorizingRealm{ //授权 @Override protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) { System.out.println("=================="); return null; } //认证 @Override protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException { //在token中获取 用户名 String principal = (String) token.getPrincipal(); System.out.println(principal); //实际开发中应当 根据身份信息使用jdbc mybatis查询相关数据库 //在这里只做简单的演示 //假设username,password是从数据库获得的信息 String username="zhangsan"; String password="123456"; if(username.equals(principal)){ //参数1:返回数据库中正确的用户名 //参数2:返回数据库中正确密码 //参数3:提供当前realm的名字 this.getName(); SimpleAuthenticationInfo simpleAuthenticationInfo = new SimpleAuthenticationInfo(principal,password,this.getName()); return simpleAuthenticationInfo; } return null; } }
这篇关于shiro笔记的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!
- 2024-11-01后台管理开发学习:新手入门指南
- 2024-11-01后台管理系统开发学习:新手入门教程
- 2024-11-01后台开发学习:从入门到实践的简单教程
- 2024-11-01后台综合解决方案学习:从入门到初级实战教程
- 2024-11-01接口模块封装学习入门教程
- 2024-11-01请求动作封装学习:新手入门教程
- 2024-11-01登录鉴权入门:新手必读指南
- 2024-11-01动态面包屑入门:轻松掌握导航设计技巧
- 2024-11-01动态权限入门:新手必读指南
- 2024-11-01动态主题处理入门:新手必读指南