1.shiro简介
1.1什么是shieo
Apache Shiro 是一个强大易用的 Java 安全框架,提供了认证、授权、加密和session会话管理等功能,对于任何一个应用程序,Shiro 都可以提供全面的安全管理服务。并且相对于其他安全框架spring security,Shiro 要简单的多。
1.2什么是权限管理
基本上涉及到用户参与的系统都要进行权限管理,权限管理属于系统安全的范畴,权限管理实现对用户访问系统的控制,按照安全规则或者安全策略控制用户可以访问而且只能访问自己被授权的资源。
权限管理包括用户身份认证和授权两部分,简称认证授权。对于需要访问控制的资源用户首先经过身份认证,认证通过后用户具有该资源的访问权限方可访问。
1.3 什么是身份认证
身份认证,就是判断一个用户是否为合法用户的处理过程。最常用的简单身份认证方式是系统通过核对用户输入的用户名和口令,看其是否与系统中存储的该用户的用户名和口令一致,来判断用户身份是否正确。对于采用指纹等系统,则出示指纹;对于硬件Key等刷卡系统,则需要刷卡。
1.4认证授权框架有哪些
shiro框架和spring security框架 这款框架是现在市面比较流行。
2.代码演示
2.1依赖
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-core</artifactId>
<version>1.3.2</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId>
<version>1.1.3</version>
</dependency>
2.2Realm域
/**
* Realm域:Shiro从Realm获取安全数据(如用户、角色、权限),
* 就是说SecurityManager要验证用户身份,那么它需要从Realm
* 获取相应的用户进行比较以确定用户身份是否合法;也需要从Realm
* 得到用户相应的角色/权限进行验证用户是否能进行操作;可以把
* Realm看成DataSource,即安全数据源
*
* 自定义realms对象
* 继承AuthorizingRealm
* 重写方法
* doGetAuthorizationInfo:授权
* 获取到用户的授权数据(用户的权限数据)
* doGetAuthenticationInfo:认证
* 根据用户名密码登录,将用户数据保存(安全数据)
*
*/
public class MyRealm extends AuthorizingRealm {
//授权:授权的主要目的就是根据认证数据获取到用户的权限信息
/**
* principalCollection:包含了所有已认证的安全数据
* AuthorizationInfoInfo:授权数据
*/
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
System.out.println("执行授权方法");
//1.获取安全数据 username,用户id
String username = (String)principalCollection.getPrimaryPrincipal();
//2.通过认证传递的安全数据,去数据库查询角色以及权限,实现授权
List<String> perms = new ArrayList<>();
perms.add("user:save");
perms.add("user:update");
perms.add("user:delete");
perms.add("user:find");
List<String> roles = new ArrayList<>();
roles.add("role1");
roles.add("role2");
//4.构造返回
SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
//设置权限集合
info.addStringPermissions(perms);
info.addRoles(roles);
return info; //设置角色集合
}
//认证:认证的主要目的,比较用户名和密码是否与数据库中的一致
//将安全数据存入到shiro进行保管
//参数:authenticationToken登录构造的usernamepasswordtoken
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
System.out.println("执行认证方法");
//1.构造uptoken
UsernamePasswordToken upToken = (UsernamePasswordToken) authenticationToken;
//2.获取输入的用户名密码
String username = upToken.getUsername();
String password = new String(upToken.getPassword());
//3.根据用户名查询数据库,正式系统查询
//4.比较密码和数据库中的密码是否一致
if("654321".equals(password) && username.equals("liuls")) {
//5.如果成功,向shiro存入安全数据
SimpleAuthenticationInfo info = new SimpleAuthenticationInfo(username,password,"myRealm");//1.安全数据,2.密码。3。当前realm域名称
return info;
}else{
//6.失败,抛出异常或返回null
throw new RuntimeException("用户名或密码错误");
}
}
}
2.3测试类
/**
* 测试用户认证:
* 认证:用户登录
*
* 1.根据配置文件创建SecurityManagerFactory
* 2.通过工厂获取SecurityManager
* 3.将SecurityManager绑定到当前运行环境
* 4.从当前运行环境中构造subject
* 5.构造shiro登录的数据
* 6.主体登陆
*/
@Test
public void testLogin() {
//1.根据配置文件创建SecurityManagerFactory
Factory<SecurityManager> factory = new
IniSecurityManagerFactory("classpath:shiro-test-3.ini");
//2.通过工厂获取SecurityManager
SecurityManager securityManager = factory.getInstance();
//3.将SecurityManager绑定到当前运行环境
SecurityUtils.setSecurityManager(securityManager);
Subject subject = SecurityUtils.getSubject();
String username = "liuls";
String password = "654321";
UsernamePasswordToken token = new UsernamePasswordToken(username,password);
//执行login-->realm域中的认证方法
subject.login(token);
System.out.println(subject.isAuthenticated());
//鉴权
System.out.println(subject.hasRole("role1"));//true
System.out.println(subject.hasRole("role2"));//true
System.out.println(subject.isPermitted("user:save"));//true
System.out.println(subject.isPermitted("user:update"));//true
System.out.println(subject.isPermitted("user:find"));//true
}