Simple and Flexible Security Framework--Shiro Architecture and Authentication Process

       Apache Shiro is a powerful and easy-to-use security framework that can be used in any application environment and can be well coupled with third-party frameworks. Its design goal is to simplify application security management. So how exactly does Shiro work?

       Let's first take a look at the architecture overview:

                         

       It is worth mentioning that Shiro does not provide maintenance of user permissions, but finds relevant data from one or more configured Realms (equivalent to DAO) to complete user authorization management and authentication (login).

1. Detailed architecture of Shiro

                     

                       (Refer to http://jinnianshilongnian.iteye.com/blog/2018936)

       1.Subject: Any "user" who can interact with the application.

       2.SecurityManager: The security manager is the heart of Shiro and is responsible for interacting with other components.

       3.Authenticator: Verify whether there is an identity, which is the usual login.

       4. Authorizer: Authorizer, used to determine whether the current user has permission to perform related operations.

       5.SessionManager: The component that manages the Session.

       6.CacheManager: Cache used to manage the user's identity, permissions, roles, etc.

       7.Cryptography: encryption, decryption, and salt value operations for passwords.

       8.Realm: Represents one or more secure entity data sources.

Through the above components, we can complete security-related functions such as authentication, authorization, session management, encryption/decryption, remember me, allowing one user to pretend to be another user.

The process of identity authentication

Authentication means login, the following example shows the process of authentication

package com.liugh;

import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.*;
import org.apache.shiro.config.IniSecurityManagerFactory;
import org.apache.shiro.mgt.SecurityManager;
import org.apache.shiro.session.Session;
import org.apache.shiro.subject.Subject;
import org.apache.shiro.util.Factory;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class Quickstart {
    private static final transient Logger log = LoggerFactory.getLogger(Quickstart.class);

    public static void main(String[] args) {
        Factory<SecurityManager> factory = new IniSecurityManagerFactory("classpath:shiro.ini");
        SecurityManager securityManager = factory.getInstance();
        SecurityUtils.setSecurityManager(securityManager);
        // 获取当前的 Subject. 调用 SecurityUtils.getSubject();
        Subject currentUser = SecurityUtils.getSubject();
        // 测试使用 Session
        // 获取 Session: Subject#getSession()
        Session session = currentUser.getSession();
        session.setAttribute("someKey", "aValue");
        String value = (String) session.getAttribute("someKey");
        if (value.equals("aValue")) {
            log.info("---> 检索正确的值[" + value + "]");
        }
        // 测试当前的用户是否已经被认证. 即是否已经登录.
        // 调动 Subject 的 isAuthenticated() 
        if (!currentUser.isAuthenticated()) {
        	// 把用户名和密码封装为 UsernamePasswordToken 对象
            UsernamePasswordToken token = new UsernamePasswordToken("lonestarr", "vespa");
            // rememberme
            token.setRememberMe(true);
            try {
            	// 执行登录. 
                currentUser.login(token);
            } 
            // 若没有指定的账户, 则 shiro 将会抛出 UnknownAccountException 异常. 
            catch (UnknownAccountException uae) {
                log.info("---->没有查询到用户名" + token.getPrincipal());
                return; 
            } 
            // 若账户存在, 但密码不匹配, 则 shiro 会抛出 IncorrectCredentialsException 异常。 
            catch (IncorrectCredentialsException ice) {
                log.info("----> 用户的密码错误 " + token.getPrincipal());
                return; 
            } 
            // 用户被锁定的异常 LockedAccountException
            catch (LockedAccountException lae) {
                log.info("用户: " + token.getPrincipal() + " 被锁定  " +
                        "请与管理员联系解锁它。");
            }
            // 所有认证时异常的父类.
            catch (AuthenticationException ae) {
            }
        }
        log.info("----> 用户 [" + currentUser.getPrincipal() + "] 登录成功.");
        // 测试是否有某一个角色. 调用 Subject 的 hasRole 方法.
        if (currentUser.hasRole("admin")) {
            log.info("----> 当前用户有管理员的角色");
        } else {
            log.info("----> 当前用户是个普通人");
            return; 
        }
        // 测试用户是否具备某一个行为,用户张三是否具备删除操作?
        if (currentUser.isPermitted("user:delete:zhangsan")) {
            log.info("zhangsan 用户具备了删除的操作");
        } else {
            log.info("zhangsan 用户不具备删除的操作");
        }
        // 执行登出. 调用 Subject 的 Logout() 方法.
        System.out.println("---->" + currentUser.isAuthenticated());
        currentUser.logout();
        System.out.println("---->" + currentUser.isAuthenticated());
        System.exit(0);
    }
}

The whole process is actually not difficult, we summarize

1. Call SecurityUtils.getSubject() to get the current Subject.;
2. Call the Subject's isAuthenticated() to test whether there is a login.
3. If the user is not logged in. Then encapsulate the username and password into a UsernamePasswordToken object

  • Create a form page
  • Submit the request to the SpringMVC Handler
  • Get username and password. 

4. Call the login(AuthenticationToken) method of the Subject to log in.
5. Customize the method of Realm, get the corresponding record from the database, and return it to Shiro.

6. Shior performs password comparison operation.

       In actual development, step 123 is actually completed in the Spring MVC Handler. If only authentication is required, inherit AuthenticatingRealm.class and rewrite the abstract method doGetAuthenticationInfo to query the user, whether it is locked, password encryption and salt value ratio operation, etc. How are these to be done? Stay tuned for the next article:

Simple and flexible security framework--Shiro password comparison and authorization


 

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=324407759&siteId=291194637