一 权限框架设计之ACL和RBAC讲解*
简介:介绍什么是ACL和RBAC
ACL: Access Control List 访问控制列表
以前盛行的一种权限设计,它的核心在于用户直接和权限挂钩
优点:简单易用,开发便捷
缺点:用户和权限直接挂钩,导致在授予时的复杂性,比较分散,不便于管理
例子:常见的文件系统权限设计, 直接给用户加权限
RBAC: Role Based Access Control
基于角色的访问控制系统。权限与角色相关联,用户通过成为适当角色的成员而得到这些角色的权限
优点:简化了用户与权限的管理,通过对用户进行分类,使得角色与权限关联起来
缺点:开发对比ACL相对复杂
例子:基于RBAC模型的权限验证框架与应用 Apache
简介:介绍主流的权限框架 Apache Shiro、spring Security
什么是 spring Security:
官网基础介绍
官网:https://spring.io/projects/spring-security
什么是 Apache Shiro:
官网基础介绍
https://github.com/apache/shiro
两个优缺点,应该怎么选择
Apache Shiro比Spring Security , 前者使用更简单
Shiro 功能强大、 简单、灵活, 不跟任何的框架或者容器绑定,可以独立运行
Spring Security 对Spring 体系支持比较好,脱离Spring体系则很难开发
SpringSecutiry 支持Oauth鉴权 https://spring.io/projects/spring-security-oauth,Shiro需要自己实现
Shiro核心知识之架构图交互和四大模块讲解
简介:讲解Shiro架构图交互和四大核心模块 身份认证,授权,会话管理和加密
直达Apache Shiro官网 http://shiro.apache.org/introduction.html
什么是身份认证
Authentication,身份证认证,一般就是登录
什么是授权
Authorization,给用户分配角色或者访问某些资源的权限
什么是会话管理
Session Management, 用户的会话管理员,多数情况下是web session
什么是加密
Cryptography, 数据加解密,比如密码加解密等
简介:讲解用户访问整合Shrio的系统,权限控制的运行流程和Shiro常见名称讲解
直达官网 :http://shiro.apache.org/architecture.html
Subject
我们把用户或者程序称为主体(如用户,第三方服务,cron作业),主体去访问系统或者资源
SecurityManager
安全管理器,Subject的认证和授权都要在安全管理器下进行
Authenticator
认证器,主要负责Subject的认证
Realm
数据域,Shiro和安全数据的连接器,好比jdbc连接数据库; 通过realm获取认证授权相关信息
Authorizer
授权器,主要负责Subject的授权, 控制subject拥有的角色或者权限
Cryptography
加解密,Shiro的包含易于使用和理解的数据加解密方法,简化了很多复杂的api
Cache Manager
缓存管理器,比如认证或授权信息,通过缓存进行管理,提高性能
使用SpringBoot2.x整合Shiro权限认证
**Maven3.5 + Jdk8 + Springboot 2.X + IDEA **
创建SpringBoot项目
https://start.spring.io/
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<!-- 阿里巴巴druid数据源-->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.1.6</version>
</dependency>
<!-- 单元测试junit4 的依赖-->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
</dependency>
整合Shiro相关jar包
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-spring</artifactId>
<version>1.4.0</version>
</dependency>
Idea中Maven的更新(点击项目右键》maven》)
下面搭建测试环境
package com.example.demo;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.mgt.DefaultSecurityManager;
import org.apache.shiro.realm.SimpleAccountRealm;
import org.apache.shiro.subject.Subject;
import org.junit.Before;
import org.junit.Test;
/**
* 单元测试测试
*
* @BeforeClass>@Before>@Test>@Afer>@AfterClass
*
* @Test 加在待测试的方法前面
* @Before 带上@Test的方法执行前会执行该方法
* @After 带上@Test的方法执行完毕后会执行该方法
* @BeforeClass 加上这个注解,则该方法会第一个执行(在所有方法中),且方法要加上关键词static,是一个static方法
* @AfterClass 加上这个注解,则该方法最后一个执行(在所有方法中),同样,方法要加上关键词static,是一个static方法
* ————————————————
*
*/
public class TestAuth {
private SimpleAccountRealm accountRealm = new SimpleAccountRealm();
private DefaultSecurityManager defaultSecurityManager = new DefaultSecurityManager();
//环境的初始化
@Before
public void init() {
accountRealm.addAccount("xxx", "123");
accountRealm.addAccount("jhj", "123");
defaultSecurityManager.setRealm(accountRealm);
}
@Test
public void testAuthentication() {
SecurityUtils.setSecurityManager(defaultSecurityManager);
//当前操作主体, application user
Subject subject=SecurityUtils.getSubject();
UsernamePasswordToken usernamePasswordToken=new UsernamePasswordToken("jhj","123");
subject.login(usernamePasswordToken);
System.out.println("认证结果"+subject.isAuthenticated());
}
}
当密码输入正确时候输出是
当密码输入错误的时候出现异常
Shiro的授权实操和常用Api 梳理
//是否有对应的角色
subject.hasRole(“root”)
//获取subject名
subject.getPrincipal()
//检查是否有对应的角色,无返回值,直接在SecurityManager里面进行判断
subject.checkRole(“admin”)
//检查是否有对应的角色
subject.hasRole(“admin”)
//退出登录
subject.logout();
package com.example.demo;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.mgt.DefaultSecurityManager;
import org.apache.shiro.realm.SimpleAccountRealm;
import org.apache.shiro.subject.Subject;
import org.junit.Before;
import org.junit.Test;
/**
* 单元测试测试
*
* @BeforeClass>@Before>@Test>@Afer>@AfterClass
*
* @Test 加在待测试的方法前面
* @Before 带上@Test的方法执行前会执行该方法
* @After 带上@Test的方法执行完毕后会执行该方法
* @BeforeClass 加上这个注解,则该方法会第一个执行(在所有方法中),且方法要加上关键词static,是一个static方法
* @AfterClass 加上这个注解,则该方法最后一个执行(在所有方法中),同样,方法要加上关键词static,是一个static方法
* ————————————————
*
*/
public class TestAuth3 {
private SimpleAccountRealm accountRealm = new SimpleAccountRealm();
private DefaultSecurityManager defaultSecurityManager = new DefaultSecurityManager();
//环境的初始化
@Before
public void init() {
accountRealm.addAccount("xxx", "123","root","admin");
accountRealm.addAccount("jhj", "123");
defaultSecurityManager.setRealm(accountRealm);
}
@Test
public void testAuthentication() {
SecurityUtils.setSecurityManager(defaultSecurityManager);
//当前操作主体, application user
Subject subject=SecurityUtils.getSubject();
UsernamePasswordToken usernamePasswordToken=new UsernamePasswordToken("xxx","123");
subject.login(usernamePasswordToken);
//返回认证结构是否成功验证登录名和密码
System.out.println("认证结果"+subject.isAuthenticated());
//验证对应的角色是不是root
System.out.println("是否有对应的角色"+subject.hasRole("root"));
//经过测试getPrincpal认证结果是返回用户名
System.out.println("getPrincpal认证结果"+subject.getPrincipal());
//退出登录所以下面的认证结果为false
subject.logout();
System.out.println("认证结果"+subject.isAuthenticated());
}
}
idea因为有代码提示看起来特备爽,如下所示(简洁明了)