For example, to determine a user has permission to view the page, edit the data permissions, have a button permissions, and have the right to print, and so on.
I. Three elements of the mandate
Authorization has three core elements: permissions, roles, and users.
Permissions
Permissions are the core elements of the Apache Shiro security mechanism. It explicitly declares the allowed behavior and performance in the application. A well-formed permission declaration can clearly express the user's permissions to the resource.
Most of the resources 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 a permission declaration is to be based on resources and operations.
And we can only understand what this permission can do in the application through the permission declaration, but not who has this permission.
As a result, we need to associate users and permissions in the application.
The common practice is to assign permissions to a role and then associate the role with one or more users.
Permission Declaration and granularity
A Shiro permission declaration is usually a colon-delimited expression. As mentioned earlier, a permission expression can clearly specify the resource type, the allowed operations, and the accessible data. At the same time, the Shiro permission expression supports simple wildcard characters, and can be more flexible to set permissions.
The following example describes the permission expression.
User data can be queried
User:view
can query or edit user data
User:view,edit
Can do all of the user data
user:* or user
Can edit user data with ID 123
User:edit:123
Role
Shiro supports two role modes:
1, the traditional role: a role represents a series of operations, when the need for an operation to authorize authentication, only to determine whether the role can be. This kind of role privilege is relatively simple and fuzzy, which is not conducive to expansion.
2, Permission role: A role has a set of permissions. When authorizing authentication, you need to determine whether the current role has that permission. This role privilege can provide a detailed description of permissions for the role, and is suitable for more complex permission designs.
The following is a detailed description of the authorization implementation for both role patterns.
II. implementation of the mandate
Shiro supports three ways to implement the licensing process:
Coding implementation
Annotation implementation
JSP Taglig Implementation
1. Authorization implementation based on coding
1.1 implementation based on traditional role authorization
When you need to verify that a user has a role, you can invoke the Hasrole* method validation of the subject instance.
Copy Code code as follows:
Subject CurrentUser = Securityutils.getsubject ();
if (Currentuser.hasrole ("Administrator")) {
Show the admin button
} else {
Don ' t show the button? Grey it out?
}
The related authentication methods are as follows:
Subject method |
Describe |
Hasrole (String rolename) |
Returns True when the user has the specified role |
Hasroles (list<string> rolenames) |
Returns an array of Boolean values in the order of the list |
Hasallroles (collection<string> rolenames) |
Returns true if the user has all the specified roles |
Assertion Support
Shiro also supports authorization verification in an assertion manner. The assertion succeeds, does not return any values, the program continues execution, and when the assertion fails, an exception message is thrown. Using assertions, you can make our code more concise.
Copy Code code as follows:
Subject CurrentUser = Securityutils.getsubject ();
Guarantee that's the current user is a bank teller and
Therefore allowed to open:
Currentuser.checkrole ("Bankteller");
Openbankaccount ();
How to assert:
Subject method |
Describe |
Checkrole (String rolename) |
Asserts whether the user has a specified role |
Checkroles (collection<string> rolenames) |
Asserts whether the user has all the specified roles |
Checkroles (String ... rolenames) |
Method overload for the previous method |
1.2 Implementation based on privilege role authorization
Compared with the traditional role pattern, the role-based role pattern coupling is lower, it will not modify the source code because of the change of role, therefore, the role-based role pattern is a better way of access control.
Its code implementations are implemented in the following ways:
1, based on the implementation of the Rights object
Creates an instance of the org.apache.shiro.authz.Permission, passing the instance object as a parameter to subject.ispermitted () for validation.
Copy Code code as follows:
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 |
Describe |
ispermitted (Permission p) |
Subject have permission to set up, return Treu |
ispermitted (list<permission> perms) |
Returns a Boolean array of corresponding permissions |
Ispermittedall (collection<permission> perms) |
Returns True when subject has all the set permissions |
2, based on the implementation of string
The implementation of a string is more concise than a clunky, object-based approach.
Copy Code code as follows:
Subject CurrentUser = Securityutils.getsubject ();
if (currentuser.ispermitted ("printer:print:laserjet4400n")) {
Show the Print button
} else {
Don ' t show the button? Grey it out?
}
Permission expressions separated by colons are implementations of the Org.apache.shiro.authz.permission.WildcardPermission default support.
The resource types are represented here: operations: Resource IDs
Similar to object-based implementation-related methods, based on the implementation of string-related methods:
Ispermitted (string perm), ispermitted (String ... perms), Ispermittedall (String ... perms)
Assertion implementation based on permission object
Copy Code code as follows:
Subject CurrentUser = Securityutils.getsubject ();
Guarantee that's the current user is permitted
To open a bank account:
Permission p = new Accountpermission ("open");
Currentuser.checkpermission (P);
Openbankaccount ();
A string based assertion implementation
Copy Code code as follows:
Subject CurrentUser = Securityutils.getsubject ();
Guarantee that's the current user is permitted
To open a bank account:
Currentuser.checkpermission ("Account:open");
Openbankaccount ();
Related methods of assertion implementation
Subject method |
Description |
Checkpermission (Permission p) |
Assert that the user has set permissions |
Checkpermission (String Perm) |
Assert that the user has set permissions |
Checkpermissions (collection<permission> perms) |
Asserts whether the user has all the specified permissions |
Checkpermissions (String ... perms) |
Asserts whether the user has all the specified permissions |
2, the implementation of the authorization based on annotations
Shiro Annotations Support AspectJ, Spring, Google-guice, and so on, and can be configured differently depending on the application.
Related annotations:
@ requiresauthentication
A user class/attribute/method can be used to indicate that the current user needs to be a certified user.
Copy Code code as follows:
@RequiresAuthentication
public void Updateaccount (account UserAccount) {
This method is invoked by a
Subject This is guaranteed authenticated
...
}
@ requiresguest
Indicates that the user needs to be a "guest" user
@ requirespermissions
Current user needs to have set permissions
Copy Code code as follows:
@RequiresPermissions ("Account:create")
public void CreateAccount (account account) {
This method is invoked by a Subject
This is permitted to create
...
}
@RequiresRoles
Current user needs to have a role in place
@ requiresuser
The current user needs to be an authenticated user or a remembered user
3, based on the JSP tag authorization implementation
Shiro provides a set of JSP tag libraries to achieve page-level authorization control.
Before using the Shiro tag library, you first need to introduce the Shiro tag in the JSP:
Copy Code code as follows:
<%@ taglib prefix= "Shiro" uri= "Http://shiro.apache.org/tags"%>
Here are the Shiro tags:
Guest Label
Verify that the current user is a "visitor", that is, a user that is not authenticated (contains a memory that is not remembered)
Copy Code code as follows:
<shiro:guest>
Hi there! Please <a href= "login.jsp" >Login</a> or <a href= "signup.jsp" >Signup</a> today!
</shiro:guest>
User Label
Authenticated by or remembered by the user
Copy Code code as follows:
<shiro:user>
Welcome back john! Not John? Click <a href= "login.jsp" >here<a> to login.
</shiro:user>
Authenticated label
Authenticated user. Does not contain the remembered user, which is the difference from the user label.
Copy Code code as follows:
<shiro:authenticated>
<a href= "updateaccount.jsp" >update your contact information</a>
</shiro:authenticated>
Notauthenticated Label
Not authenticated through the user, corresponds to the authenticated label. The difference with the guest label is that the tag contains the remembered user.
Copy Code code as follows:
<shiro:notAuthenticated>
Please <a href= the "login.jsp" >login</a> in order to update your credit card information.
</shiro:notAuthenticated>
Principal label
Output current user information, usually the login account information
Copy Code code as follows:
Hello, <shiro:principal/> how do you are to today?
Hasrole Label
Verify that the current user belongs to the role
Copy Code code as follows:
<shiro:hasrole name= "Administrator" >
<a href= "admin.jsp" >administer the system</a>
</shiro:hasRole>
Lacksrole Label
In contrast to the Hasrole label logic, validation passes when the user does not belong to the role
Copy Code code as follows:
<shiro:lacksrole name= "Administrator" >
Sorry, you are not allowed to administer the system.
</shiro:lacksRole>
Hasanyrole Label
Verify that the current user belongs to any of the following roles.
Copy Code code as follows:
<shiro:hasanyroles name= "developer, project Manager, Administrator" >
You are either a developer, project manager, or administrator.
</shiro:lacksRole>
Haspermission Label
Verify that the current user has set permissions
Copy Code code as follows:
<shiro:haspermission name= "User:create" >
<a href= "createuser.jsp" >create a new user</a>
</shiro:hasPermission>
Lackspermission Label
In contrast to the Haspermission label logic, when the current user does not have permission to do so, the validation passes
Copy Code code as follows:
<shiro:haspermission name= "User:create" >
<a href= "createuser.jsp" >create a new user</a>
</shiro:hasPermission>
III. internal processing mechanism of Shiro authorization
1, invoke authorization authentication method in the application (subject ispermitted* or hasrole*, etc.)
2. An instance of Sbuject is usually an instance object of a Delegatingsubject class (or subclass), and the SecurityManager instance of the application setting is delegated to the corresponding ispermitted* or hasrole* method at the beginning of authentication.
3, next SecurityManager will entrust the built-in Authorizer instance (default is Modularrealmauthorizer class instance, similar authentication instance, it also supports one or more realm instance authentication) to invoke the appropriate authorization method.
4. Each realm will check to see if the same Authorizer interface is implemented. You will then invoke Reaml's own corresponding authorization validation method.
When multiple realm are used, unlike authentication policy processing, the authorization process:
1. When an exception is called Realm, an exception is thrown immediately, ending the authorization validation.
2, as long as there is a successful realm verification, then the authorization will be considered successful, immediately return, end certification.