shiro's basic knowledge reserve -- certification process

shiro function and basic knowledge

shiro mainly has two parts, one is authentication, the other is authorization

  • Authentication: when a user logs in to the system, shiro will authenticate whether the user is a logged in user.
  • Authorization: a system can have users in several roles, such as administrators or ordinary users. How to define administrators and ordinary users? This requires the authorization mechanism in shiro to assign different role permissions to users

Basic knowledge and process of certification

1. Key objects of authentication in shiro

  • **Subject: * * the subject is the user accessing the system. The subject enables the user, program and user to authenticate, which is called the subject.
  • **Principal: * * identity information basically refers to the user name or other information, but the identity information must be unique.
  • **Credential: * * credential information, which is only the security information known by the subject, such as password, certificate, etc

2. Certification process


Shiro will package the identity information and credential information into a Token and go to the security manager in the core architecture of Shiro to verify whether it is legal. If the information is consistent, you can enter the system. If it is inconsistent, the authentication fails.

3. Specific operation

Introducing shiro's dependency

		<dependency>
            <groupId>org.apache.shiro</groupId>
            <artifactId>shiro-core</artifactId>
            <version>1.3.2</version>
        </dependency>

Profile for introducing shiro

This is a * ini file. * ini file is similar to txt file. ini file can write some complex data formats. This configuration file should be placed in the resources folder of maven file. Used to learn shiro to write relevant permission data of our system. Put the permission data into the ini configuration file without directly connecting to the database

[users]
# user 'root' with password 'secret' and the 'admin' role
root = secret, admin
# user 'guest' with the password 'guest' and the 'guest' role
guest = guest, guest
# user 'presidentskroob' with password '12345' ("That's the same combination on
# my luggage!!!" ;)), and role 'president'
presidentskroob = 12345, president
# user 'darkhelmet' with password 'ludicrousspeed' and roles 'darklord' and 'schwartz'
darkhelmet = ludicrousspeed, darklord, schwartz
# user 'lonestarr' with password 'vespa' and roles 'goodguy' and 'schwartz'
lonestarr = vespa, goodguy, schwartz
# Automatically added information
xiaochen=123
# -----------------------------------------------------------------------------
# Roles with assigned permissions
#
# Each line conforms to the format defined in the
# org.apache.shiro.realm.text.TextConfigurationRealm#setRoleDefinitions JavaDoc
# -----------------------------------------------------------------------------
[roles]
# 'admin' role has all permissions, indicated by the wildcard '*'
admin = *
# The 'schwartz' role can do anything (*) with any lightsaber:
schwartz = lightsaber:*
# The 'goodguy' role is allowed to 'drive' (action) the winnebago (type) with
# license plate 'eagle5' (instance specific id)
goodguy = winnebago:drive:eagle5


Add some fixed content to the configuration file

In the previous step, we added shiro's configuration file. We can add our own information in the configuration file.
Example: in the figure below, xiaochen=123 means that the user name is xiaochen and the password is 123. You can log in to our system.
It is equivalent to writing some user names and passwords in the configuration file and allowing them to pass shiro's permissions.
(tip: This is only a part of shiro's process. Later, we will directly connect to the database to obtain the user name and password of the database)

Write the main method to test shiro's function

The process of this method is the process that shiro needs to operate for authentication. Note that the realm here is the original relay inirealm

package com.example.shiro.demoshiro;

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.mgt.DefaultSecurityManager;
import org.apache.shiro.mgt.SecurityManager;
import org.apache.shiro.realm.text.IniRealm;
import org.apache.shiro.subject.Subject;

//Test shiro's function
public class TestAuthenticator {
    public  static  void main(String[] args){
//        1. Create a security manager object
        DefaultSecurityManager securityManager=new DefaultSecurityManager();
//        2. Set realm to the security manager and read Shiro Ini configuration file
        securityManager.setRealm(new IniRealm("classpath:shiro.ini"));
//        3. The global tool class, securityUtils, provides authentication and exit methods
//        Set the security manager for the tool class of global security
        SecurityUtils.setSecurityManager(securityManager);
//        4. Get the subject of the key object
        Subject subject = SecurityUtils.getSubject();

//        5. Create a token, create an object of user password token, and assign a value
        UsernamePasswordToken token = new UsernamePasswordToken("xiaochen","123");

//        6. Perform user authentication and output a plurality of exception information
        try{
            System.out.println("Certification status:"+subject.isAuthenticated());//Get authentication status information
            subject.login(token); //User authentication
            System.out.println("Certification status:"+subject.isAuthenticated());
        }catch(UnknownAccountException e){
            e.printStackTrace();//Print exception information
            System.out.println("Authentication failed, user does not exist");
        }catch(IncorrectCredentialsException e) {
            e.printStackTrace();//Print exception information
            System.out.println("Authentication failed, user information error");
        }catch(Exception e){
                e.printStackTrace();//Print exception information
        }

    }
}

4. Read the information in the database

In 3, we introduced shiro's configuration file shiro Ini, user name and password are all set here, but when we really use shiro, we need the information stored in the database, so it is inevitable that we use shiro to connect to the database.

1. Theoretical analysis of source code

First, we can implement it through realm. Does our data come from the database or ini configuration file.
Through the source code, we found:
Finally, the user name verification is completed in the doGetAuthenticationInfo method under the simpleAccountRealm class that performs user name comparison. This simpleAccountRealm inherits the authorizing realm class. If we write a class to change it to the database as verification data, we also need to create a new class to inherit the authorizing realm class.
The final password verification is completed in the assertCredentialsMatch method in the AuthenticatingRealm class. It's done automatically.

2. Customize the realm class connecting to the database

The custom Realm class inherits the doGetAuthenticationInfo method in the authorizingream class implementation to redefine the source path of authentication. Here is the data changed to the database, and the doGetAuthorizationInfo () method is used for authorization

package com.example.shiro.realm;

import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.SimpleAuthenticationInfo;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;

/**
 * This class is customized, and the Realm converts the authenticated or authorized data source into a database
 */
public class CustomerRealm extends AuthorizingRealm {

//    Method of authorization
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
        return null;
    }
//     Method of authentication
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
//Get user name in token
        String principal = (String) authenticationToken.getPrincipal();
        System.out.println(principal);
//        According to the identity information, use jdbc or mybatis to query the relevant database. Here, use fake data for verification
//        Originally, an AuthenticationInfo object should be returned, which uses the implementation class simpleAuthenticationInfo of this class
        if("xiaochen".equals(principal)){
//            Parameter 1: returns the correct user name in the database; parameter 2: returns the correct password in the database; parameter 3: provides the name of the current realm this Getname(), which can be implemented by this method.
            SimpleAuthenticationInfo simpleAuthenticationInfo = new SimpleAuthenticationInfo("xiaochen","123",this.getName());
            return simpleAuthenticationInfo;

        }

        return null;
    }
}

3. Write the main method to test the realm

package com.example.shiro.demoshiro;


import com.example.shiro.realm.CustomerRealm;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.mgt.DefaultSecurityManager;
import org.apache.shiro.subject.Subject;

/**
 * Use the custom realm test class. The custom realm class is used here, so you don't have to use the in the ini configuration file
 */
public class TestCustomerRealmAuthentictor {
    public static void main(String[] args) {
        //    Create securityManager
        DefaultSecurityManager defaultSecurityManager = new DefaultSecurityManager();
        //    Set our ream
        defaultSecurityManager.setRealm(new CustomerRealm());
//        Set the security tool class to the security manager
        SecurityUtils.setSecurityManager(defaultSecurityManager);
//        Obtain the subject through the security tool class
        Subject subject = SecurityUtils.getSubject();
//        Create token
        UsernamePasswordToken token = new UsernamePasswordToken("xiaochen", "123");
        try {
            subject.login(token);
            System.out.println(subject.isAuthenticated());//Print verification status
        } catch (AuthenticationException e) {
            e.printStackTrace();
        }

    }


}

Keywords: Java Shiro

Added by snrecords on Mon, 03 Jan 2022 08:00:12 +0200