Shiro Study Notes _ 0500 _ authorization, shiro Study Notes _ 0500
1. Authorization: Give the identityCertifiedGrant the ram user the permission to access certain resources.
2. Permission granularity: coarse granularity and fine granularity.
Coarse granularity:For example, the crud of a userTable.
Fine Granularity:TableRecord. For example, you can only query the salaries of users whose id is 1. Shiro generally manages coarse-grained permissions. For example, menus, buttons, and URLs. Generally, fine-grained permissions are controlled through services.
3. role:A set of permissions.
Roles have two concepts:
Implicit roles seem to be the traditional role-based access control. However, if you want to add or delete a role or redefine the behavior of a role, you need to modify a lot of code, which is difficult to maintain.
Explicit role, resource-based access control.
The Shiro Team advocates permission use and explicit roles. The difference between the two depends on this guy's article: new rbac Solution
4. Permission indicates the rule:Resource: Operation: instance. It can be expressed with wildcards.
For example, "user: add" indicates that the user has the permission to be added. "user: *" indicates that the user has the permission to perform all operations on the user. "user: delete: 100 indicates that you have the permission to delete records marked as 100.
5. Permission process in shiro:
========================================================== ====================================
6. Example program:
(Using ini for authentication)
Create a maven project. project structure:
Maven dependency:
<dependencies> <dependency> <groupId>org.apache.shiro</groupId> <artifactId>shiro-core</artifactId> <version>1.3.2</version> </dependency> <dependency> <groupId>commons-logging</groupId> <artifactId>commons-logging</artifactId> <version>1.2</version> </dependency> <dependency> <groupId>log4j</groupId> <artifactId>log4j</artifactId> <version>1.2.17</version> </dependency> <dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-log4j12</artifactId> <version>1.7.5</version> </dependency> </dependencies>
Log4j Configuration:
log4j.rootLogger=info, stdoutlog4j.appender.stdout=org.apache.log4j.ConsoleAppenderlog4j.appender.stdout.layout=org.apache.log4j.PatternLayoutlog4j.appender.stdout.layout.ConversionPattern=%d %p [%c] - %m %n
Shiro. ini configuration:
Two users are defined: zhangsan/1111, lisi/1111, and two roles: role1, role2, and role1 have the add, update, and delete permissions on the user. role2 has all permissions on the user.
[users]zhangsan=1111,role1lisi=1111,role2[roles]role1=user:add,user:update,user:deleterole2=user:*
Test procedure:
Package com. lhy. shiro; import java. util. arrayList; import java. util. arrays; import java. util. hashSet; import java. util. set; import org. apache. shiro. securityUtils; import org. apache. shiro. authc. incorrectCredentialsException; import org. apache. shiro. authc. unknownAccountException; import org. apache. shiro. authc. usernamePasswordToken; import org. apache. shiro. authz. permission; import org. apache. shiro. config. iniSec UrityManagerFactory; import org. apache. shiro. mgt. securityManager; import org. apache. shiro. subject. subject; import org. apache. shiro. util. factory; public class AuthorizationDemo {public static void main (String [] args) {// 1, create a SecurityManager Factory to read the shiro configuration file factory <SecurityManager> Factory = new IniSecurityManagerFactory ("classpath: shiro. ini "); // 2 obtain the securityManager s of the SecurityManager instance through the SecurityManager Factory EcurityManager = factory. getInstance (); // 3 set the SecurityManager object to the running environment SecurityUtils. setSecurityManager (securityManager); // 4 obtain the subject Subject subject = SecurityUtils through SecurityUtils. getSubject (); try {// 5. assume that the login name is zhangsan and the password is 1111 UsernamePasswordToken token = new UsernamePasswordToken ("zhangsan", "1111"); // 6. log on and verify the subject. login (token); // use subject to determine whether the user has verified if (subject. isAuthenticated () {Sy Stem. out. println ("User Logon successful! ") ;}} Catch (UnknownAccountException e) {e. printStackTrace (); System. out. println (" incorrect user name or password! ");} Catch (IncorrectCredentialsException e) {System. out. println (" incorrect user name or password! ");} // *************** Role-based authorization **************** * *** // hasRole determines a permission boolean flag = subject. hasRole ("role1"); System. out. println (flag);/*** hasAllRoles: determines whether a given [all roles] * parameter type: Collection <String> * returns boolean */flag = subject. hasAllRoles (Arrays. asList ("role1", "role2", "role3"); System. out. println ("authorize-hasAllRoles method-whether role1, role2, and role3 are available for all roles ---" + flag);/*** hasRoles method to determine one by one the given [roles ], return boolean [] * parameter type: List <String> */boolean [] flags = subject. hasRoles (Arrays. asList ("role1", "role2"); for (int I = 0; I <flags. length; I ++) {System. out. println ("authorize -- hasRoles -- determine which of the given roles are:" + flags [I]);}/*** if the hasRole method has no permission, false is returned and no exception is thrown, the checkRole method throws an exception * checks permissions, and UnauthorizedException is thrown if no corresponding role exists * // checks a permission subject. checkRole ("role2");/*** check Multiple permissions * parameter type: 1, variable parameter String ..., 2, Collection <String> */subject. checkRoles ("role1", "role2"); subject. checkRoles (Arrays. asList ("role1", "role2 ")); // *************** resource-based authorization **************** * *** // isPermitted: judge a single permission: boolean permitted = subject. isPermitted ("user: add"); System. out. println ("Resource-Based permission -- whether subject has-user: add permission-" + permitted);/*** isPermitted: determines whether there are certain * parameter types in multiple roles: string... variable Parameter * return: boolean [] */flags = subject. isPermitted ("user: add", "user: update", "user: read"); for (int I = 0; I <flags. length; I ++) {System. out. println (flags [I]);}/*** isPermittedAll: determines whether a given [all permissions] * parameter type: String... permissions Variable Parameter * return: boolean */flag = subject. isPermittedAll ("user: add", "user: update"); System. out. println (flag);/*** when determining a permission, an exception UnauthorizedException */subject will be thrown. checkPermission ("user: read");/*** Multiple permissions: checkPermissions * parameter type: String... permissions */subject. checkPermissions ("user: add", "user: update"); // 7 exit subject. logout ();}}
There are three methods to check permissions in shiro:
A) programming method:
If (subject. hasRole ("Administrator") {// operate a resource}
B) annotation:
@ RequiresRoles ("Administrator") public void list () {// query data}
C) labeling:
<Shiro: hasPermission name = "user: update"> <a href = "#"> update </a> </shiro>
Authorization process:
View the source code of subject. isPermitted:
In fact, the call is the isPermitted of the DelegatingSubject class, And the DelegatingSubject is handed over to securityManager.
Ctrl + t. Check the class relationship. As you can see, securityManager is the implementation class of the SecurityManager interface. The DefaultSecurityManager class inherits many parent classes.
Specifically, the authorsecursecuritymanager parent class AuthorizingSecurityManager contains an Authorizer,
Specifically, it calls the ModularRealmAuthorizer method and finally submits it to realm.
ModularRealmAuthorizer has a PermissionResolver, ctro + t to view the Realm: it actually calls AuthorizingRealm,
In AuthorizingRealm, PermissionResolver exists, while the actual calling is its implementation class WildcardPermissionResolver.
View WildcardPermission: a familiar character is displayed in it, which is a character used to parse shiro permissions.
Summary:
A) obtain the subject
B) Determine whether the subject is authenticated
C) Call subject. isPermitted */hasRole * to determine the authorization.
I) The subject class DelegatingSubject is used to call the method, and the processing is handed over to SecurityManager.
Ii) securityManager is processed by its implementation class DefaultSecurityManager, which is essentially handled by the parent class AuthorizingSecurityManager. This class is handled by authorizer)
Iii) Authorizer is processed by its implementation class ModularRealmAuthorizer. This class can call the corresponding Realm to obtain data. In this class, PermissionResolver can parse the permission string, in the corresponding Realm, the corresponding PermissionResolver is also handed over to WildcardPermissionResolver. This class calls WildPermission to parse the permission string.
Iv) return the processing result