Use of shiro in spring boot

Posted by Bobo the Bugbear on Wed, 26 Jan 2022 12:46:48 +0100

Shiro

I Shiro permissions

  • What is permission control:
    • Ignore particularly detailed concepts. For example, permissions can be subdivided into many types, such as function permissions, data permissions, management permissions, etc
    • Understand two concepts: user and resource, so that the specified user can only operate the specified resource (CRUD)
  • What to do when learning java web
    • There is a doFilter method in the Filter interface. Write your own business Filter and configure which web resource to intercept
    • If the access path hits the corresponding Filter, the doFilter() method will be executed, and then judge whether you have permission to access the corresponding resources
    • /api/user/info?id=1
public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) {
	HttpServletRequest httpRequest=(HttpServletRequest)request;
	HttpServletResponse httpResponse=(HttpServletResponse)response;

	HttpSession session=httpRequest.getSession();

	if(session.getAttribute("username")!=null){
		chain.doFilter(request, response);  //If it can be released
	} else {
		httpResponse.sendRedirect(httpRequest.getContextPath()+"/login.jsp");
	}
}

II Permission framework ACL and RBAC

2.1 what are ACL and RBAC

  • ACL: Access Control List
    • The core of a previously popular permission design is that users are directly linked to permissions
    • Advantages: simple and easy to use, convenient development
    • Disadvantages: users and permissions are directly linked, resulting in complexity and dispersion during authorization, which is not easy to manage
    • Example: common file system permission design directly adds permissions to users
  • RBAC: Role Based Access Control
    • Role based access control system. Permissions are associated with roles. Users get the permissions of these roles by becoming members of the appropriate roles
    • Advantages: it simplifies the management of users and permissions. By classifying users, roles and permissions are associated
    • Disadvantages: the development of ACL is relatively complex
    • Example: authorization verification framework and application based on RBAC model Apache Shiro and spring Security
  • BAT enterprise ACL S are generally used for the report system and Alibaba ODPS
  • Conclusion: it should not be too complex. If there are too many rules, the maintainability and performance will be reduced. More classification ABAC, PBAC, etc

2.2 introduction to mainstream authority framework and explanation of technical selection

  • What is spring Security: introduction to the official website

    Spring Security is a security framework that can provide declarative security access control solutions for spring based enterprise applications. It provides a set of beans that can be configured in the spring application context, and makes full use of Spring IoC, DI (inversion of control, DI: dependency injection) and AOP (aspect oriented programming) functions to provide declarative security access control function for the application system and reduce the work of writing a large amount of repeated code for enterprise system security control.
    Bottom line: the predecessor of Spring Security is Acegi Security, which is the framework used by the Spring project team to provide security authentication services

  • What is Apache Shiro: introduction to the official website

    • https://github.com/apache/shiro

Apache Shiro is a powerful and easy-to-use Java security framework that performs authentication, authorization, password, and session management. With Shiro's easy to understand API, you can get any application quickly and easily, from the smallest mobile application to the largest network and enterprise application. Bottom line: Shiro is a powerful and easy-to-use Java security framework that provides authentication, authorization, encryption and session management

  • Two advantages and disadvantages, how to choose

    • Apache Shiro is simpler to use than Spring Security
    • Shiro is powerful, simple and flexible. It does not bind to any framework or container and can run independently
    • Spring Security supports spring system well, but it is difficult to develop without spring system
    • Spring security supports Oauth authentication https://spring.io/projects/spring-security-oauth , Shiro needs to implement it himself

III Apache Shiro basic concepts and architecture

3.1 architecture diagram and four modules of Shiro core knowledge

  • Direct access to Apache Shiro official website http://shiro.apache.org/introduction.html
  • What is identity authentication
    • Authentication, ID card authentication, is generally login
  • What is authorization
    • Authorization, which assigns users roles or permissions to access certain resources
  • What is session management
    • Session Management is the user's session administrator. In most cases, it is a web session
  • What is encryption
    • Cryptography, data encryption and decryption, such as password encryption and decryption

[the external chain picture transfer fails. The source station may have an anti-theft chain mechanism. It is recommended to save the picture and upload it directly (img-u4yz1exu-1624780881563)( http://shiro.apache.org/assets/images/ShiroFeatures.png )]

3.2 Shrio authority control process and concept

  • Subject
    • We refer to users or programs as principals (such as users, third-party services, cron jobs), and principals access systems or resources
  • SecurityManager
    • The authentication and authorization of the security manager and Subject shall be carried out under the security manager
  • Authenticator
    • Authenticator, which is mainly responsible for the authentication of Subject
  • Realm
    • Data domain, Shiro and security data connector, such as jdbc connection database; Obtain information related to authentication and authorization through realm
  • Authorizer
    • The authorizer is mainly responsible for the authorization of the subject and controlling the role or permission of the subject
  • Cryptography
    • Encryption and decryption, Shiro contains easy-to-use and understandable data encryption and decryption methods, simplifying many complex APIs
  • Cache Manager
    • Cache managers, such as authentication or authorization information, manage through cache to improve performance

More information navigation: http://shiro.apache.org/reference.html

IV Spring boot integration Shiro

4.1 dependence

<dependencies>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    <dependency>
        <groupId>mysql</groupId>
        <artifactId>mysql-connector-java</artifactId>
    </dependency>
    <dependency>
        <groupId>com.zaxxer</groupId>
        <artifactId>HikariCP-java7</artifactId>
        <version>2.4.13</version>
    </dependency>
    <dependency>
        <groupId>com.baomidou</groupId>
        <artifactId>mybatis-plus-boot-starter</artifactId>
        <version>3.3.2</version>
    </dependency>
    <dependency>
        <groupId>org.apache.shiro</groupId>
        <artifactId>shiro-spring</artifactId>
        <version>1.4.1</version>
    </dependency>
    <dependency>
        <groupId>org.projectlombok</groupId>
        <artifactId>lombok</artifactId>
        <optional>true</optional>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-test</artifactId>
        <scope>test</scope>
        <exclusions>
            <exclusion>
                <groupId>org.junit.vintage</groupId>
                <artifactId>junit-vintage-engine</artifactId>
            </exclusion>
        </exclusions>
    </dependency>
</dependencies>

4.2 design of database table

Five tables of authority standards:

  • sys_user
  • sys_role
  • sys_user_role
  • sys_permission
  • sys_role_permission

4.3 custom realm

/**
 * Create a realm. There are two methods in the realm.
 */
public class CustomizeRealm extends AuthorizingRealm {

    // Authentication. As long as the AuthenticationInfo is returned successfully,
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
        System.out.println("Start certification");
        if(authenticationToken instanceof UsernamePasswordToken) {
            UsernamePasswordToken token = (UsernamePasswordToken)authenticationToken;
            String username = token.getUsername();
            String password = new String(token.getPassword()).intern();

            // To db validation
            System.out.println("username: " + username + "## password: " + password);

            AuthenticationInfo info = new SimpleAuthenticationInfo(username, password, "XX");
            return info;
        }
        return null;
    }

    // to grant authorization
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
        System.out.println("to grant authorization");
        return null;
    }
}

SecurityUtils. getSubject(). Where is the user information obtained by getprincipal () set?

Custom realm – "doGetAuthenticationInfo" – "simpleauthenticationinfo" = new simpleauthenticationinfo (user, user. Getpassword(), bytesourcesalt, getname());

The first parameter of the method is securityutils getSubject(). The value obtained by getprincipal () can set String and object.

It has been difficult to distinguish between authentication and authorization before. In fact, it is very simple. For example:

If you want to board the plane, you need to show your ID card and ticket. The ID card is to prove that you Zhang San is indeed you Zhang San. This is authentication; The ticket is to prove that you Zhang San did buy a ticket to get on the plane. This is authorization.

4.3 shiro configuration

@Configuration
public class ShiroConfig {

    @Bean
    public ShiroFilterFactoryBean shiroFilterFactoryBean(SecurityManager securityManager) {
        ShiroFilterFactoryBean factoryBean = new ShiroFilterFactoryBean();

        // Set up the SecurityManager to be responsible for the operation of the whole shiro
        factoryBean.setSecurityManager(securityManager);
        factoryBean.setLoginUrl("/login.html");

        Map<String, String> filterMap = new HashMap<>();
        /**
         * map The key of the map is the access path, and the value of the map is a fixed value: anno, authc
         * anon -> anonymous((anonymous)
         * authc -> authencation((certified)
         */
        filterMap.put("/login", "anon"); // Access is not allowed until authentication is passed
//        filterMap.put("/user", "authc"); //  Access is not allowed until authentication is passed
//        filterMap.put("/test", "authc"); //  It can be accessed anonymously. To put it bluntly, you don't need to log in
        filterMap.put("/**", "authc");

        factoryBean.setFilterChainDefinitionMap(filterMap);

        return factoryBean;
    }
    
    /**
    *  SecurityManager Configuration of
    */
    @Bean
    public SecurityManager securityManager(SessionManager manager, Realm realm) 	{
        DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
        securityManager.setSessionManager(sessionManager);
        securityManager.setRealm(realm);
        return securityManager;
    }

    /**
     *  This class is used to set permissions by implementing annotations
     */
    @Bean
    public DefaultAdvisorAutoProxyCreator advisorAutoProxyCreator(){
        DefaultAdvisorAutoProxyCreator advisor = new DefaultAdvisorAutoProxyCreator();
        advisor.setProxyTargetClass(true);
        return advisor;
    }
 
 	/**
     * Configure permissions by implementing annotations
     */
    @Bean
    public AuthorizationAttributeSourceAdvisor 
    			authorizationAttributeSourceAdvisor(SecurityManager securityManager){
        AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor = new 
        				AuthorizationAttributeSourceAdvisor();
        authorizationAttributeSourceAdvisor.setSecurityManager(securityManager);
        return authorizationAttributeSourceAdvisor;
    }
    /**
    @Bean
    public LifecycleBeanPostProcessor lifecycleBeanPostProcessor() {
        return new LifecycleBeanPostProcessor();
    }
     */
   /**
    *  SessionManager Configuration of
    */
    @Bean
    public SessionManager sessionManager(){
        SessionManager sessionManager = new CustomSessionManager();
        return sessionManager;
    }
    /**
     * Realm
     * @param addSaltCredentialsMatch
     * @return
     */
    @Bean
    public Realm realm(AddSaltCredentialsMatch addSaltCredentialsMatch) {
        CustomRealm realm = new CustomRealm();
        realm.setCredentialsMatcher(addSaltCredentialsMatch);  //Password rules
        return realm;
    }

    /**
     * Custom password salt rules
     * @return
     */
    @Bean
    public AddSaltCredentialsMatch addSaltCredentialsMatch() {
        return new AddSaltCredentialsMatch();
    }
}

4.4 user login

@RequestMapping("/login")
@RestController
public class LoginController {

    @GetMapping
    public String login(String username, String password) {
        // Get a topic (user)
        Subject subject = SecurityUtils.getSubject();

        UsernamePasswordToken token = new UsernamePasswordToken(username, password);

        subject.login(token);

        return "success";
    }
}

4.5 custom SessionManager

public class CustomSessionManager extends DefaultWebSessionManager {

    /**
     * Override the default session
     * @param request
     * @param response
     * @return
     */
    @Override
    protected Serializable getSessionId(ServletRequest request, ServletResponse response) {

        String sessionId = WebUtils.toHttp(request).getHeader("Authencation");
        if(null != sessionId) {
            request.setAttribute(ShiroHttpServletRequest.REFERENCED_SESSION_ID_SOURCE,
                    ShiroHttpServletRequest.COOKIE_SESSION_ID_SOURCE);

            request.setAttribute(ShiroHttpServletRequest.REFERENCED_SESSION_ID, sessionId);
            //automatically mark it valid here.  If it is invalid, the
            //onUnknownSession method below will be invoked and we'll remove the attribute at that time.
            request.setAttribute(ShiroHttpServletRequest.REFERENCED_SESSION_ID_IS_VALID, Boolean.TRUE);

            return sessionId;
        }else {
            return super.getSessionId(request, response);
        }
    }
}

V Permission data cache

As the middleware most frequently used by enterprises, redis is used to cache various business data. When shiro's cache is used, redis is still used as the caching Middleware in the course. Download address: https://github.com/MicrosoftArchive/redis/releases

5.1 introducing dependencies

<dependency>
      <groupId>org.crazycake</groupId>
      <artifactId>shiro-redis</artifactId>
      <version>3.2.3</version>
</dependency>

5.2 configuring RedisManager

@Bean
public RedisManager redisManager() {
	RedisManager redisManager = new RedisManager();
	redisManager.setHost("localhost:6379");
	return redisManager;
}

5.3 configuring CacheManager

@Bean
public CacheManager cacheManager(RedisManager redisManager) {
	RedisCacheManager cacheManager = new RedisCacheManager();
	cacheManager.setRedisManager(redisManager);
	return cacheManager;
}

5.4 add cache management in SecurityManager

securityManager.setCacheManager(cacheManager);

Vi Session data cache

6.1 configuring RedisSessionDao

@Bean
public RedisSessionDAO redisSessionDAO(RedisManager redisManager) {
	RedisSessionDAO redisSessionDAO = new RedisSessionDAO();
	redisSessionDAO.setRedisManager(redisManager);
	return redisSessionDAO;
}

6.2 setting of SessionManager

@Bean
public SessionManager sessionManager(RedisSessionDAO redisSessionDAO){
	CustomSessionManager sessionManager = new CustomSessionManager();
	sessionManager.setSessionDAO(redisSessionDAO);
	return sessionManager;
}

Appendix:

/**
   shiro Two md5 processes are provided internally. However, the data obtained is inconsistent with the md5 data obtained by other tool classes.
 */
@Bean
public CredentialsMatcher credentialsMatcher() {
	HashedCredentialsMatcher hashedCredentialsMatcher = new HashedCredentialsMatcher();
	hashedCredentialsMatcher.setHashAlgorithmName("MD5"); //Set encryption method
	hashedCredentialsMatcher.setHashIterations(2);  //md5 encryption twice

	return hashedCredentialsMatcher;
}

Processing method: when the user registers and stores the password, the password is stored according to shiro's rules.

new SimpleHash("md5", "123", null, 2).toString() // The password obtained by this processing method is stored in the database.

Topics: Shiro