shiro简介
shiro官网
Apache Shiro是一个强大且易用的Java安全框架,执行身份验证、授权、密码和会话管理。使用Shiro的易于理解的API,您可以快速、轻松地获得任何应用程序,从最小的移动应用程序到最大的网络和企业应用程序。
框架图说明
官网架构说明
从外部查看shiro框架
应用代码直接交互的对象是Subject,也就是说Shiro的对外API核心就是Subject
内部结构框架
常见单词说明
Shiro中的shiro.ini说明
shiro.ini放置在classpath路径下shiro会自动查找。
ini配置文件中有四大主要配置类
main users roles urls
main
提供了对根对象securityManager及其依赖对象的配置
#创建对象
securityManager=org.apache.shiro.mgt.DefaultSecurityManager
其构造器必须是public空参构造器,通过反射创建相应的实例。
- 对象名=全限定类名 相对于调用public无参构造器创建对象
- 对象名.属性名=值 相当于调用setter方法设置常量值
- 对象名.属性名=$对象引用 相当于调用setter方法设置对象引用
users
提供了对用户/密码及其角色的配置,用户名=密码,角色1,角色2
username=password,role1,role2
例如:配置用户名/密码及其角色,格式:“用户名=密码,角色1,角色2”,角色部分可省略。如:
[users]
zhang=123,role1,role2
wang=123
roles
提供了角色及权限之间关系的配置,角色=权限1,权限2 role1 = permission1 , permission2
例如:配置角色及权限之间的关系,格式:“角色=权限1,权限2”;如:
[roles]
role1=user:create,user:update
role2=*
如果只有角色没有对应的权限,可以不配roles
urls
用于web,提供了对web url拦截相关的配置,url=拦截器[参数],拦截器
/index.html = anon
/admin/** = authc, roles[admin],perms["permission1"]
第一个案例
官方教程
添加对应的依赖
<dependency>
\t<groupid>org.apache.shiro/<groupid>
\t<artifactid>shiro-core/<artifactid>
\t<version>1.1.0/<version>
/<dependency>
<dependency>
\t<groupid>org.slf4j/<groupid>
\t<artifactid>slf4j-simple/<artifactid>
\t<version>1.6.1/<version>
\t<scope>test/<scope>
/<dependency>
<dependency>
\t<groupid>junit/<groupid>
\t<artifactid>junit/<artifactid>
\t<version>4.12/<version>
\t<scope>test/<scope>
/<dependency>
<dependency>
\t<groupid>commons-logging/<groupid>
\t<artifactid>commons-logging/<artifactid>
\t<version>1.2/<version>
/<dependency>
添加shiro.ini文件
src/main/resource下添加
添加内容如下
[users]
root = 123456
# 账号为root 密码是 123456
认证操作
@Test
public void test() {
\t// 1.获取SecurityManager工厂对象
\tFactory<securitymanager> factory =
\t\t\tnew IniSecurityManagerFactory("classpath:shiro.ini");
\t// 2.通过Factory对象获取SecurityManager对象
\tSecurityManager securityManager = factory.getInstance();
\t// 3.将SecurityManager对象添加到当前运行环境中
\tSecurityUtils.setSecurityManager(securityManager);
\t
\t// 4.获取Subject对象
\tSubject subject = SecurityUtils.getSubject();
\tAuthenticationToken token = new UsernamePasswordToken("root", "123456");
\t// 登录操作
\tsubject.login(token);
\t// 获取登录的状态
\tSystem.out.println(subject.isAuthenticated());
}/<securitymanager>
测试
账号密码正确
账号错误
账号错误抛 UnknownAccountException异常
密码错误
密码错误会抛 IncorrectCredentialsException异常
所以代码可以调整下:
\t@Test
\tpublic void test() {
\t\t// 1.获取SecurityManager工厂对象
\t\tFactory<securitymanager> factory =
\t\t\t\tnew IniSecurityManagerFactory("classpath:shiro.ini");
\t\t// 2.通过Factory对象获取SecurityManager对象
\t\tSecurityManager securityManager = factory.getInstance();
\t\t// 3.将SecurityManager对象添加到当前运行环境中
\t\tSecurityUtils.setSecurityManager(securityManager);
\t\t
\t\t// 4.获取Subject对象
\t\tSubject subject = SecurityUtils.getSubject();
\t\tAuthenticationToken token = new UsernamePasswordToken("root", "111");
\t\t// 登录操作
\t\ttry {
\t\t\tsubject.login(token);
\t\t} catch (UnknownAccountException e) {
\t\t\tSystem.out.println("账号出错...");
\t\t} catch(IncorrectCredentialsException e){
\t\t\tSystem.out.println("密码出错...");
\t\t}
\t\t// 获取登录的状态
\t\tSystem.out.println(subject.isAuthenticated());
\t}/<securitymanager>
认证流程总结
login方法
DelegatingSubject中的login方法
在此方法中我们看到是 SecurityManager来管理认证操作的
继续进入
进入DefaultSecurityManager的login方法
此方法中调用Authenticator认证
AbstractAuthenticator认证
ModularRealmAuthenticator
在该方法中获取ini文件中的信息,加载解析不是在次方法中。
AuthenticatingRealm
流程描述
- 创建token令牌,token中有用户提交的认证信息即账号和密码
- 执行subject.login(token),最终由securityManager通过Authenticator进行认证
- Authenticator的实现ModularRealmAuthenticator调用realm从ini配置文件取用户真实的账号和密码,这里使用的是IniRealm(shiro自带)
- IniRealm先根据token中的账号去ini中找该账号,如果找不到则给ModularRealmAuthenticator返回null,如果找到则匹配密码,匹配密码成功则认证通过。
閱讀更多 職涯寶 的文章