Shiro

概述

什么是权限管理
权限管理实现对用户访问系统的控制
用户可以访问而且只能访问自己被授权的资源
只要有用户和密码的系统,权限管理几乎都会出现
举例
给张三赋予“人力资源经理”角色
“人力资源经理”具有“查询员工”、“添加员工”、“修改员工”和“删除员工”权限。
此时张三能够进入系统,则可以进行这些操作;
权限管理
认证
对于需要访问控制的资源用户首先经过身份认证
是判断一个用户是否为合法用户的处理过程
授权
认证通过后,还需用户具有资源的访问权限,方可访问
控制能够访问哪些资源
shiro概述
Apache Shiro是Java的一个安全框架
Shiro是一个强大的简单易用的Java安全框架,主要用来更便捷的认证、授权、加密、会话管理、与Web集成、缓存等
Shiro使用起来小而简单
spring中有spring security ,是一个权限框架,它和spring依赖过于紧密,没有shiro使用简单。
shiro不依赖于spring,shiro不仅可以实现web应用的权限管理,还可以实现c/s系统,分布式系统权限管理,
shiro属于轻量框架,越来越多企业项目开始使用shiro.

shiro核心概念

核心类

Authentication
身份认证/登录,验证用户是不是拥有相应的身份;
Authorization
授权,即权限验证,验证某个已认证的用户是否拥有某个权限;
Session Manager
会话管理,即用户登录后就是一次会话,在没有退出之前,它的所有信息都在会话中;
Cryptography
加密,保护数据的安全性
Web Support
Web支持,可以非常容易的集成到Web环境;
Caching
缓存,比如用户登录后,其用户信息、拥有的角色/权限不必每次去查,这样可以提高效率;
Concurrency
shiro支持多线程应用的并发验证,即如在一个线程中开启另一个线程,能把权限自动传播过去;
Testing
提供测试支持;
Run As
允许一个用户假装为另一个用户(如果他们允许)的身份进行访问;
Remember Me
记住我,这个是非常常见的功能,即一次登录后,下次再来的话不用登录了。

整体类图

主要概念

Subject
当前的操作用户
可以是人
爬虫
当前跟软件交互的东西
在shiro当中我们可以统称"用户"
在代码的任何地方,你都能轻易的获得Shiro Subject。
一旦获得Subject,你就可以立即获得你希望用Shiro为当前用户做的90%的事情(登录、退出、访问会话、执行授权检查等)
SecurityManager
SecurityManager负责管理所有用户的安全操作
引用了多个内部嵌套安全组件,是Shiro框架的核心
你可以把它看成DispatcherServlet前端控制器。
用于调度各种Shiro框架的服务
Realms
Realms则是用户的信息认证器和用户的权限认证器
执行认证(登录)和授权(访问控制)时,Shiro会从应用配置的Realm中查找很多内容
Realm 可以理解为读取用户信息、角色及权限的 DAO
SecurityManager要验证用户身份与权限,那么它需要从Realm获取相应的信息进行比较以确定用户身份是否合法;
可以把Realm看成DataSource,即安全数据源。

Shiro架构

整体架构图

subject:主体
主体可以是用户也可以是程序,主体要访问系统,系统需要对主体进行认证、授权。
securityManager:安全管理器
主体进行认证和授权都是通过securityManager进行。
authenticator: 认证器
主体进行认证最终通过authenticator进行的。
authorizer: 授权器
主体进行授权最终通过authenticator进行的。
sessionManager:会话管理
web应用中一般是用web容器对session进行管理,shiro也提供一套session管理的方式。
sessionDao:
通过sessionDao管理session数据,
cacheManager: 缓存管理器
主要对session和授权数据进行缓存,比如将授权数据通过cacheManager进行缓存管理,和 ehcache整合对缓存数据进行管理。
realm: 领域
相当于数据源,通过realm存取认证、授权相关数据。
cryptography: 密码管理
提供了一套加密/解密的组件,方便开发。比如 提供常用的散列、加/解密等功能。

认证

什么是认证

  • 身份认证,就是判断一个用户是否为合法用户的处理过程
  • 通过核对用户输入的用户名和口令,看其是否与系统中存储的该用户的用户名和口令一致,来判断用户身份是否正确

关键对象

Subject:主体
用户
Principal:身份信息
是主体(subject)进行身份认证的标识,标识必须具有唯一性,如用户名、手机号、邮箱地址等
credential:凭证信息
是只有主体自己知道的安全信息,如密码、证书等。

使用ini完成认证

1.在Maven中添加依赖jar包

<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-core</artifactId>
<version>1.4.0</version>
</dependency>

2.添加shiro.ini配置文件

​ 首先准备一些用户身份/凭据(shiro.ini):

[users]
itlike=1234
my=1234

3.登录与退出

​ 1.构建securityManager工厂

​ 2.通过工厂创建securityManager

​ 3.将securityManager设置到运行环境中

​ 4.创建一个Subject实例

​ 5.创建token令牌

​ 6.用户登录

​ 7.用户退出

​ 代码

/*1.构建securityManager工厂*/
IniSecurityManagerFactory factory = new IniSecurityManagerFactory("classpath:shiro.ini");
/*2.通过工厂创建securityManager*/
SecurityManager securityManager = factory.getInstance();
/*3.将securityManager设置到运行环境中*/
SecurityUtils.setSecurityManager(securityManager);
/*4.创建一个Subject实例*/
Subject subject = SecurityUtils.getSubject();
/*5.创建token令牌 用户名和密码*/
UsernamePasswordToken token = new UsernamePasswordToken("itlike", "1234");
/*6.用户登陆*/
try {
subject.login(token);
} catch (UnknownAccountException e) {
System.out.println("用户名不存在");
e.printStackTrace();
}catch (IncorrectCredentialsException e){
System.out.println("密码错误");
e.printStackTrace();
}
System.out.println("是否认证"+subject.isAuthenticated());
/*7.用户退出*/
subject.logout();
System.out.println("是否认证"+subject.isAuthenticated());

认证流程

认证流程图

认证代码执行流程

​ 1.调用subject.login方法进行登录,其会自动委托给securityManager.login方法进行登录;

​ 2.securityManager通过Authenticator(认证器)进行认证;

​ 3.Authenticator的实现ModularRealmAuthenticator调用realm从ini配置文件取用户真实的账号和密码

​ 4.IniRealm先根据token中的账号去ini中找该账号,如果找不到则给ModularRealmAuthenticator返回null,如果找到则匹配密码,匹配密码成功则认证通过。

​ 5、最后调用Subject.logout进行退出操作。

自定义realm

1.创建一个类继承AuthorizingRealm

2.覆盖doGetAuthenticationInfo方法,在此方法当中数据库获取用户,交有验证器去验证

public class EmployeeRealm extends AuthorizingRealm {

    @Autowired
private EmployeeService employeeService; /*认证*/
@Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
System.out.println("来到了认证-------");
/*获取身份信息*/
String username = (String)token.getPrincipal();
System.out.println(username);
/*根据用户名当中查询有没有当前用户*/
Employee employee = employeeService.getEmployeeWithUserName(username);
System.out.println(employee);
if (employee == null){
return null;
}
/*认证*/
/*参数: 主体,正确的密码,盐,当前realm名称*/
SimpleAuthenticationInfo info = new SimpleAuthenticationInfo(
employee,
employee.getPassword(),
ByteSource.Util.bytes(employee.getUsername()),
this.getName()); return info;
} /*授权
web doGetAuthorizationInfo 什么时候调用
1.发现访问路径对应的方法上面 有授权注解 就会调用doGetAuthorizationInfo
2.页面当中有授权标签 也会调用doGetAuthorizationInfo
* */
@Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
return null;
}
}

3.在ini文件当中进行配置

myRealm=MyRealm
securityManager.realms=$myRealm

散列密码

概述

  • 散列算法一般用于生成数据的摘要信息,是一种不可逆的算法
  • 一般适合存储密码之类的数据,常见的散列算法如MD5、SHA等

使用shiro进行散列密码

​ Md5Hash

​ SimpleHash

​ 示例

Md5Hash md5Hash = new Md5Hash("itlike");
System.out.println(md5Hash);
/*通过加盐的方式来对密码进一步保护*/
Md5Hash md5Hash2 = new Md5Hash("itlike","myxq");
System.out.println(md5Hash2);
/*可进行二次散列*/
Md5Hash md5Hash3 = new Md5Hash("itlike","myxq",2);
System.out.println(md5Hash3); /*使用SimpleHash*/
SimpleHash simpleHash = new SimpleHash(
"md5",
"itlike",
"myxq",
2);
System.out.println(simpleHash);

realm中配置散列

  • 在ini文件当中进行散列
  • 要保证数据库中的密码是经过散列之后的
[main]
#定义凭证匹配器
credentialsMatcher=org.apache.shiro.authc.credential.HashedCredentialsMatcher
#散列算法
credentialsMatcher.hashAlgorithmName=md5
#散列次数
credentialsMatcher.hashIterations=3 #指定realm
myRealm=com.itlike.MyRealm
#配置散列
myRealm.credentialsMatcher=$credentialsMatcher
#配置自定义散列
securityManager.realms=$myRealm

授权

什么是授权

  • 授权,即访问控制,控制谁能访问哪些资源。
  • 主体进行身份认证后需要分配权限,方可访问系统的资源。
  • 对于某些资源没有权限是无法访问的。

使用ini形式配置权限信息

在ini文件中用户、角色、权限的配置规则
用户名=密码,角色1,角色2...
首先根据用户名找角色,再根据角色找权限,角色是权限集合。
权限字符串的规则
“资源标识符:操作:资源实例标识符”
对哪个资源的哪个实例具有什么操作
:”是资源/操作/实例的分割符
权限字符串也可以使用*通配符

​ 示例

[users]
#用户itlike的密码是1234,此用户具有role1和role2两个角色
itlike=1234,role1,role2
myxq=1234,role2 [roles]
#角色role1对资源user拥有create、update权限
role1=user:create,user:update
#角色role2对资源user拥有create、delete权限
role2=user:create,user:delete
#角色role3对资源user拥有create权限
role3=user:create

自定义Realm形式权限

/*获取身份信息*/
Object principal = principals.getPrimaryPrincipal();
/*根据用户名查询该用户的角色和权限*/
List<String> roles = new ArrayList();
roles.add("role1");
roles.add("role2");
List<String> permissions = new ArrayList();
permissions.add("user:create");
permissions.add("user:delete");
/*把角色和权限与subject关联在一起,返回*/
SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
info.addRoles(roles);
info.addStringPermissions(permissions);

SSM项目实战 之 Shiro的更多相关文章

  1. SSM项目实战 之 权限管理系统

    目录 SSM权限管理系统 项目搭建 1.创建Maven-webapp工程 2.SSM框架集成 3.添加代码生成器 主页搭建 EasyUI主页 员工列表 1.在tree当中指定跳转的地址--暂时用tre ...

  2. SSM项目实战

    1.  实战才是检验学的怎么样的标准,一个小项目,运行老是出错,加上自己一贯的马虎的习惯,不严谨,就使学习之路更加的曲折了,感觉自己在这一行中比较吃力,但是自己选择了这条路,就得好好走下去,不要怀疑自 ...

  3. SSM项目实战 之 Maven

    目录 Maven 简介 Maven是什么 Maven下载安装 Maven使用 Maven规定了一套默认的项目格式 创建第一个Maven项目 Maven仓库 Maven常用命令 Maven作用范围(sc ...

  4. SSM项目实战 之 EasyUI

    目录 EasyUI 简介 概述 使用EasyUI panel组件 简介 示例 JS形式及属性介绍 panel事件与方法 Window组件 概述 使用 行为 dialog 概述 使用 tabs组件 概述 ...

  5. Java归去来第4集:java实战之Eclipse中创建Maven类型的SSM项目

    一.前言 如果还不了解剧情,请返回第3集的剧情          Java归去来第3集:Eclipse中给动态模块升级 二.在Eclipse中创建Maven类型的SSM项目 2.1:SSM简介 SSM ...

  6. 15套java架构师、集群、高可用、高可扩展、高性能、高并发、性能优化、Spring boot、Redis、ActiveMQ、Nginx、Mycat、Netty、Jvm大型分布式项目实战视频教程

    * { font-family: "Microsoft YaHei" !important } h1 { color: #FF0 } 15套java架构师.集群.高可用.高可扩展. ...

  7. 15套java互联网架构师、高并发、集群、负载均衡、高可用、数据库设计、缓存、性能优化、大型分布式 项目实战视频教程

    * { font-family: "Microsoft YaHei" !important } h1 { color: #FF0 } 15套java架构师.集群.高可用.高可扩 展 ...

  8. java架构师负载均衡、高并发、nginx优化、tomcat集群、异步性能优化、Dubbo分布式、Redis持久化、ActiveMQ中间件、Netty互联网、spring大型分布式项目实战视频教程百度网盘

    15套Java架构师详情 * { font-family: "Microsoft YaHei" !important } h1 { background-color: #006; ...

  9. 15套java架构师大型分布式综合项目实战、千万高并发-视频教程

    * { font-family: "Microsoft YaHei" !important } h1 { color: #FF0 } 15套java架构师.集群.高可用.高可扩 展 ...

随机推荐

  1. node连接Mysql报错ER_NOT_SUPPORTED_AUTH_MODE

    报错信息 本人系统安装的是mysql-installer-community-8.0.18.0.msi这个版本,然后我本地使用node-mysql去连接数据库. test.js文件 var mysql ...

  2. 结对项目(java实现)

    一 .Github项目地址:https://github.com/734635746/MyApp 二.PSP表格 PSP2.1 Personal Software Process Stages 预估耗 ...

  3. unity 用LineRender画四边形并测面积

    作为一个菜鸡,这个高中数学题差不多废了我两个上午...好了,废话不多说,直接上代码... using System.Collections.Generic; using UnityEngine; pu ...

  4. php 弹窗案例

    <?php // 弹出对话框并且返回原来的页面 echo "<script language=\"JavaScript\">\r\n"; ec ...

  5. windows下binlog问题解决

    1.先确定mysql是否开启了binlog show binary logs; 默认情况下是不开启的 2.如何开启 在my.ini配置下添加两个参数 # Binary Logginglog-bin=m ...

  6. 七、Linux_端口、进程

    Linux_端口.进程 1.查看所有端口 netstat -nlutp 2.停掉使用端口的进程,根据进程pid kill 1818 kill -9 1818 # 强制杀掉进程 3.根据进程名杀死进程: ...

  7. golang面向对象实现

    面向对象编程三大特点:封装.继承.多态. 1. 构造函数 Go不支持构造器.如果某类型的零值不可用,需要提供NewT(parameters)函数,用来初始化T类型的变量.按照Go的惯例,应该把创建T类 ...

  8. k8s包管理工具helm - 介绍和安装

    目录 1.Kubernetes 应用部署的挑战 2.Helm 是什么 3.Helm 组件及相关术语 4.Helm 工作原理 5.Helm 安装 5.1 客户端安装 5.2 安装服务端 Tiller 5 ...

  9. sqliteman install parameter

    .安装前准备 系统要求:linux Qt库版本:一般都有 .安装文件 官网自行下载 .安装 )这里用的pscp pscp .\sqliteman-.tar.gz root@192.168.30.140 ...

  10. WM_MOUSEWHEEL、WM_LBUTTONDOWN等父子窗口消息传递陷阱

    mfc中,碰到以下问题:父对话框A.子窗口B.B是CWnd对象.需要在B中处理WM_MOUSEWHEEL.WM_LBUTTONDOWN等消息. 所以在B中增加对应的消息处理,发现B中的消息循环中,收不 ...