Shiro学习笔记(4)-Shiro授权机制

前言

本文主要讲解shiro的具体授权机制,这和上一篇所说的认证一样属于shiro提供的核心功能。

u8WZfe.png

授权相关要素

(1) Permissions:
简单来说就是针对特定操作(crud…)或者针对特定资源的访问权限,permission是单纯的定义了一组具有访问权限的操作(不决定谁具有访问该操作的权限)。

(2) Roles :

角色代表了一组操作(权限)集合,角色通常会分配给特定的账户,并且一个用户可以拥有多个角色。

隐式角色 :绝大多数的应用,会声明一个角色,但是不会直接定义它的具体权限,只是我们印象中会有一组默认的权限。比如。我们定义了一个“admin”的角色,我们可能知道它是一个管理员,但是并不清楚它具体有哪些操作可以执行。我们需要在代码中通过if/else的判断来进行控制,这种方式在添加了新角色的时候需要加入大量代码,比如我们加了另一个admin角色admin2,他也有admin1的权限那么我们需要在判断条件中进行额外的判断,这样子就很麻烦。

显示角色: 显示角色指的是我们通过最初就细粒度的定义角色的权限,比如admin的权限我们定义成add:*,表示admin具有add下的所有的权限,当权限控制精确到具体操作的时候,我们不需要在新加入角色的时候再次进行判断,并且如果权限操作有所改变的时候比如admin只有delete下的deleteuser操作,我们只需要改成delete:deleteUser"就可以了。Shiro也推荐这种方法进行角色定义。

(3) Users : 用户代表这个应用的使用者,Shiro中指的就是Subject。用户拥有特定的角色或者权限来做具体的操作。

授权方式

编码式授权

这种方式往往是最直接的也是最容易的,具体分为两种验证方式:

(1)基于Role的授权 : 正如上面所说的可以通过隐式的判断角色类型来进行权限验证,操作方法如下

Subject currentUser = SecurityUtils.getSubject();

if (currentUser.hasRole("administrator")) {
    //show the admin button 
} else {
    //don't show the button?  Grey it out? 
} 

(2)基于Permission的授权 : 基于Permission的授权通过更细粒度的操作控制来更好的控制访问权限,操作方法如下

Obejct-based

Permission printPermission = new PrinterPermission("laserjet4400n", "print");

Subject currentUser = SecurityUtils.getSubject();

if (currentUser.isPermitted(printPermission)) {
    //show the Print button 
} else {
    //don't show the button?  Grey it out?
}

String-based

Subject currentUser = SecurityUtils.getSubject();

if (currentUser.isPermitted("printer:print:laserjet4400n")) {
    //show the Print button
} else {
    //don't show the button?  Grey it out? 
}

基于注解的授权

Shiro支持基于注解的权限控制

(1) @RequiresAuthentication:当前用户需要进行认证后才能操作

@RequiresAuthentication
public void updateUser(User user) {
}

(2) @RequiresGues:需要guest用户(即能成功登陆的用户)才能进行操作

@RequiresGuest
public void signUp(User user) {
...
} 

(3) @RequiresPermissions: 需要当前主题被授予了指定权限才能进行操作

@RequiresPermissions("user:create")
public void createUser(User user) {
 
}

(4) @RequiresRoles : 需要指定权限才能进行操作

@RequiresRoles("admin")
public void deleteUser(User user) {
 ... 
}

(5) @RequiresUser: 需要指定的用户才能进行特定操作

@RequiresUser
public void updateUser(User user) {
  ...
}

授权机制

uLxxxS.png

  1. 首先通过Subject hasRole*, checkRole*, isPermitted*, or checkPermission*等方法变种将需要验证的权限进行传入。
  2. 委派SecurityManager 调用hasRole*, checkRole*, isPermitted*, or checkPermission* 等方法变种进行验证
  3. SecurityManager再委派Authorizer调用hasRole*, checkRole*, isPermitted*, or checkPermission* 等方法变种进行验证。默认是一个ModularRealmAuthorizer,可以同时验证多个Realm。
  4. 最后再调用各自的Realm实现进行验证。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章