org.apache.shiro
shiro-all
1.2.2
org.springframework
spring-jdbc
5.1.7.RELEASE
// 创建会话工厂 加载配置文件
Factory factory = new IniSecurityManagerFactory("classpath:shiro.ini");
// 获取全局的权限管理器
SecurityManager securityManager = factory.getInstance();
// 设置权限管理器
SecurityUtils.setSecurityManager(securityManager);
// 获取当前用户
Subject subject = SecurityUtils.getSubject();
// 创建令牌
UsernamePasswordToken token = new UsernamePasswordToken("admin1","123");
// 当前用户登录令牌
subject.login(token);
1.SecurityManager权限验证工厂
2.SecurityManager 一个全局唯一的安全管理器
3.SecurityUtils可以通过这个工具类获取全局的SecurityManager
但是需要我们首先设置一下
4.Subject我们当前登录的账号(用户),通过isAuthenticated方法知道是否登录了
5.UsernamePasswordToken是登录的凭证,用户输入的账号密码放进去,让subject判断是否登录成功
6.login登录的时候通过异常判断是哪种登录失败
7.如果身份验证失败请捕获 AuthenticationException 或其子类,常见的如:
DisabledAccountException(禁用的帐号)、
LockedAccountException(锁定的帐号)、
UnknownAccountException(错误的帐号)、
ExcessiveAttemptsException(登录失败次数过多)、
IncorrectCredentialsException (错误的凭证)、
ExpiredCredentialsException(过期的凭证)等,
具体请查看其继承关系;对于页面的错误消息展示,最好使用如 “用户名 / 密码错误” 而不是 “用户名错误”/“密码错误”,防止一些恶意用户非法扫描帐号库;
subject.checkRole("管理员"); //判断是否有这个角色 ,没有抛出异常
subject.hasRole("管理员");// true和false
subject.checkPermission("role.*"); // 没有的话抛异常
subject.isPermitted("role.*") // 返回值为true和false
域,Shiro 从从 Realm 获取安全数据(如用户、角色、权限),就是说 SecurityManager 要验证用户身份,
那么它需要从 Realm 获取相应的用户进行比较以确定用户身份是否合法;
也需要从 Realm 得到用户相应的角色 / 权限进行验证用户是否能进行操作;
可以把 Realm 看成 DataSource,即安全数据源。
也就是说对于我们而言,最简单的一个 Shiro 应用:
应用代码通过 Subject 来进行认证和授权,而 Subject 又委托给 SecurityManager;
我们需要给 Shiro 的 SecurityManager 注入 Realm,从而让 SecurityManager 能得到合法的用户及其权限进行判断。
从以上也可以看出,Shiro 不提供维护用户 / 权限,而是通过 Realm 让开发人员自己注入。
Realm个人其实理解为就是来判断当前的subject用户是登录成功、失败的一个东西
package com.zhiyou100.realm;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.SimpleAuthenticationInfo;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
public class MyRealm2 extends AuthorizingRealm {
// 资源和角色的添加
@Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection collection) {
// TODO Auto-generated method stub
// 只有下面的方法执行了才能执行这个方法,认为当前的用户已经登陆了
// getPrimaryPrincipal 获取的是下面验证的用户信息
String account = (String) collection.getPrimaryPrincipal();
// 里面装的是用户里面的role和权限
SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
if ("admin".equals(account)) {
info.addRole("管理员");
info.addStringPermission("*");
}
return info;
}
@Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
// TODO Auto-generated method stub
// 获取账号
String account = (String)token.getPrincipal();
// 获取密码
String password = new String((char[]) token.getCredentials());
// 把账号密码保存在info中,并返回
AuthenticationInfo info = new SimpleAuthenticationInfo(account,password,getName());
return info;
}
}
告诉
myRealm=com.zhiyou100.realm.MyRealm
securityManager.realms=$myRealm
1)在这个图片中我们可以看见‘I’代表的是接口,‘c’代表的抽象类和普通类
2)Realm是最上层的接口,所有的东西都需要我们自己实现
3)IniRealm是我们之前没有自定义realm使用的
4)JdbcRealm是链接数据库使用的,但是因为属于shiro自己写的,所以他对数据库表的格式要求有规范的
5)所以我们更多的使用的是AuthorizingRealm