Shiro practical course (Part I)

Time:2021-9-27

Shiro practical course (Part I)

Note: the Shiro tutorial comes from a tutorial on site B. since the source code is paid, I won’t share it. The next article will explain the use of springboot with Shiro.

My personal blog:

Tianya Zhi

My official account: rookie thanks.

Shiro practical course (Part I)

1. Authority management

1.1 what is permission management

Basically, all systems involving user participation should be subject to permission management. Permission management belongs to the category of system security, and permission management is realizedControl of user access to the system, users can access and can only access their authorized resources according to security rules or security policies.

Rights management includes usersidentity authentication andto grant authorizationTwo parts, abbreviationAuthentication authorization。 For the resource that needs access control, the user first passes the identity authentication. After passing the authentication, the user can access the resource with the access authority.

1.2 what is identity authentication

identity authentication , which is the process of judging whether a user is a legal user. The most commonly used simple identity authentication method is that the system judges whether the user’s identity is correct by checking the user name and password entered by the user to see whether they are consistent with the user’s user name and password stored in the system. For systems using fingerprints, show fingerprints; Card swiping is required for hardware key and other card swiping systems.

1.3 what is authorization

Authorization, i.e. access control, control who can access which resources. After identity authentication, the principal needs to allocate permissions to access system resources. Some resources cannot be accessed without permissions


2. What is Shiro

Apache Shiro™ is a powerful and easy-to-use Java security framework that performs authentication, authorization, cryptography, and session management. With Shiro’s easy-to-understand API, you can quickly and easily secure any application – from the smallest mobile applications to the largest web and enterprise applications.

Shiro is a powerful and easy-to-use Java security framework that performs authentication, authorization, encryption, and session management. With Shiro’s easy to understand API, you can quickly and easily protect any application from the smallest mobile application to the largest web and enterprise applications.

Shiro is an open source framework under Apache. It extracts the functions related to security authentication of software system, realizes user identity authentication, authority authorization, encryption, session management and other functions, and forms a general security authentication framework.


3. Shiro’s core architecture

Shiro practical course (Part I)

3.1 Subject

Subject is the subject, the external application interacts with the subject. The subject records the current operating user. The concept of the user is understood as the main body of the current operation. It may be a user requesting through the browser or a running program. Subject is an interface in Shiro, which defines many methods related to authentication and authorization. External programs are authenticated and authorized through subject, while subject is authenticated and authorized through securitymanager security manager

3.2 SecurityManager

Securitymanager is the security manager, it is the core of Shiro and is responsible for the security management of all subjects. Subject authentication and authorization can be completed through securitymanager. In essence, securitymanager authenticates through authenticator, authorizes through authorizer, and manages sessions through SessionManager.

Securitymanager is an interface that inherits the three interfaces of authenticator, authorizer and SessionManager.

3.3 Authenticator

Authenticator is the authenticator, authenticator is an interface for authenticating the user’s identity. Shiro provides the implementation class of modularrealmauthenticator, which can basically meet most requirements or customize the authenticator.

3.4 Authorizer

The authorizer is the authorizer, the user is authenticated through the authenticator. When accessing the function, it is necessary to judge whether the user has the operation authority of this function through the authorizer.

3.5 Realm

Realm is the domain, which is equivalent to datasource data source. For security authentication, securitymanager needs to obtain user permission data through realm. For example, if the user identity data is in the database, realm needs to obtain user identity information from the database.

  • Note: don’t interpret realm as just fetching data from the data source. There are relevant codes for authentication and authorization verification in realm.

3.6 SessionManager

Session manager is session management, Shiro framework defines a set of session management, which does not depend on the session of the web container. Therefore, Shiro can be used in non web applications or centralized session management of distributed applications. This feature enables it to realize single sign on.

3.7 SessionDAO

Sessiondao is the session Dao, is a set of interfaces for session operations. For example, to store a session in a database, you can store the session in the database through JDBC.

3.8 CacheManager

CacheManager is cache management, store user rights data in the cache, which can improve performance.

3.9 Cryptography

Cryptography is password management, Shiro provides a set of encryption / decryption components to facilitate development. For example, it provides common hash, encryption / decryption and other functions.


4. Authentication in Shiro

4.1 certification

Identity authentication is the process of judging whether a user is a legal user. The most commonly used simple identity authentication method is that the system judges whether the user’s identity is correct by checking the user name and password entered by the user to see whether they are consistent with the user’s user name and password stored in the system.

4.2 key objects of certification in Shiro

  • Subject: subject

The user who accesses the system can be a user, a program, etc., and those who authenticate are called subjects;

  • Principal: identity information

It is the identity of the subject for identity authentication. The identity must haveUniquenessFor example, user name, mobile phone number, e-mail address, etc., an entity can have multiple identities, but it must have a primary identity.

  • Credential: credential information

It is the security information that only the subject knows, such as password, certificate, etc.

4.3 certification process

Shiro practical course (Part I)

4.4 development of certification

1. Create a project and introduce dependencies
<dependency>
  <groupId>org.apache.shiro</groupId>
  <artifactId>shiro-core</artifactId>
  <version>1.5.3</version>
</dependency>
2. Introduce Shiro configuration file and add the following configuration
[users]
xiaoxie=123
zhangsan=456

Shiro practical course (Part I)

3. Develop certification code
public class TestAuthenticator {
    public static void main(String[] args) {
        //Create securitymanager
        DefaultSecurityManager defaultSecurityManager = new DefaultSecurityManager();
        defaultSecurityManager.setRealm(new IniRealm("classpath:shiro.ini"));
        //The default security manager will be set in the installation tool class
        SecurityUtils.setSecurityManager(defaultSecurityManager);
        //Get principal object
        Subject subject = SecurityUtils.getSubject();
        //Create token token
        UsernamePasswordToken token = new UsernamePasswordToken("xiaochen1", "123");
        try {
            subject.login(token);// User login
            System.out.println ("login succeeded ~ ~);
        } catch (UnknownAccountException e) {
            e.printStackTrace();
            System. Out. Println ("wrong user name!!");
        }catch (IncorrectCredentialsException e){
            e.printStackTrace();
            System. Out. Println ("wrong password!!!");
        }

    }
}
  • Disabledaccountexception (account is disabled)
  • Lockedaccountexception (account is locked)
  • Excessiveattemptsexception (too many login failures)
  • Expiredcredentialsexception, etc

4.5 custom realm

The above program uses the inirealm provided by Shiro. Inirealm reads user information from the INI configuration file. In most cases, it needs to read user information from the system database, so it needs to customize the realm.

1. Realm provided by Shiro

Shiro practical course (Part I)

2. According to the authentication source code, the authentication uses simpleaccountrealm

Shiro practical course (Part I)
There are two methods in part of the source code of simpleaccountrealm, one is authentication and the other is authorization,

public class SimpleAccountRealm extends AuthorizingRealm {
        //...... Omitted
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
        UsernamePasswordToken upToken = (UsernamePasswordToken) token;
        SimpleAccount account = getUser(upToken.getUsername());

        if (account != null) {

            if (account.isLocked()) {
                throw new LockedAccountException("Account [" + account + "] is locked.");
            }
            if (account.isCredentialsExpired()) {
                String msg = "The credentials for account [" + account + "] are expired";
                throw new ExpiredCredentialsException(msg);
            }

        }

        return account;
    }

    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
        String username = getUsername(principals);
        USERS_LOCK.readLock().lock();
        try {
            return this.users.get(username);
        } finally {
            USERS_LOCK.readLock().unlock();
        }
    }
}
3. Custom realm
/**
 *Custom realm
 */
public class CustomerRealm extends AuthorizingRealm {
    //Authentication method
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
        return null;
    }

    //Authorization method
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
        String principal = (String) token.getPrincipal();
        if("xiaochen".equals(principal)){
            return new SimpleAuthenticationInfo(principal,"123",this.getName());
        }
        return null;
    }
}
4. Use custom realm authentication
public class TestAuthenticatorCusttomerRealm {
    public static void main(String[] args) {
        //Create securitymanager
        DefaultSecurityManager defaultSecurityManager = new DefaultSecurityManager();
        //IniRealm realm = new IniRealm("classpath:shiro.ini");
        //Set to custom realm to get authentication data
        defaultSecurityManager.setRealm(new CustomerRealm());
        //The default security manager will be set in the installation tool class
        SecurityUtils.setSecurityManager(defaultSecurityManager);
        //Get principal object
        Subject subject = SecurityUtils.getSubject();
        //Create token token
        UsernamePasswordToken token = new UsernamePasswordToken("xiaochen", "123");
        try {
            subject.login(token);// User login
            System.out.println ("login succeeded ~ ~);
        } catch (UnknownAccountException e) {
            e.printStackTrace();
            System. Out. Println ("wrong user name!!");
        }catch (IncorrectCredentialsException e){
            e.printStackTrace();
            System. Out. Println ("wrong password!!!");
        }

    }
}

4.6 using MD5 and salt

The practical application is to store the salt and hash values in the database, automatically take out the salt and encrypted values from the database, and Shiro completes the password verification.

1. Customize the realm of MD5 + salt
/**
 *Custom MD5 + salt realm
 */
public class CustomerRealm extends AuthorizingRealm {
    //Authentication method
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
        return null;
    }

    //Authorization method
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
        String principal = (String) token.getPrincipal();
        if("xiaochen".equals(principal)){
            String password = "3c88b338102c1a343bcb88cd3878758e";
            String salt = "Q4F%";
            return new SimpleAuthenticationInfo(principal,password, 
                                                ByteSource.Util.bytes(salt),this.getName());
        }
        return null;
    }
2. Use MD5 + salt authentication
public class TestAuthenticatorCusttomerRealm {
    public static void main(String[] args) {
        //Create securitymanager
        DefaultSecurityManager defaultSecurityManager = new DefaultSecurityManager();
        //IniRealm realm = new IniRealm("classpath:shiro.ini");
        //Set to custom realm to get authentication data
        CustomerRealm customerRealm = new CustomerRealm();
        //Set MD5 encryption
        HashedCredentialsMatcher credentialsMatcher = new HashedCredentialsMatcher();
        credentialsMatcher.setHashAlgorithmName("MD5");
        credentialsMatcher.setHashIterations(1024);// Sets the number of hashes
        customerRealm.setCredentialsMatcher(credentialsMatcher);
        defaultSecurityManager.setRealm(customerRealm);
        //The default security manager will be set in the installation tool class
        SecurityUtils.setSecurityManager(defaultSecurityManager);
        //Get principal object
        Subject subject = SecurityUtils.getSubject();
        //Create token token
        UsernamePasswordToken token = new UsernamePasswordToken("xiaochen", "123");
        try {
            subject.login(token);// User login
            System.out.println ("login succeeded ~ ~);
        } catch (UnknownAccountException e) {
            e.printStackTrace();
            System. Out. Println ("wrong user name!!");
        }catch (IncorrectCredentialsException e){
            e.printStackTrace();
            System. Out. Println ("wrong password!!!");
        }

    }
}

5. Authorization in Shiro

5.1 authorization

Authorization, or access control, controls who can access which resources. After identity authentication, the principal needs to allocate permissions to access system resources. Some resources cannot be accessed without permissions.

5.2 key objects

Authorization can be simply understood as how who operates what (which):

Who is the subject, the principal needs to access resources in the system.

What is the resource, such as system menu, page, button, class method, system commodity information, etc. Resources includeResource typeandResource instanceFor exampleProduct information is resource type, item of type T01 isResource instance, the commodity information numbered 001 also belongs to the resource instance.

How, permission, which specifies the permission of the entity to operate the resource. Permission is meaningless to leave the resource, such as user query permission, user add permission, call permission of a class method, modification permission of user No. 001, etc. through the permission, you can know what operation permission the entity has for which resources.

5.3 authorization process

Shiro practical course (Part I)

5.4 authorization method

  • Role based access control

    • RBAC role-based access control is a role-based access control

      if(subject.hasRole("admin")){
         //What resources do you operate on
      }
  • Resource based access control

    • RBAC (resource based access control) is a resource centric access control

      If (subject. Ispermission ("user: update: 01") {// resource instance
        //Modify 01 user
      }
      If (subject. Ispermission ("user: update: *") {// resource type
        //Modify 01 user
      }

5.5 permission string

The rules for permission strings are:Resource identifier: Action: resource instance identifier“:” is the delimiter of the resource / operation / instance. The permission string can also use the * wildcard.

example:

  • User creation permission: user: create, or user: create:*
  • User’s permission to modify instance 001: user: update: 001
  • All permissions of user instance 001: user: *: 001

5.6 implementation of authorization programming in Shiro

  • Programming

    Subject subject = SecurityUtils.getSubject();
    if(subject.hasRole(“admin”)) {
        //Have authority
    } else {
        //No permission
    }
  • Annotation type

    @RequiresRoles("admin")
    public void hello() {
        //Have authority
    }
  • Label type

    JSP / GSP tag: it is completed through the corresponding tag on the JSP / GSP page:
    <shiro:hasRole name="admin">
        <!—  Permission - >
    </shiro:hasRole>
    Note: using Shiro in thymeleaf requires additional integration!

5.7 development authorization

1. Realization of realm
public class CustomerRealm extends AuthorizingRealm {
    //Authentication method
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
        String primaryPrincipal = (String) principals.getPrimaryPrincipal();
        System.out.println("primaryPrincipal = " + primaryPrincipal);

        SimpleAuthorizationInfo simpleAuthorizationInfo = new SimpleAuthorizationInfo();

        simpleAuthorizationInfo.addRole("admin");

        simpleAuthorizationInfo.addStringPermission("user:update:*");
        simpleAuthorizationInfo.addStringPermission("product:*:*");


        return simpleAuthorizationInfo;
    }

    //Authorization method
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
        String principal = (String) token.getPrincipal();
        if("xiaochen".equals(principal)){
            String password = "3c88b338102c1a343bcb88cd3878758e";
            String salt = "Q4F%";
            return new SimpleAuthenticationInfo(principal,password, 
                                                ByteSource.Util.bytes(salt),this.getName());
        }
        return null;
    }

}
2. Authorization
public class TestAuthenticatorCusttomerRealm {
    public static void main(String[] args) {
        //Create securitymanager
        DefaultSecurityManager defaultSecurityManager = new DefaultSecurityManager();
        //IniRealm realm = new IniRealm("classpath:shiro.ini");
        //Set to custom realm to get authentication data
        CustomerRealm customerRealm = new CustomerRealm();
        //Set MD5 encryption
        HashedCredentialsMatcher credentialsMatcher = new HashedCredentialsMatcher();
        credentialsMatcher.setHashAlgorithmName("MD5");
        credentialsMatcher.setHashIterations(1024);// Sets the number of hashes
        customerRealm.setCredentialsMatcher(credentialsMatcher);
        defaultSecurityManager.setRealm(customerRealm);
        //The default security manager will be set in the installation tool class
        SecurityUtils.setSecurityManager(defaultSecurityManager);
        //Get principal object
        Subject subject = SecurityUtils.getSubject();
        //Create token token
        UsernamePasswordToken token = new UsernamePasswordToken("xiaochen", "123");
        try {
            subject.login(token);// User login
            System.out.println ("login succeeded ~ ~);
        } catch (UnknownAccountException e) {
            e.printStackTrace();
            System. Out. Println ("wrong user name!!");
        }catch (IncorrectCredentialsException e){
            e.printStackTrace();
            System. Out. Println ("wrong password!!!");
        }
        //Certification passed
        if(subject.isAuthenticated()){
            //Role based permission management
            boolean admin = subject.hasRole("admin");
            System.out.println(admin);

            boolean permitted = subject.isPermitted("product:create:001");
            System.out.println(permitted);
        }

    }
}

The next article will explain Shiro’s development with springboot. Thank you!!!