Fork me on GitHub

Shiro———权限管理(一)

1.权限管理

1.1什么是权限管理

基本上涉及到用户参与的系统都要进行权限管理,权限管理属于系统安全的范畴,权限管理实现对用户访问系统的控制,按照安全规则或者安全策略控制用户可以访问而且只能访问自己被授权的资源。

权限管理包括用户身份认证和授权两部分,简称认证授权。对于需要访问控制的资源用户首先经过身份认证,认证通过后用户具有该资源的访问权限方可访问。

1.2用户身份认证

身份认证,就是判断一个用户是否为合法用户的处理过程。最常用的简单身份认证方式是系统通过核对用户输入的用户名和口令,看其是否与系统中存储的该用户的用户名和口令一致,来判断用户身份是否正确。对于采用指纹等系统,则出示指纹;对于硬件Key等刷卡系统,则需要刷卡。

1.3用户授权

用户授权,简单理解为访问控制,在用户认证通过后,系统对用户访问资源进行控制,用户具有资源的访问权限方可访问。用户授权的流程到达了用户授权环节,当然是需要用户认证之后了用户访问资源,系统判断该用户是否有权限去操作该资源,如果该用户有权限才能够访问,如果没有权限就不能访问了

1.4权限管理

一般地,我们可以抽取出这么几个模型:

主体(账号、密码)
资源(资源名称、访问地址)
权限(权限名称、资源id)
角色(角色名称)
角色和权限关系(角色id、权限id)
主体和角色关系(主体id、角色id)

通常企业开发中将资源和权限表合并为一张权限表,如下:

资源(资源名称、访问地址)
权限(权限名称、资源id)
合并为:

权限(权限名称、资源名称、资源访问地址)

2.验证流程

  1. 首先调用Subject.login(token)进行登陆,其会委托给Security Manager,调用之前必须通过SecurityUtil’s.setSecurityManager()设置;
  2. SecurityManager负责真正的身份验证逻辑;它会委托给Authenticator进行身份验证;
  3. Authenticator才是真正的身份验证者,Shiro API中核心的身份认证入口点,此时衣自定义插入自己的实现;
  4. Authenticator可能会委托给相应的AuthenticationStrategy进行多Realm身份验证,默认以自定义插入自己的实现;
  5. Authenticator会把相应的token传入Realm,从Realm获取身份验证信息,如果返回/有抛出异常标十异常身份验证失败,此处可以配置多个Realm,将按照相应的顺序及策略进行访问。

3.简单应用

maven项目添加依赖

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>

<groupId>net.zzqd</groupId>
<artifactId>shiro-demo1</artifactId>
<version>1.0-SNAPSHOT</version>

<dependencies>
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-core</artifactId>
<version>1.2.3</version>
</dependency>
<!-- 日志工具包-->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
<version>1.6.1</version>
</dependency>
</dependencies>
</project>

shiro.ini

users下面是用户名,密码;roles下面是角色名,权限,*代表所有权限

1
2
3
4
5
6
7
[users]
root=123456,admin
test=000000,test

[roles]
admin=*
test=search,add,update

ShiroTest

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
package net.zzqd.shrio.test;

import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.config.IniSecurityManagerFactory;
import org.apache.shiro.mgt.SecurityManager;
import org.apache.shiro.subject.Subject;
import org.apache.shiro.util.Factory;



/**
* @author zqnh
* @date 2019/7/14 on 18:20.
*/
public class ShiroTest
{
public static void main(String[] args)
{
//读取配置文件,返回Factory对象,管理subject的工具
Factory<SecurityManager> factory =
new IniSecurityManagerFactory("classpath:shiro.ini");
//获取SecurityManager
SecurityManager securityManager = factory.getInstance();
//全局设置,设置一次
SecurityUtils.setSecurityManager(securityManager);
//subject代表当前用户交互的用户项
Subject subject = SecurityUtils.getSubject();
//用用户名和密码登陆
UsernamePasswordToken token = new UsernamePasswordToken("test","000000");
try{
//登陆
subject.login(token);
//判断是否验证过
if (subject.isAuthenticated())
{
System.out.println("登陆成功");
if(subject.hasRole("admin"))
{
System.out.println("有admin权限");
}else
{
System.out.println("没有admin权限");
}
if(subject.isPermitted("search"))
{
System.out.println("有search权限");
}else
{
System.out.println("没有search权限");
}
if(subject.isPermitted("del"))
{
System.out.println("有del权限");
}else
{
System.out.println("没有del权限");
}
if(subject.isPermittedAll("add","update"))
{
System.out.println("有add和update权限");
}
else
{
System.out.println("没有有add和update权限");
}
}
}catch (AuthenticationException e)
{
e.printStackTrace();
System.out.println("用户名或密码错误,登陆失败");
}
}
}

Shiro权限拦截

Shiro进行权限拦截时,也是基于拦截器,NameableFilter是给Filter起个名字,通过这个名字找到拦截器实例,OncePerRequestFilter是防止多次执行Filter,ShiroFilter是程序的入口点,用于拦截用于权限控制的请求进行处理,AdviceFilter类似于SpringMVC中的executer,其中preHandle类似于AOP中的前置增强,在拦截器执行前执行,如果返回True,表示继续拦截器执行,基于表单的处理,授权等,

类似于AOP中的后置返回增强,在拦截器执行后执行,比如计算进行时间,afterCompleon类似于AOP中的后置最终增强,不管有没有异常,都会执行,可以清理资源;PathMatchingFilter,pathMatch方法用于path与请求路径匹配,如果匹配返回true,preHandle,当pathMatch匹配到路径后,进行角色确认,

Like • 1 Liked 1 Comments 所有评论
  • zqnh commented on Fri May 24 2019

    我是作者,博客评论系统初始化成功,纪念一下!