Home  >  Article  >  Backend Development  >  Apache Shiro User Manual (3) Shiro Authorization

Apache Shiro User Manual (3) Shiro Authorization

黄舟
黄舟Original
2017-01-18 09:27:132222browse

Authorization is access control, which will determine whether the user has the corresponding access rights to resources in the application.

For example, determine whether a user has permission to view pages, permission to edit data, permission to have a certain button, and whether he has permission to print, etc.

1. Three elements of authorization

Authorization has three core elements: permissions, roles and users.

Permissions

Permissions are the core element of the Apache Shiro security mechanism. It clearly states the allowed behavior and performance in the application. A well-formatted permissions statement clearly communicates the permissions a user has on the resource.

Most resources will support typical CRUD operations (create, read, update, delete), but it makes sense for any operation to be based on a specific resource. Therefore, the fundamental idea of ​​permission declaration is based on resources and operations.

Through the permission declaration, we can only understand what this permission can do in the application, but we cannot determine who has this permission.

So, we need to associate users and permissions in the application.

The usual approach is to assign permissions to a role and then associate this role with one or more users.

Permission declaration and granularity

Shiro permission declaration usually uses expressions separated by colons. As mentioned before, a permission expression can clearly specify the resource type, allowed operations, and accessible data. At the same time, Shiro permission expressions support simple wildcards, allowing for more flexible permission settings.

The following uses examples to illustrate permission expressions.

User data can be queried

User:view

User data can be queried or edited

User:view,edit

Can be edited Perform all operations on user data

User:* or user

Can edit user data with id 123

User:edit:123

Role

Shiro supports two role modes:

1. Traditional role: A role represents a series of operations. When an operation needs to be authorized and verified, you only need to determine whether it is the role. Can. This kind of role permissions is relatively simple and vague, which is not conducive to expansion.

2. Permission role: A role has a set of permissions. During authorization verification, it is necessary to determine whether the current role has the permission. This kind of role permissions can provide a detailed permission description for the role, which is suitable for more complex permission designs.

The authorization implementation of the two role modes will be described in detail below.

2. Authorization implementation

Shiro supports three ways to implement the authorization process:

Coding implementation
Annotation implementation
JSP Taglig implementation

1. Encoding-based authorization implementation

1.1 Traditional role-based authorization implementation

When you need to verify whether a user has a certain role, you can call the hasRole* method of the Subject instance to verify.

Subject currentUser = SecurityUtils.getSubject(); 

if (currentUser.hasRole("administrator")) { 

//show the admin button 

} else { 

//don't show the button? Grey it out? 

}

The relevant verification methods are as follows:

Subject method                                                                                                                                                                                                            The verification method

hasRoles(List roleNames) Returns a corresponding boolean value array in order of the list

hasAllRoles(Collection roleNames) Returns true if the user has all specified roles

Assertion Support

Shiro also supports authorization verification in the form of assertions. If the assertion succeeds, no value is returned and the program continues execution; if the assertion fails, an exception message will be thrown. Using assertions can make our code more concise.

Subject currentUser = SecurityUtils.getSubject(); 

//guarantee that the current user is a bank teller and 

//therefore allowed to open the account: 

currentUser.checkRole("bankTeller"); 

openBankAccount();

Relevant methods of assertion:

Subject method                                                                                                                                                                                                                 roleNames) Assert whether the user has all specified roles

checkRoles(String... roleNames) Overload the previous method

1.2 Based on permission role authorization implementation

Related Compared with the traditional role model, the permission-based role model is less coupled. It will not modify the source code due to role changes. Therefore, the permission-based role model is a better access control method.

Its code implementation has the following implementation methods:

1. Implementation based on permission object


Create an instance of org.apache.shiro.authz.Permission, and This instance object is passed as a parameter to Subject.isPermitted() for verification.

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? 

} 

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? 

}

The relevant methods are as follows:



Subject method Description

isPermitted(Permission p) When the Subject has the specified permissions, treu is returned

isPermitted(List perms)    返回对应权限的boolean数组    

isPermittedAll(Collection perms)    Subject拥有所有制定权限时,返回true    

2、 基于字符串的实现 

相比笨重的基于对象的实现方式,基于字符串的实现便显得更加简洁。 

Subject currentUser = SecurityUtils.getSubject(); 

if (currentUser.isPermitted("printer:print:laserjet4400n")) { 

//show the Print button 

} else { 

//don't show the button? Grey it out? 

}

使用冒号分隔的权限表达式是org.apache.shiro.authz.permission.WildcardPermission 默认支持的实现方式。 

这里分别代表了 资源类型:操作:资源ID 

类似基于对象的实现相关方法,基于字符串的实现相关方法: 

isPermitted(String perm)、isPermitted(String... perms)、isPermittedAll(String... perms) 

基于权限对象的断言实现 

Subject currentUser = SecurityUtils.getSubject(); 

//guarantee that the current user is permitted 

//to open a bank account: 

Permission p = new AccountPermission("open"); 

currentUser.checkPermission(p); 

openBankAccount();

基于字符串的断言实现 

Subject currentUser = SecurityUtils.getSubject(); 

//guarantee that the current user is permitted 

//to open a bank account: 

currentUser.checkPermission("account:open"); 

openBankAccount();

断言实现的相关方法 

Subject方法    说明    

checkPermission(Permission p)    断言用户是否拥有制定权限    

checkPermission(String perm)    断言用户是否拥有制定权限    

checkPermissions(Collection perms)    断言用户是否拥有所有指定权限    

checkPermissions(String... perms)    断言用户是否拥有所有指定权限

   

2、基于注解的授权实现 

Shiro注解支持AspectJ、Spring、Google-Guice等,可根据应用进行不同的配置。 

相关的注解: 

@ RequiresAuthentication 

可以用户类/属性/方法,用于表明当前用户需是经过认证的用户。 

@RequiresAuthentication 

public void updateAccount(Account userAccount) { 

//this method will only be invoked by a 

//Subject that is guaranteed authenticated 

... 

} 

@ RequiresGuest

表明该用户需为”guest”用户 

@ RequiresPermissions 

当前用户需拥有制定权限 

@RequiresPermissions("account:create") 

public void createAccount(Account account) { 

//this method will only be invoked by a Subject 

//that is permitted to create an account 

... 

} 

@RequiresRoles

当前用户需拥有制定角色 

@ RequiresUser 

当前用户需为已认证用户或已记住用户 

3、基于JSP TAG的授权实现 

Shiro提供了一套JSP标签库来实现页面级的授权控制。 

在使用Shiro标签库前,首先需要在JSP引入shiro标签: 

<%@ taglib prefix="shiro" uri="http://shiro.apache.org/tags" %>

下面一一介绍Shiro的标签: 

guest标签 

验证当前用户是否为“访客”,即未认证(包含未记住)的用户 

<shiro:guest> 

Hi there! Please <a href="login.jsp">Login</a> or <a href="signup.jsp">Signup</a> today! 

</shiro:guest>

user标签 

认证通过或已记住的用户 

<shiro:user> 

Welcome back John! Not John? Click <a href="login.jsp">here<a> to login. 

</shiro:user>

authenticated标签 

已认证通过的用户。不包含已记住的用户,这是与user标签的区别所在。 

<shiro:authenticated> 

<a href="updateAccount.jsp">Update your contact information</a>. 

</shiro:authenticated> 

notAuthenticated标签

未认证通过用户,与authenticated标签相对应。与guest标签的区别是,该标签包含已记住用户。 

<shiro:notAuthenticated> 

Please <a href="login.jsp">login</a> in order to update your credit card information. 

</shiro:notAuthenticated>

principal 标签 

输出当前用户信息,通常为登录帐号信息 

Hello, <shiro:principal/>, how are you today?

验证当前用户是否属于该角色 

<shiro:hasRole name="administrator"> 

<a href="admin.jsp">Administer the system</a> 

</shiro:hasRole>

lacksRole标签 

与hasRole标签逻辑相反,当用户不属于该角色时验证通过 

<shiro:lacksRole name="administrator"> 

Sorry, you are not allowed to administer the system. 

</shiro:lacksRole>

hasAnyRole标签 

验证当前用户是否属于以下任意一个角色。 

<shiro:hasAnyRoles name="developer, project manager, administrator"> 

You are either a developer, project manager, or administrator. 

</shiro:lacksRole>

hasPermission标签 

验证当前用户是否拥有制定权限 

<shiro:hasPermission name="user:create"> 

<a href="createUser.jsp">Create a new User</a> 

</shiro:hasPermission>

lacksPermission标签 

与hasPermission标签逻辑相反,当前用户没有制定权限时,验证通过 

<shiro:hasPermission name="user:create"> 

<a href="createUser.jsp">Create a new User</a> 

</shiro:hasPermission>

三、Shiro授权的内部处理机制 

Apache Shiro User Manual (3) Shiro Authorization

1、在应用程序中调用授权验证方法(Subject的isPermitted*或hasRole*等) 

2、Sbuject的实例通常是DelegatingSubject类(或子类)的实例对象,在认证开始时,会委托应用程序设置的securityManager实例调用相应的isPermitted*或hasRole*方法。 

3、接下来SecurityManager会委托内置的Authorizer的实例(默认是ModularRealmAuthorizer 类的实例,类似认证实例,它同样支持一个或多个Realm实例认证)调用相应的授权方法。 

4、每一个Realm将检查是否实现了相同的 Authorizer 接口。然后,将调用Reaml自己的相应的授权验证方法。 

当使用多个Realm时,不同于认证策略处理方式,授权处理过程中: 

1、当调用Realm出现异常时,将立即抛出异常,结束授权验证。 

2、只要有一个Realm验证成功,那么将认为授权成功,立即返回,结束认证。

以上就是Apache Shiro 使用手册(三)Shiro 授权的内容,更多相关内容请关注PHP中文网(www.php.cn)!


Statement:
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn