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

Authentication: Sometimes called “login”, this is the act of proving that a user is who they say they are. Authorization: The process of determining “who” has access to “what”. Session Manager: Manages user-specific sessions, even in non-Web or EJB applications. Cryptography: The use of cryptographic algorithms to keep data secure while still being easy to use.

Three core components: Subject, SecurityManager, and Realms

Subject: indicates the current user. However, in Shiro, the concept of Subject does not just refer to people. It can also be a third-party process, a Daemon Account, or something similar. It simply means “what is currently interacting with the software.” Subject represents the security actions of the current user, and SecurityManager manages the security actions of all users. SecurityManager: It is the core of Shiro’s framework, a typical Facade pattern through which Shiro manages internal component instances and provides various services for security management. Realm: Realm acts as a “bridge” or “connector” between Shiro and application security data. That is, when authenticating a user (login) and authenticating a user (access control), Shiro looks up the user and their permission information from an application-configured Realm.

To briefly introduce the process, you need to import the dependencies first

<dependency>
    <groupId>org.apache.shiro</groupId>
    <artifactId>shiro-spring</artifactId>
    <version>1.5.0</version>
</dependency>
Copy the code

Import the following dependencies if Thymeleaf needs to integrate Shiro

<dependency>
    <groupId>com.github.theborakompanioni</groupId>
    <artifactId>thymeleaf-extras-shiro</artifactId>
    <version>2.0.0</version>
</dependency>
Copy the code

Custom realm

package com.hzy.config;

import com.hzy.pojo.User;
import com.hzy.service.UserService;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.*;
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;

// Customize a realm
public class UserRealm extends AuthorizingRealm {
    @Autowired
    private UserService userService;
    / / certification
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
        System.out.println("Certification");
        UsernamePasswordToken token = (UsernamePasswordToken) authenticationToken;
        User user = userService.queryUserByName(token.getUsername());
        if (user == null) {
            return null;
        }

        Subject currentSubject = SecurityUtils.getSubject();
        currentSubject.getSession().setAttribute("loginUser",user);
        // Password authentication shiro does

        return new SimpleAuthenticationInfo(user,user.getPassword(),"");
    }

    / / authorization
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
        System.out.println("Authorization");
        SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
        // info.addStringPermission("user:add");

        // Get the current user's object
        Subject subject = SecurityUtils.getSubject();
        User currentUser = (User) subject.getPrincipal(); // Get the user object
        // Set the permissions of the current user
        info.addStringPermission(currentUser.getPerms());
        returninfo; }}Copy the code

ShiroConfig

package com.hzy.config;

import at.pollux.thymeleaf.shiro.dialect.ShiroDialect;
import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import java.util.LinkedHashMap;
import java.util.Map;

@Configuration
public class ShiroConfig {
    //ShiroFilterFactoryBean
    @Bean
    public ShiroFilterFactoryBean getShiroFilterFactoryBean (@Qualifier("securityManager") DefaultWebSecurityManager defaultWebSecurityManager ) {
        ShiroFilterFactoryBean bean = new ShiroFilterFactoryBean();
        // Set the security manager
        bean.setSecurityManager(defaultWebSecurityManager);
        // Add shiro built-in filters
        /* * anno: access without authentication * authC: access with authentication * user: access with remember me function * perms: access with permission for a resource * role: access with permission for a role * */

        / / intercept
        Map<String,String> filterMap = new LinkedHashMap<>();
        / / authorization
        filterMap.put("/user/add"."perms[user:add]");
        filterMap.put("/user/update"."perms[user:update]");
        //filterMap.put("/user/*","authc");

       bean.setFilterChainDefinitionMap(filterMap);

        // Set the login request
        bean.setLoginUrl("/toLogin");
        // Unauthorized page
        bean.setUnauthorizedUrl("/noauth");
        return bean;
    }

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

    // Create realm objects
    @Bean
    public UserRealm userRealm(a) {
        return new UserRealm();
    }

    ShiroDialect: used to integrate Shiro and Thymeleaf
    @Bean
    public ShiroDialect getShiroDialect(a) {
        return newShiroDialect(); }}Copy the code

MyController

package com.hzy.controller;

import org.apache.catalina.security.SecurityUtil;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.IncorrectCredentialsException;
import org.apache.shiro.authc.UnknownAccountException;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.subject.Subject;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

@Controller
public class MyController {
    @RequestMapping({"/","/index"})
    public String index(Model model) {
        model.addAttribute("msg"."hello shiro");
        return "index";
    }

    @RequestMapping("/user/add")
    public String add(a) {
        return "user/add";
    }
    @RequestMapping("/user/update")
    public String update(a) {
        return "user/update";
    }

    @RequestMapping("/toLogin")
    public String toLogin(a){
        return "login";
    }

    @RequestMapping("/login")
    public String login(String username,String password, Model model) {
        // Get the current user
        Subject subject = SecurityUtils.getSubject();
        // Encapsulate user login data
        UsernamePasswordToken token = new UsernamePasswordToken(username, password);
        try {
            subject.login(token);

            return "index";
        }catch (UnknownAccountException e) {
            model.addAttribute("msg"."User name does not exist");
            return "login";
        }catch (IncorrectCredentialsException e) {
            model.addAttribute("msg"."Password error");
            return "login"; }}@RequestMapping("/noauth")
    @ResponseBody
    public String unauthorized(a) {
        return "This page cannot be accessed without authorization"; }}Copy the code

Effect demo, different users will see different interface

The home page is a login link

Different login users will see different screens