Spring boot integrates Shiro and simple implementation

Posted by lizard on Tue, 26 Nov 2019 16:33:35 +0100

Spring boot integrates Shiro and simple implementation

Create a SpringBoot project

Create a little

Add dependency

1. Add thymeleaf

<!-- thymeleaf Dependent dependence -->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
<dependency>
    <groupId>com.github.theborakompanioni</groupId>
    <artifactId>thymeleaf-extras-shiro</artifactId>
    <version>2.0.0</version>
</dependency>

2. Add mybatis

<!-- mybatis Related dependence of -->
<dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>druid</artifactId>
    <version>1.0.27</version>
</dependency>
<dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
    <scope>runtime</scope>
</dependency>
<dependency>
    <groupId>org.mybatis.spring.boot</groupId>
    <artifactId>mybatis-spring-boot-starter</artifactId>
    <version>2.0.0</version>
</dependency>

Configure Shiro (key)

Create Shiro's configuration class ShiroConfig

  1. The @ coinfiguration annotation added to ShiroConfig COnfiguration class indicates that this is a COnfiguration class
  2. First, you need to configure three beans: ShiroFilterFactoryBean, defaultwebsecurity manager, UserRealm
  3. ShiroFilterFactoryBean depends on DefaultWebSecurityManager, DefaultWebSecurityManager depends on UserRealm
  4. Custom Realm: extends authorizing Realm, overriding two methods: doGetAuthorizationInfo(), doGetAuthenticationInfo(), that is, authorization and authentication

ShiroConfig.java

/**
 * shiro Configuration class
 */

@Configuration//Configuration class annotation
public class ShiroConfig {
    /**
     * Create ShiroFilterFactoryBean
     */
    @Bean
    public ShiroFilterFactoryBean getShiroFilterFactoryBean(DefaultWebSecurityManager securityManger){
        ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();
        //Set up security manager
        shiroFilterFactoryBean.setSecurityManager(securityManger);

        /**
         * shiro Built in filter for. Can implement the interceptor related to permissions
         * Common filters
         *  anon: Access without authentication (login)
         *  authc: Must be authenticated to access
         *  user: If you use the function of remeberme, you can directly access it
         *  perms: The resource must have resource permission to access
         *  role: The resource must have role permission to access
         */
        Map<String,String> filterMap = new LinkedHashMap<String,String>();
        filterMap.put("/add","authc");
        filterMap.put("/update","authc");
        filterMap.put("/tt","authc");
       // filterMap.put("/*","authc");
        //Authorize resources: custom characters in perms
        filterMap.put("/add","perms[user:add]");
        filterMap.put("/add","perms[user:update]");
        //Modify the default login jump page
        shiroFilterFactoryBean.setLoginUrl("/toLogin");
        //Modify the default unauthorized jump page
        shiroFilterFactoryBean.setUnauthorizedUrl("/noAuth");
        shiroFilterFactoryBean.setFilterChainDefinitionMap(filterMap);
        return shiroFilterFactoryBean;
    }

    /**
     * Create defaultwebsecuritymanager
     */
    @Bean
    public DefaultWebSecurityManager getDefaultWebSecurityManger(UserRealm userRealm){
        DefaultWebSecurityManager securityManger = new DefaultWebSecurityManager();
        //Correlation realm
        securityManger.setRealm(userRealm);
        return securityManger;
    }

    /**
     * Create Realm
     */
    @Bean("name=userRealm")//Add name to Spring container
    public UserRealm getRealm(){
        return new UserRealm();
    }
    /**
     * Configure shiro dialect, the use of user thmeleaf and shiro label
     */
    @Bean
    public ShiroDialect getShiroDialect(){
        return new ShiroDialect();
    }
  }

UserRealm.java

/**
 1. Custom Realm
 */
public class UserRealm extends AuthorizingRealm {
    @Autowired
    UserService userService;
    /**
     * Execute authorization logic
     * @param principalCollection
     * @return
     */
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
        System.out.println("shouquan");
        //Empower resources
        SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
        //Database query user authorization
        Subject subject = SecurityUtils.getSubject();
        User user = (User)subject.getPrincipal();//Return object in corresponding authentication
        //Add authorization string for resource
        info.addStringPermission(user.getPerms());//Get the user authorization information of the database
        return info;
    }

    /**
     * Execute authentication logic
     * @param authenticationToken
     * @return
     * @throws AuthenticationException
     */
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
        System.out.println("renzheng");
        //Write Shiro judgment logic to judge user name and password
        //1. Judge user name
        UsernamePasswordToken token = (UsernamePasswordToken)authenticationToken;
        User user = userService.findByName(token.getUsername());
        if(user == null){
            //user name does not exist
            return null;//The bottom layer of shiro will throw an unknowaccountexception
        }
        //2. Determine password
        return new SimpleAuthenticationInfo(user,user.getPassword(),"");

    }
}

Configure login logic

UserController.java

  1. subject.login(token) will inevitably call the authentication method in UserRealm
/**
 * Login logic processing
 */
@RequestMapping("/login")
public String login(String name ,String password ,Model model){
    /*
     * Using shiro to write authentication operations
     */
    //1. Get subject
    Subject subject = SecurityUtils.getSubject();
    //2. Encapsulate user data
    UsernamePasswordToken token = new UsernamePasswordToken(name,password);
    //3. Execute login method
    try{
        subject.login(token);
        //Login successfully
        //Jump to test.html
        return "redirect:/success";
    }catch (UnknownAccountException e){
        model.addAttribute("msg","user name does not exist");
        return "/toLogin";
    }catch (IncorrectCredentialsException e){
        model.addAttribute("msg","Incorrect password");
        return "/toLogin";
    }
}

toLogin.html

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.w3.org/1999/xhtml">
<head>
    <meta charset="UTF-8">
    <title>Page login</title>
</head>
<body>
<h3 th:text="${msg}" style="color: red;"></h3>
<form method="post" action="/login">
    User name:<input type="text" name="name"/></br>
    Password:<input type="password" name="password"/></br>
    <input type="submit" value="Sign in"/>
</form>
</body>
</html>

Configuration authorization

Authorization goes directly to UserRealm to query permissions. The authorized menu will be displayed on the page first. Now Shiro dialect is configured in Shiro config to display whether it is displayed through shiro:hasPermission = "custom permission".
text.html

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.w3.org/1999/xhtml" xmlns:shiro="http://www.w3.org/1999/xhtml">
<head>
    <meta charset="UTF-8"/>
    <title>test Thymeleaf</title>
</head>
<body>    
    <div shiro:hasPermission="user:add">
        Enter the user add function:<a href="add">User add</a></br>
    </div>
    <div shiro:hasPermission="user:update">
        Enter the user add function:<a href="update">User update</a>
    </div>
</body>
</html>

Topics: Programming Shiro Spring Thymeleaf Mybatis