Integration of springboot and Shiro privilege management

Time:2021-3-3

Subject: user principal (give the operation to the security manager)

Securitymanager: Security Manager (associated realm)

Realm: a bridge for Shiro to connect data

rely on

Shiro dependency

     <!-- https://mvnrepository.com/artifact/org.apache.shiro/shiro-spring -->
            <dependency>
                <groupId>org.apache.shiro</groupId>
                <artifactId>shiro-spring</artifactId>
                <version>1.3.2</version>
            </dependency>

Thymeleaf integrates Shiro permission label

    <!-- https://mvnrepository.com/artifact/com.github.theborakompanioni/thymeleaf-extras-shiro -->
            <dependency>
                <groupId>com.github.theborakompanioni</groupId>
                <artifactId>thymeleaf-extras-shiro</artifactId>
                <version>2.0.0</version>
            </dependency>

Integrating mybatis

dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <scope>runtime</scope>
        </dependency>
        <!-- https://mvnrepository.com/artifact/com.alibaba/druid -->
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid</artifactId>
            <version>1.1.10</version>
        </dependency>
        <dependency>
            <groupId>org.mybatis.spring.boot</groupId>
            <artifactId>mybatis-spring-boot-starter</artifactId>
            <version>2.0.0</version>
        </dependency>

to configure

establish UserController.java

@RequestMapping("/login")
        public String login(String name,String password,boolean rememberMe, Model model) {

             //1. Get subject
            Subject subject = SecurityUtils.getSubject();

            //2. Encapsulating user data
            UsernamePasswordToken token = new UsernamePasswordToken(name,password,rememberMe);

            //3. Execute login method
            try {
                //Leave it to realm to process --- execute its authentication method
                subject.login(token);
                //Login successful
                return "redirect:/testThymeleaf";
            }catch (UnknownAccountException e){
                //Login failed: the user name does not exist
                model.addAttribute("msg","User name does not exist");
                return "user/login";
            }catch (IncorrectCredentialsException e){
                //Login failure: wrong password
                model.addAttribute("msg","Password error");
                return "user/login";
            }
        }

establish UserRealm.java

package com.brewin.shiro.config;

import org.apache.shiro.SecurityUtils;
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.authc.UsernamePasswordToken;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.apache.shiro.subject.Subject;
import org.springframework.beans.factory.annotation.Autowired;

import com.brewin.shiro.domain.User;
import com.brewin.shiro.service.UserService;

public class UserRealm extends AuthorizingRealm{
    @Autowired
    private UserService userService;
    //Authorization logic
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection arg0) {
        // TODO Auto-generated method stub
        System.out.println("Execute authorization logic");
        //Empowering resources
        SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
        //Add the authorization string for the resource
//        info.addStringPermission("user:update");

        //Get the current login user
        Subject subject = SecurityUtils.getSubject();
        User user = (User)subject.getPrincipal();
        //System.out.println(subject.getPrincipal());
        User dbUser = userService.findById(user.getId());
       // info.addStringPermission("user:add");
        info.addStringPermission(dbUser.getPerms());
        return info;
    }
//Authentication logic
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
        // TODO Auto-generated method stub
        System.out.println("Execute authentication logic");
           //Write Shiro judgment logic to judge user name and password
        UsernamePasswordToken token  =  (UsernamePasswordToken)authenticationToken;

        User user = userService.findByName(token.getUsername());

        //1. Judge user name
        if(user == null){
            //The user name does not exist
            return null; //Shiro bottom layer will throw unknowaccountexception
        }

        //2. Judge the password. The user here is principal
        return new SimpleAuthenticationInfo(user,user.getPassword(),getName());
    }

}

It is divided into authentication and authorization

establish ShiroConfig.java

@Configuration
public class ShiroConfig {
    //Create shirofilterfactorybean
    @Bean
    public ShiroFilterFactoryBean getShiroFilterFactoryBean(@Qualifier("securityManager")DefaultWebSecurityManager securityManager) {
        ShiroFilterFactoryBean shiroFilterFactoryBean=new ShiroFilterFactoryBean();
        //Set up security manager
        shiroFilterFactoryBean.setSecurityManager(securityManager);
        //Add Shiro built in filter
        /**

        Map<String,String> filterMap = new LinkedHashMap<String,String>();
        //Configuration remembers the address that I can access through authentication or authentication
        filterMap.put("/testThymeleaf", "user");



        //Set release page
        filterMap.put("/testThymeleaf","anon");
        filterMap.put("/login","anon");

        //Authorization filter
        filterMap.put("/add","perms[user:add]");
        filterMap.put("/update","perms[user:update]");
        filterMap.put("/*", "authc");

        //After interception, jump to login.jsp , modify the jump page
        shiroFilterFactoryBean.setLoginUrl("/toLogin");
        //Set unauthorized prompt page.setUnauthorizedUrl("/noAuth");


        shiroFilterFactoryBean.setFilterChainDefinitionMap(filterMap);
        return shiroFilterFactoryBean;
    }

    //establishDefaultWebSecurityManager
    @Bean("securityManager")
    public DefaultWebSecurityManager getDefaultWebSecurityManager(@Qualifier("userRealm")UserRealm userRealm) {
        DefaultWebSecurityManager securityManager=new DefaultWebSecurityManager();
        //relationRealm
        securityManager.setRealm(userRealm);
        return securityManager;
    }
    //establishRealm
    @Bean(name="userRealm")
    public UserRealm getRealm() {
        return new UserRealm();
    }

    /**
    @Bean
    public ShiroDialect getShiroDialect(){
        return new ShiroDialect();
    }

    /**
     @Bean
     public SimpleCookie rememberMeCookie(){
       //System.out.println("ShiroConfiguration.rememberMeCookie()");
       //This parameter is the name of the cookie, corresponding to the name of the front-end checkbox = remember me
       SimpleCookie simpleCookie = new SimpleCookie("rememberMe");
       //<! -- remember that the effective time of my cookie is 30 days, in seconds; -- >
       simpleCookie.setMaxAge(259200);
       return simpleCookie;
     }

        /**
        @Bean
        public CookieRememberMeManager rememberMeManager(){
               //System.out.println("ShiroConfiguration.rememberMeManager()");
               CookieRememberMeManager cookieRememberMeManager = new CookieRememberMeManager();
               cookieRememberMeManager.setCookie(rememberMeCookie());
               //The key of rememberme cookie encryption is recommended to be different for each item. The key length of the default AES algorithm (128 256 512 bits)
               cookieRememberMeManager.setCipherKey(Base64.decode("2AvVhdsgUs0FSA3SDFAdag=="));
               return cookieRememberMeManager;
         }

}

Shirodialect works with the thymeleaf tag to display only the authorization page

establish test.html page

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org" xmlns:shiro="http://www.w3.org/1999/xhtml">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<h1 th:text="${title}"></h1>
<div shiro:hasPermission="user:add">Enter user add function:<a th:href="@{/add}">User add</a><br>
</div>
<div shiro:hasPermission="user:update">Enter the user update function:<a th:href="@{/update}">User update</a>
</div>
<a href="/toLogin">Sign in</a>
</body>
</html>

This work adoptsCC agreementReprint must indicate the author and the link of this article