一、Shiro基本概括
RBAC: 基于角色的访问控制(Role-Based Access Control)
- 认证授权流程
认证:对用户身份的检查(登录验证)
授权:对用户权限的检查(是否有对应的操作权限)
~流程示意图:
(原来上图褐色区域部分是我们自己手写的代码,也就是过滤器拦截器。然而每个项目的这一步骤都相似有其共有核心,便出现了安全框架,shiro就是其一)
安全框架:一种帮助我们在应用开发系统过程中完成用户的认证和权限检查的框架。可以理解为演唱会入场处的保安检查认证。
~形容图:
常用安全框架:
- shiro:比较流行,Apache组织开发,功能相对强大(但没spring security大),容易使用(学之必吹)的java安全框架,小而简单。
- spring security:基于spring的一个安全框架,但是依赖于spring容器,有局限性。
- Aouth2:第三方授权登录,就类似打游戏或小程序等不需要注册账号,只需qq或者微信授权即可,内含授权码,凭证,令牌(token)。不了解有兴趣了解的也可以了解一下,能扩展我们的知识点,百度百科链接,便于理解的博客链接。
- 自定义安全认证中心。
shiro优点:
- 功能强大简单易用。
- 可以完成用户认证、授权、密码及会话管理。
- 小到app大到项目都可以应用。
- 本身主要是针对单体项目的认证授权。(单体项目:可以对比微服务架构项目来理解。)
二、Shiro的工作原理
1、Shiro的核心功能
- Anthentication(身份,认证) 认证:验证用户是否有相应的身份-登录认证
- Authorization 授权,即权限验证:对已经通过认证的用户检查是否具有某个权限或角色,从而控制是否能进行某种操作。
- Session Management 会话管理,用户在认证成功后创建会话,在没有退出之前,当前用户的所有信息都会被保存在这个会话中。可以是普通的JavaSE应用,也可以是web应用。
- Cryptography 加密,对敏感信息进行加密处理,shiro就提供了这种加密机制。
- 支持的特性:
Web Support — Shiro提供了过滤器,可以通过过滤器拦截web请求来处理web应用的访问控制。
Caching 缓存支持,shiro可以缓存用户信息以及用户的角色权限信息,可以提高执行效率。
Concurrency shiro支持多线程应用。
Testing提供测试支持。
Run As 身份伪装,允许一个用户以另一种身份去运行。
RemeberMe 保存密码。
- 特别说明:shiro是一个安全框架,不提供用户及权限的维护,只做检查!(用户的权限管理需要自己去设计).
2、Shiro的核心组件
- Shiro三大核心组件:Subject、Security Manager、Realms
~~Subject,表示待认证和授权的用户。 例如用户的账户密码被包装进subject.当然包装着当前信息不一定就只代表着账户密码,可以代表当前用户。
~~Security Manager,核心组件!接收请求,管理调用内部组件。他是Shiro框架的核心,Shiro就是通过Security Manager来进行内部实例的管理,并通过它来提供安全管理的各种服务。相当于Shiro这个框架的前端控制器(类比MVC)。
1.Aurhenticator,认证器
2.Anthorize , 授权器
3.SessionManager,会话管理器
4.cacheManager, 缓存管理器
~~Realm,相当于Shiro进行认证和授权的数据源。secrityManage 需要认证或授权,必然也需要数据源,数据源来自哪,就来自于reaml,它充当了Shiro与安全数据之间的“桥梁”或者“连接器”,也就是说,当对用户进行认证(登录)和授权(访问控制)验证时,Shiro会用应用配置的Realm中查找用户及其权限信息。Realm可以查找shiro.ini文件方式或通过dao层查找数据库两种方式去验证用户。相当于加了一层。
当用户信息放在了两个或者多个数据库,会有两个Realm或多个Realm分别去查找相应数据库,然后送给Shiro的SecurityManager去认证,这就叫Shiro的多Realm认证。
Shiro认证流程图如下:
三、基于javaSE应用—Shiro的基本使用(IDEA版本)
1.创建maven项目
File-->Close Project-->Create New Project-->选择Maven-->next-->Groupld和Artifactld的名字随便起-->next-->Project name随便起-->Project location位置看个人-->Finish.
2.导入Shiro依赖库
在已经创建好的maven项目中打开pom.xml文件,导入Shiro依赖库。
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-core</artifactId>
<version>1.4.1</version>
</dependency>
如果导入不成功,或者下的比较慢可能是maven配置的setting用了c盘的那个,可以自己设置回来:在File-->Settings-->Build,Execution,,,,-->Build Tools-->Maven 然后右侧的 User settings file和Local repository设置为自己设定的setting.xml文件和依赖放置文件repo,比如本人的用的maven仓库在d盘。如图:
如果maven镜像都没有配置好的话:点这里;
如果你 每次 创建的maven项目都会默认使用c盘的那个路径(在下maven的时候默认就会在c盘有这路径,没有办法),想要修改的话:点这里;
3.创建Shiro配置文件
~在resource目录下创建名为(名字随意)shiro.ini的文件。
~在文件中完成用户、角色及权限的配置,例如:
[users]
zhangsan=123456,seller
lisi=666666,ckmgr
admin=222222,admin
[roles]
admin=*
seller=order-add,order-del,order-list
ckmgr=ck-add,ck-del,ck-list
[users]代表了下面的都是用户,“=”左边的代表用户名,“=”用变得代表密码,“,”分割后,“seller”代表下面[roles]角色属性。
[roles]代表下面的是角色,“=”左边的是角色名,“=”右边的代表拥有的权限,“,”分割,其中“ * "代表着拥有所有权限。
4.测试代码
在上诉过程都完成之后,可以编写测试类代码:
注意几个包不要导错,所有的包应该都是在 org.apache.shiro.*下面的。
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.IncorrectCredentialsException;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.mgt.DefaultSecurityManager;
import org.apache.shiro.realm.text.IniRealm;
import org.apache.shiro.subject.Subject;
import java.util.Scanner;
public class TestShiro {
public static void main(String[] args) {
Scanner scan = new Scanner(System.in);
System.out.println("请输入用户名:");
String username = scan.nextLine();
System.out.println("请输入密码:");
String password = scan.nextLine();
//1、创建安全管理器
DefaultSecurityManager securityManager = new DefaultSecurityManager();
//2、创建Realm
IniRealm iniRealm = new IniRealm("classpath:shiro.ini");
//3、将Realm设置给安全管理器
securityManager.setRealm(iniRealm);
//4、将Realm设置给安全工具
SecurityUtils.setSecurityManager(securityManager);
//5、通过SecrityUtils工具类获取subject对象q
Subject subject = SecurityUtils.getSubject();
//【认证流程】
//a、将认证账号和密码封装到token对象中
UsernamePasswordToken token = new UsernamePasswordToken(username,password);
//b、通过subject对象调用login方法进行认证申请
boolean f = false;
try{
subject.login(token);
f = true;
}catch (IncorrectCredentialsException e){
f = false;
}
System.out.println(f?"登录成功!":"登录失败!");
//【授权】
//判断是否有某个角色
System.out.println(subject.hasRole("seller"));
//判断是否有某个权限
System.out.println(subject.isPermitted("order-del"));
}
}
持续更新中+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++持续更新中