什么是Shiro
Shiro
是一个功能强大且易于使用的Java安全框架,它执行身份验证、授权、加密和会话管理。使用Shiro易于理解的API,您可以快速轻松地保护任何应用程序—从最小的移动应用程序到最大的web和企业应用程序
Shiro核心架构
核心
AuthorizingRealm:授权领域需要继承来实现他的子方法 AuthorizingRealm:权限验证 AuthenticationInfo:登录认证什么是认证
身份认证,就是判断一个用户是否为合法用户的处理过程。最常用的简单身份认证方式是系统通过核对用户输入的用户名和口令,看其是否与系统中存储的该用户的用户名和口令一致,来判断用户身份是否正确
三个概念 Subject 访问系统的用户,主体可以是用户、程序等,进行认证的都称为主体 Principal 身份信息,是主体(subject)进行身份认证的标识,标识必须具有唯一性,如用户名、手机号、邮箱地址等,一个主体可以有多个身份,但是必须有一个主身份(Primary Principal) credential 凭证信息,是只有主体自己知道的安全信息,如密码、证书等
认证的实现
1.创建一个普通的maven项目导入依赖到pom.xml
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-core</artifactId>
<version>1.5.3</version>
</dependency>
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-spring</artifactId>
<version>1.5.3</version>
</dependency>
2.引入shiro配置文件,shiro.ini
;规定写法key value
[users]
;用户名=密码
zs=123
ls=123
3.实现java代码
package cn.hp.shrio01Test;
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;
import org.apache.shiro.util.ByteSource;
import java.security.Principal;
import java.util.ArrayList;
import java.util.List;
/**
* @description:
* @author: 为自己带盐
* @date: 2022/7/19 14:51
**/
public class MyRealm extends AuthorizingRealm {
/**
* 权限验证
*
* @param principalCollection
* @return
*/
@Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
System.out.println(" 权限验证");
//获取到主要信息
String primaryPrincipal = (String) principalCollection.getPrimaryPrincipal();
//创建权限,如果角色带有super,则查看所有的展示信息,否则只展示特定的列
String role = "super";
String roles = "super";
//创建简单的授权信息
SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
//通过array list去添加
List rolesList = new ArrayList();
rolesList.add(role);
rolesList.add(roles);
//把刚才的list添加到角色中
info.addRoles(rolesList);
//创建收集对象
Principal principal = (Principal) principalCollection;
//将角色赋给认证对象
//通过账号去查询该用户的权限字符串
String parme = "user:show:*";
info.addStringPermission(parme);
return info;
}
}
登录认证实现
/**
* 登录认证
*
* @param authenticationToken
* @return
* @throws AuthenticationException
*/
@Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
//打印,看是否能进到此方法中
System.out.println("authenticationToken = " + authenticationToken);
//获取登录账号
String principal = (String) authenticationToken.getPrincipal();
//通过用户去数据库查询,得到用户的详解信息
System.out.println("principal 主身份信息= = " + principal);
//对密码进行加盐加密
String salt = "121123123";
//定义一个账号,密码
String username = "zs", password = "ad58d13c27dd9a7bbeb41683f57a8bf7";
//对账号进行判断 如果zs是有权限的则创建一个简单返回创建信息
if (username.equals(principal)) {
//第一个参数,数据库中查询的账号 密码 当前名字
return new SimpleAuthenticationInfo(username, password, ByteSource.Util.bytes(salt), getName());
}
return null;
}
测试类
package cn.hp.shrio01Test;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.IncorrectCredentialsException;
import org.apache.shiro.authc.UnknownAccountException;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.concurrent.SubjectAwareExecutor;
import org.apache.shiro.realm.text.IniRealm;
import org.apache.shiro.subject.Subject;
import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
import org.junit.Test;
public class shrio01 {
@Test
public void t1() {
//1.创建安全管理器
DefaultWebSecurityManager manager = new DefaultWebSecurityManager();
//2.创建一个realm对象
IniRealm realm = new IniRealm("classpath:shrio.ini");
//3.将realm交给安全管理器
manager.setRealm(realm);
//4.安全管理工具类,将安全管理员交给安全管理器
SecurityUtils.setSecurityManager(manager);
//5.获取主体subject 代表了用户
Subject subject = SecurityUtils.getSubject();
//6.获取一个token令牌
UsernamePasswordToken token = new UsernamePasswordToken("zs", "123");
//此方法负责安全验证
try {
subject.login(token);
//如果不通过会抛出异常
System.out.println(" 登录成功 ");
} catch (UnknownAccountException e) {
System.out.println("账号错误");
} catch (IncorrectCredentialsException e) {
System.out.println("密码错误");
}
}
}
认证经常出现的状态
UnknownAccountException:用户名错误
IncorrectCredentialsException:密码错误