tags: Shiro


Shiro article 3 [Authorization, Custom REAML Authorization]

We covered Shiro’s authentication in the last article, now let’s deal with Shiro’s authorization

Shiro’s licensing process is similar to the certification process:

Authorization methods supported by Shiro

Shiro supports three types of authorization:

Shiro supports authorization in three ways: (...) Programing is done by writing if/else authorization blocks: Subject Subject = securityutils.getSubject (); 3. Annotated: Done by placing appropriate annotations on the executing Java method: @requiresroles ("admin") public void hello() {// Have rights}... > </shiro:hasRole>Copy the code

Use programmatic authorization

Similarly, we are authorized through the security manager, so we still need to configure the corresponding configuration file:

Shro-permission. ini configuration file:

# user [users] # user zhang's password is 123, This user has role1 and role2 two roles zhang = 123, role1, role2 wang = 123, role2 # # access [roles] role role1 have the create, update the resource user permissions Role1 =user:create,user:update # Role role2 has the create and delete permissions on resource user Role3 =user:create # Permission identifier rules: Resource: Operation: instance (separated by semicolons) User :create :01 Indicates that the create operation is performed on instance 01 of user resources. User :create: The create operation is performed on user resources, which is equivalent to user:create:*. The create operation is performed on all user resource instances. User: * : 01 Indicates that all operations are performed on user resource instance 01.Copy the code

Code test:



	// Role authorization and resource authorization tests
	@Test
	public void testAuthorization(a) {

		Create a SecurityManager factory
		Factory<SecurityManager> factory = new IniSecurityManagerFactory(
				"classpath:shiro-permission.ini");

		/ / create the SecurityManager
		SecurityManager securityManager = factory.getInstance();

		// Set the SecurityManager to the system runtime environment, and then configure the SecurityManager in the Spring container
		SecurityUtils.setSecurityManager(securityManager);

		/ / create the subject
		Subject subject = SecurityUtils.getSubject();

		// Create a token
		UsernamePasswordToken token = new UsernamePasswordToken("zhangsan"."123");

		// Perform authentication
		try {
			subject.login(token);
		} catch (AuthenticationException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

		System.out.println("Certification Status:" + subject.isAuthenticated());
		// Perform authorization after the authentication succeeds

		// Role-based authorization
		// hasRole passes the role identity
		boolean ishasRole = subject.hasRole("role1");
		System.out.println("Single role judgment" + ishasRole);
		// hasAllRoles has multiple roles
		boolean hasAllRoles = subject.hasAllRoles(Arrays.asList("role1"."role2"."role3"));
		System.out.println("Multiple role judgment" + hasAllRoles);

		// Use the check method for authorization. If authorization fails, an exception will be thrown
		// subject.checkRole("role13");

		// Resource-based authorization
		// isPermitted passes the permission identifier
		boolean isPermitted = subject.isPermitted("user:create:1");
		System.out.println("Single permission judgment" + isPermitted);

		boolean isPermittedAll = subject.isPermittedAll("user:create:1"."user:delete");
		System.out.println("Multiple permission judgment" + isPermittedAll);
		// Use the check method for authorization. If authorization fails, an exception will be thrown
		subject.checkPermission("items:create:1");

	}

Copy the code

Customize the realm for authorization

Typically, our permissions are queried from the database, not paired against our profile. Therefore, we need to customize REAML, and let REAML compare the permissions of the database query

Shiro-realm. ini configuration file: Injects custom REAML information into the security manager

[the main] # custom realm customRealm = cn. Itcast. Shiro. Realm. CustomRealm # set the realm to the securityManager, Equivalent to injecting SecurityManager.Realms =$customRealm in SpringCopy the code

We already used a custom reAML last time, when we just overwrote the doGetAuthenticationInfo() method. This time we’ll override the doGetAuthorizationInfo() method

	// Used for authorization
	@Override
	protected AuthorizationInfo doGetAuthorizationInfo( PrincipalCollection principals) {
		
		// Get identity information from the principals
		// Convert the return value of the getPrimaryPrincipal method to the true identity type (the doGetAuthenticationInfo authentication above fills in the identity type to SimpleAuthenticationInfo),
		String userCode =  (String) principals.getPrimaryPrincipal();
		
		// Obtain permission information based on identity information
		// Connect to database...
		// Simulate getting data from the database
		List<String> permissions = new ArrayList<String>();
		permissions.add("user:create");// Create a user
		permissions.add("items:add");// Add permissions to goods
		//....
		
		// Check permissions for permissions.
		SimpleAuthorizationInfo simpleAuthorizationInfo = new SimpleAuthorizationInfo();
		// Populate the simpleAuthorizationInfo object with the authorization information queried above
		simpleAuthorizationInfo.addStringPermissions(permissions);

		return simpleAuthorizationInfo;
	}

Copy the code

Test procedure:


	// Customize a realm for resource authorization tests
	@Test
	public void testAuthorizationCustomRealm(a) {

		Create a SecurityManager factory
		Factory<SecurityManager> factory = new IniSecurityManagerFactory(
				"classpath:shiro-realm.ini");
		/ / create the SecurityManager
		SecurityManager securityManager = factory.getInstance();
		// Set the SecurityManager to the system runtime environment, and then configure the SecurityManager in the Spring container
		SecurityUtils.setSecurityManager(securityManager);
		/ / create the subject
		Subject subject = SecurityUtils.getSubject();

		// Create a token
		UsernamePasswordToken token = new UsernamePasswordToken("zhangsan"."111111");
		// Perform authentication
		try {
			subject.login(token);
		} catch (AuthenticationException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

		System.out.println("Certification Status:" + subject.isAuthenticated());
		// Perform authorization after the authentication succeeds

		// For resource-based authorization, calling the isPermitted method calls CustomRealm to query the correct permission data from the database
		// isPermitted pass the permission identifier to determine whether user:create:1 is in the CustomRealm query
		boolean isPermitted = subject.isPermitted("user:create:1");
		System.out.println("Single permission judgment" + isPermitted);

		boolean isPermittedAll = subject.isPermittedAll("user:create:1"."user:create");
		System.out.println("Multiple permission judgment" + isPermittedAll);

		// Use the check method for authorization. If authorization fails, an exception will be thrown
		subject.checkPermission("items:add:1");

	}
Copy the code


conclusion

  • Shiro user permissions come in three ways
    • programmatic
    • Annotation type
    • tabbed
  • Shiro’s REAML default is to find the configuration file information for authorization, we usually need reAML to query the corresponding information in the database. Therefore, you need to customize REAML
  • In general, the process of authentication and authorization is similar.

If you find this article helpful, give the author a little encouragement