Files
rikako-note/spring/Apache Shiro/Apache Shiro Authorization.md
wu xiangkai e38a9a9333 日常提交
2022-11-14 17:24:14 +08:00

94 lines
4.8 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

- [Apache Shiro Authorization](#apache-shiro-authorization)
- [Authorization简介](#authorization简介)
- [Authorization的核心元素](#authorization的核心元素)
- [Permission](#permission)
- [权限粒度级别](#权限粒度级别)
- [Roles](#roles)
- [Role分类](#role分类)
- [User](#user)
- [在Apache Shiro中实行Authorization](#在apache-shiro中实行authorization)
- [通过java code实现authorization](#通过java-code实现authorization)
- [基于String的权限鉴定](#基于string的权限鉴定)
- [通过注解实现Authorization](#通过注解实现authorization)
# Apache Shiro Authorization
## Authorization简介
Authorization访问控制分配访问某资源的特定权限。
## Authorization的核心元素
### Permission
Permission是最原子级别的安全策略用来控制用户与应用进行交互时可以执行哪些操作。**格式良好的permission描述了资源的类型和与该资源交互时可以执行的操作。**
对于与数据相关的资源权限通常有create、read、update、deleteCRUD
#### 权限粒度级别
在Shiro中可以在任何粒度对permission进行定义。如下是permission粒度的一些定义
1. Resource级别该级别是最广泛和最容易构建的粒度级别在该级别用户可以对资源执行特定的操作。**在Resource级别该资源类型被指定但是没有限制用户操作特定的资源实例即用户可以对该Resource类型的所有实例进行操作**
2. Instance级别该级别限定了Permission可以操作的Resource Instance在该级别用户只能够对特定的Resource实例进行操作。
3. Attribute级别该级别比限定了Permission可以操作Resouce类型或Resource实例的某个属性
### Roles
Roles是一个Permission的集合用于简化权限和用户管理过程。用户可以被授予特定的角色来获得操作某些资源的权限。
#### Role分类
1. Role不实际关联具体的Permission当你具有banker的角色时其角色隐含你可以对账户进行操作的权限当你具有waiter的角色时默认可以对厨房的door进行open/close操作
2. Role实际关联具体的Permission在该情况下Role即为一系列Permission的集合你可以对银行账号进行create、delete操作因为操作银行账号是你已分配的admin角色的一个下属权限
### User
在Shiro中User即是一个Subject实例。在Shiro中Subject可以是任何与系统进行交互的主体可以是浏览器、客户端、crond定时任务等。
## 在Apache Shiro中实行Authorization
在Apache Shiro中Authorization可以通过如下方式执行
1. 通过代码实现即在java程序中通过代码实现访问控制
2. jdk注解可以在你的方法上加上authorization注解
3. jsp/gsp taglibs
### 通过java code实现authorization
可以通过如下代码进行角色鉴定:
```java
//get the current Subject
Subject currentUser = SecurityUtils.getSubject();
if (currentUser.hasRole("administrator")) {
//show a special button
} else {
//dont show the button?)
}
```
可以通过如下代码实现对权限的鉴定操作:
```java
Subject currentUser = SecurityUtils.getSubject();
Permission printPermission = new PrinterPermission("laserjet3000n","print");
If (currentUser.isPermitted(printPermission)) {
//do one thing (show the print button?)
} else {
//dont show the button?
}
```
#### 基于String的权限鉴定
如果不想构造Permission对象可以通过构造一个字符串来代表权限。该字符串可以是任何格式只要你的Realm能够识别该格式并且与权限进行交互。
```java
String perm = "printer:print:laserjet4400n";
if(currentUser.isPermitted(perm)){
//show the print button?
} else {
//dont show the button?
}
```
### 通过注解实现Authorization
可以通过java注解来实现Authorization过程**在使用注解之前必须先开启aop**。
如果在执行openAccount之前当前Subject必须拥有account:create权限那么可以通过如下方式来实现权限鉴定。如果当前用户未被直接授予或通过role间接授予该权限那么会抛出AuthorizationException异常。
```java
//Will throw an AuthorizationException if none
//of the callers roles imply the Account
//'create' permission
@RequiresPermissions("account:create")
public void openAccount( Account acct ) {
//create the account
}
```
如果要在执行方法之前进行角色校验,可以通过如下方式加上注解达到预期功能。
```java
//Throws an AuthorizationException if the caller
//doesnt have the teller role:
@RequiresRoles( "teller" )
public void openAccount( Account acct ) {
//do something in here that only a teller
//should do
}
```