1. 程式人生 > >Spring Boot 整合 Shiro實現許可權控制,親測可用,附帶sql

Spring Boot 整合 Shiro實現許可權控制,親測可用,附帶sql

前提:

本文主要講解Spring Boot 與 Shiro的整合 與許可權控制的實現方式(主要以程式碼實現功能為主),主要用到的技術Spring Boot+Shiro+Jpa(通過Maven構建),並不會涉及到Shiro框架的原始碼分析

如果有想要學習Shiro框架的小夥伴可以去http://shiro.apache.org/官網自行學習,並推薦一箇中文學習Shiro的網站https://www.sojson.com/shiro(感覺挺不錯的)

需求說明:

通過SpringBoot+Shiro實現使用者登入驗證,授權,對不同使用者角色訪問資源進行驗證,對使用者許可權訪問資源驗證,通過迭代加密方式提高使用者密碼的安全性

使用者 and 角色表關係 多對多

角色 and 許可權表關係 多對多

廢話不多說直接上程式碼:

此專案是Maven多模組專案 碼雲地址 https://gitee.com/h-java/springboot-parent-demo

小夥伴們程式碼裡的註釋我已經寫的很詳細了,所以部落格裡不做講解,直接看程式碼註釋講解就可以了

SQL檔案

 

/*
Navicat MySQL Data Transfer

Source Server         : localhost
Source Server Version : 50520
Source Host           : localhost:3306
Source Database       : shiro-demo

Target Server Type    : MYSQL
Target Server Version : 50520
File Encoding         : 65001

Date: 2018-11-15 16:59:02
*/ SET FOREIGN_KEY_CHECKS=0; -- ---------------------------- -- Table structure for hibernate_sequence -- ---------------------------- DROP TABLE IF EXISTS `hibernate_sequence`; CREATE TABLE `hibernate_sequence` ( `next_val` bigint(20) DEFAULT NULL ) ENGINE=MyISAM DEFAULT CHARSET=utf8; -- ---------------------------- -- Records of hibernate_sequence
-- ---------------------------- INSERT INTO `hibernate_sequence` VALUES ('4'); INSERT INTO `hibernate_sequence` VALUES ('4'); INSERT INTO `hibernate_sequence` VALUES ('4'); -- ---------------------------- -- Table structure for permission_t -- ---------------------------- DROP TABLE IF EXISTS `permission_t`; CREATE TABLE `permission_t` ( `id` int(11) NOT NULL, `name` varchar(255) DEFAULT NULL, PRIMARY KEY (`id`) ) ENGINE=MyISAM DEFAULT CHARSET=utf8; -- ---------------------------- -- Records of permission_t -- ---------------------------- INSERT INTO `permission_t` VALUES ('1', 'Retrieve'); INSERT INTO `permission_t` VALUES ('2', 'Create'); INSERT INTO `permission_t` VALUES ('3', 'Update'); INSERT INTO `permission_t` VALUES ('4', 'Delete'); -- ---------------------------- -- Table structure for role -- ---------------------------- DROP TABLE IF EXISTS `role`; CREATE TABLE `role` ( `id` int(11) unsigned NOT NULL AUTO_INCREMENT, `role` varchar(255) DEFAULT NULL, PRIMARY KEY (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8; -- ---------------------------- -- Records of role -- ---------------------------- INSERT INTO `role` VALUES ('1', 'user'); INSERT INTO `role` VALUES ('2', 'admin'); -- ---------------------------- -- Table structure for role_permission_t -- ---------------------------- DROP TABLE IF EXISTS `role_permission_t`; CREATE TABLE `role_permission_t` ( `pid` int(11) NOT NULL, `rid` int(11) NOT NULL, KEY `FKt2l638rvh84yplqqu7odiwhdx` (`rid`), KEY `FKh946y0ynuov5ynnrn024vapg9` (`pid`) ) ENGINE=MyISAM DEFAULT CHARSET=utf8; -- ---------------------------- -- Records of role_permission_t -- ---------------------------- INSERT INTO `role_permission_t` VALUES ('1', '1'); INSERT INTO `role_permission_t` VALUES ('1', '2'); INSERT INTO `role_permission_t` VALUES ('2', '2'); INSERT INTO `role_permission_t` VALUES ('3', '2'); INSERT INTO `role_permission_t` VALUES ('1', '3'); INSERT INTO `role_permission_t` VALUES ('2', '3'); INSERT INTO `role_permission_t` VALUES ('3', '3'); INSERT INTO `role_permission_t` VALUES ('4', '3'); -- ---------------------------- -- Table structure for role_t -- ---------------------------- DROP TABLE IF EXISTS `role_t`; CREATE TABLE `role_t` ( `id` int(11) NOT NULL, `role` varchar(255) DEFAULT NULL, PRIMARY KEY (`id`) ) ENGINE=MyISAM DEFAULT CHARSET=utf8; -- ---------------------------- -- Records of role_t -- ---------------------------- INSERT INTO `role_t` VALUES ('1', 'guest'); INSERT INTO `role_t` VALUES ('2', 'user'); INSERT INTO `role_t` VALUES ('3', 'admin'); -- ---------------------------- -- Table structure for user -- ---------------------------- DROP TABLE IF EXISTS `user`; CREATE TABLE `user` ( `id` int(11) unsigned NOT NULL AUTO_INCREMENT, `username` varchar(255) DEFAULT NULL, `password` varchar(255) DEFAULT NULL, `role` varchar(255) DEFAULT NULL, PRIMARY KEY (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8; -- ---------------------------- -- Records of user -- ---------------------------- INSERT INTO `user` VALUES ('1', 'howie', '123456', 'user'); INSERT INTO `user` VALUES ('2', 'swit', '123456789', 'admin'); -- ---------------------------- -- Table structure for user_role_t -- ---------------------------- DROP TABLE IF EXISTS `user_role_t`; CREATE TABLE `user_role_t` ( `rid` int(11) NOT NULL, `uid` bigint(20) NOT NULL, KEY `FKe6b6umcoegdbmjws9e9y0n2jj` (`uid`), KEY `FK8lhd80hb3gbdbvdmlkn2oyprl` (`rid`) ) ENGINE=MyISAM DEFAULT CHARSET=utf8; -- ---------------------------- -- Records of user_role_t -- ---------------------------- INSERT INTO `user_role_t` VALUES ('3', '2'); INSERT INTO `user_role_t` VALUES ('2', '1'); INSERT INTO `user_role_t` VALUES ('1', '3'); -- ---------------------------- -- Table structure for user_t -- ---------------------------- DROP TABLE IF EXISTS `user_t`; CREATE TABLE `user_t` ( `id` bigint(20) NOT NULL, `password` varchar(255) DEFAULT NULL, `salt` varchar(255) DEFAULT NULL, `username` varchar(255) DEFAULT NULL, PRIMARY KEY (`id`) ) ENGINE=MyISAM DEFAULT CHARSET=utf8; -- ---------------------------- -- Records of user_t -- ---------------------------- INSERT INTO `user_t` VALUES ('1', 'dd531568fac3d2338bdba66b46b39fd7', '73ee684dd5a07e3b9034b02dcebf4e7c', 'hly'); INSERT INTO `user_t` VALUES ('2', '7f5e269e2f52955a0bbdfdef19281fd4', 'c6dc702282fd467c2c5481617c45a014', 'dxl'); INSERT INTO `user_t` VALUES ('3', 'edec83e7318071af89c8811536fd0a68', 'be535103fe5f98c4cef83cf24ab0d11b', 'zy');
View Code

 

 

 

父POM檔案:

 1 <?xml version="1.0" encoding="UTF-8"?>
 2 <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 3     xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
 4     <modelVersion>4.0.0</modelVersion>
 5 
 6     <groupId>com.boot</groupId>
 7     <artifactId>springboot-parent-demo</artifactId>
 8     <version>0.0.1-SNAPSHOT</version>
 9     <packaging>pom</packaging>
10 
11     <name>springboot-parent-demo</name>
12     <description>Spring Boot Parent Demo</description>
13 
14     <parent>
15         <groupId>org.springframework.boot</groupId>
16         <artifactId>spring-boot-starter-parent</artifactId>
17         <version>2.0.5.RELEASE</version>
18         <relativePath/> <!-- lookup parent from repository -->
19     </parent>
20 
21     <!--編碼-->
22     <properties>
23         <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
24         <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
25         <java.version>1.8</java.version>
26     </properties>
27 
28     <!--子模組-->
29     <modules>
30         <module>sb-listener</module>
31         <module>sb-configration-file</module>
32         <module>sb-shiro</module>
33         <module>sb-shiro2</module>
34     </modules>
35 
36     <!-- 版本說明:這裡統一管理依賴的版本號 -->
37     <dependencyManagement>
38         <dependencies>
39             <dependency>
40                 <groupId>com.example</groupId>
41                 <artifactId>sb-listener</artifactId>
42                 <version>0.0.1-SNAPSHOT</version>
43             </dependency>
44         </dependencies>
45     </dependencyManagement>
46 
47     <!--父依賴-->
48     <dependencies>
49         <dependency>
50             <groupId>org.springframework.boot</groupId>
51             <artifactId>spring-boot-starter-thymeleaf</artifactId>
52         </dependency>
53         <dependency>
54             <groupId>org.springframework.boot</groupId>
55             <artifactId>spring-boot-starter-web</artifactId>
56         </dependency>
57 
58         <dependency>
59             <groupId>org.projectlombok</groupId>
60             <artifactId>lombok</artifactId>
61             <optional>true</optional>
62         </dependency>
63         <dependency>
64             <groupId>org.springframework.boot</groupId>
65             <artifactId>spring-boot-starter-test</artifactId>
66             <scope>test</scope>
67         </dependency>
68     </dependencies>
69 
70     <!--外掛依賴-->
71     <build>
72         <plugins>
73             <plugin>
74                 <groupId>org.springframework.boot</groupId>
75                 <artifactId>spring-boot-maven-plugin</artifactId>
76             </plugin>
77         </plugins>
78     </build>
79 
80 
81 </project>

子模組專案sb-shiro2的POM檔案:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.example</groupId>
    <artifactId>sb-shiro2</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <packaging>jar</packaging>

    <name>sb-shiro2</name>
    <description>Spring Boot Shiro Demo 2</description>

    <parent>
        <groupId>com.boot</groupId>
        <artifactId>springboot-parent-demo</artifactId>
        <version>0.0.1-SNAPSHOT</version>
    </parent>
    
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-jpa</artifactId>
        </dependency>
        <dependency>
            <groupId>org.apache.shiro</groupId>
            <artifactId>shiro-spring</artifactId>
            <version>1.4.0</version>
        </dependency>

        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid</artifactId>
            <version>1.0.19</version>
        </dependency>

        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>


</project>

 

 整體專案結構:

 

application.yml

server:
   port: 8088
spring:
   application:
      name: shiro
   datasource:
      url: jdbc:mysql://localhost:3306/shiro-demo
      username: root
      password: 123456
      driver-class-name: com.mysql.jdbc.Driver
   jpa:
      database: mysql
      showSql: true
      hibernate:
         ddlAuto: update
      properties:
         hibernate:
            dialect: org.hibernate.dialect.MySQL5Dialect
            format_sql: true
View Code

 

entity包

通過Jpa生成資料庫表

User類

package com.example.demo.entity;

import lombok.Data;

import javax.persistence.*;
import java.io.Serializable;
import java.util.List;

/**
 * Created by hly on 2018\11\14 0014.
 */
@Data
@Entity
@Table(name = "user_t") //資料庫生成的表名
public class User implements Serializable{

    private static final long serialVersionUID = 6469007496170509665L;
    /**
     * 使用者id
     */
    @Id
    @GeneratedValue
    private long id;
    /**
     * 使用者名稱
     */
    private String username;
    /**
     * 使用者密碼
     */
    private String password;
    /**
     * yan
     */
    private String salt;
    /**
     * 使用者表和角色表的多對多關聯
     */
    @ManyToMany(fetch = FetchType.EAGER)
    @JoinTable(name = "user_role_t",joinColumns = {@JoinColumn(name = "uid")},
            inverseJoinColumns = {@JoinColumn(name = "rid")})
    private List<SysRole> roles;

    /**
     * 對鹽進行再次加密
     * @return
     */
    public String getCredentialsSalt() {
        return username + salt + salt;
    }

}
View Code

 

 

SysRole類 

package com.example.demo.entity;

import lombok.Data;

import javax.persistence.*;
import java.io.Serializable;
import java.util.List;

/**
 * Created by hly on 2018\11\14 0014.
 */
@Data
@Entity
@Table(name = "role_t")
public class SysRole implements Serializable {

    private static final long serialVersionUID = 8215278487246865520L;
    /**
     * 角色id
     */
    @Id
    @GeneratedValue
    private Integer id;
    /**
     * 角色名稱
     */
    private String role;

    /**
     * 許可權與使用者的多對多關聯
     */
    @ManyToMany
    @JoinTable(name = "user_role_t",joinColumns = {@JoinColumn(name = "rid")},
            inverseJoinColumns = {@JoinColumn(name = "uid")})
    List<User> users;

    /**
     * 角色與許可權的多對多關聯
     */
    @ManyToMany(fetch = FetchType.EAGER)
    @JoinTable(name = "role_permission_t",joinColumns = {@JoinColumn(name = "rid")},
            inverseJoinColumns = {@JoinColumn(name = "pid")})
    List<SysPermission> permissions ;

}
View Code

 

 

SysPermission類

package com.example.demo.entity;

import lombok.Data;

import javax.persistence.*;
import java.io.Serializable;
import java.util.List;

/**
 * Created by hly on 2018\11\14 0014.
 */
@Data
@Entity
@Table(name = "role_t")
public class SysRole implements Serializable {

    private static final long serialVersionUID = 8215278487246865520L;
    /**
     * 角色id
     */
    @Id
    @GeneratedValue
    private Integer id;
    /**
     * 角色名稱
     */
    private String role;

    /**
     * 許可權與使用者的多對多關聯
     */
    @ManyToMany
    @JoinTable(name = "user_role_t",joinColumns = {@JoinColumn(name = "rid")},
            inverseJoinColumns = {@JoinColumn(name = "uid")})
    List<User> users;

    /**
     * 角色與許可權的多對多關聯
     */
    @ManyToMany(fetch = FetchType.EAGER)
    @JoinTable(name = "role_permission_t",joinColumns = {@JoinColumn(name = "rid")},
            inverseJoinColumns = {@JoinColumn(name = "pid")})
    List<SysPermission> permissions ;

}
View Code

 

mapper介面

package com.example.demo.dao;

import com.example.demo.entity.User;
import org.springframework.data.jpa.repository.JpaRepository;

/**
 * Created by hly on 2018\11\14 0014.
 */
public interface UserMapper extends JpaRepository<User,Long>{
    User findUserByUsername(String username);
}
View Code

 

UserService

package com.example.demo.service;

import com.example.demo.dao.UserMapper;
import com.example.demo.entity.User;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

/**
 * Created by hly on 2018\11\14 0014.
 */
@Service
public class UserService {

    @Autowired
    private UserMapper userMapper;

    public User findUserByName(String username){
        return userMapper.findUserByUsername(username);
    }

    public User saveUser(User user){
        return userMapper.save(user);
    }
}
View Code

 

Shiro包

ShiroConfig

package com.example.demo.shiro;

import org.apache.shiro.authc.credential.HashedCredentialsMatcher;
import org.apache.shiro.mgt.SecurityManager;
import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import java.util.HashMap;
import java.util.Map;

/**
 * Created by hly on 2018\11\14 0014.
 */
@Configuration
public class ShiroConfig {
    // shiro filter
    @Bean
    public ShiroFilterFactoryBean shirFilter(SecurityManager securityManager) {
        ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();
        shiroFilterFactoryBean.setSecurityManager(securityManager);

        Map<String, String> filterChainDefinitionMap = new HashMap<String, String>();
        //登入介面,沒有登入的使用者訪問授權的介面就會跳轉到該介面
        shiroFilterFactoryBean.setLoginUrl("/login");
        //沒有授權的資源,都可以訪問,使用者訪問授權的資源無許可權時跳轉到該介面
        shiroFilterFactoryBean.setUnauthorizedUrl("/unauthc");
        shiroFilterFactoryBean.setSuccessUrl("/home/index");
        //所有路徑都攔截
        filterChainDefinitionMap.put("/*", "anon");
        //授權資源,只有登入了才能訪問,並且有該對應許可權的使用者才可以訪問
        filterChainDefinitionMap.put("/authc/index", "authc");
        filterChainDefinitionMap.put("/authc/admin", "roles[admin]");
        filterChainDefinitionMap.put("/authc/renewable", "perms[Create,Update]");
        filterChainDefinitionMap.put("/authc/removable", "perms[Delete]");
        filterChainDefinitionMap.put("/authc/retrievable", "perms[Retrieve]");
        shiroFilterFactoryBean.setFilterChainDefinitionMap(filterChainDefinitionMap);
        System.out.println("shirFilter配置成功");
        return shiroFilterFactoryBean;
    }

    //授權管理者
    @Bean
    public SecurityManager securityManager() {
        DefaultWebSecurityManager  securityManager = new DefaultWebSecurityManager();
        securityManager.setRealm(shiroRealm());
        return securityManager;
    }
    //shiro realm
    @Bean
    public EnceladusShiroRealm shiroRealm() {
        EnceladusShiroRealm shiroRealm = new EnceladusShiroRealm();
        shiroRealm.setCredentialsMatcher(hashedCredentialsMatcher());
        return shiroRealm;
    }
    //設定演算法和迭代
    @Bean
    public HashedCredentialsMatcher hashedCredentialsMatcher() {
        HashedCredentialsMatcher hashedCredentialsMatcher = new HashedCredentialsMatcher();
        hashedCredentialsMatcher.setHashAlgorithmName(PasswordHelper.ALGORITHM_NAME);// 雜湊演算法
        hashedCredentialsMatcher.setHashIterations(PasswordHelper.HASH_ITERATIONS);// 雜湊次數
        return hashedCredentialsMatcher;
    }
    //密碼加密
    @Bean
    public PasswordHelper passwordHelper() {
        return new PasswordHelper();
    }
}
View Code

 

EnceladusShiroRealm

package com.example.demo.shiro;

import com.example.demo.entity.SysPermission;
import com.example.demo.entity.SysRole;
import com.example.demo.entity.User;
import com.example.demo.service.UserService;
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.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.apache.shiro.util.ByteSource;
import org.springframework.beans.factory.annotation.Autowired;

/**
 * Created by hly on 2018\11\14 0014.
 * shiro中使用者自定義登入驗證和授權認證的地方(realm)
 */
public class EnceladusShiroRealm extends AuthorizingRealm{

    @Autowired
    private UserService userService;

    /**
     * 授權認證
     * @param principal
     * @return
     */
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principal) {
        //負責裝載role和permission的物件
        SimpleAuthorizationInfo authorizationInfo = new SimpleAuthorizationInfo();
        //獲取使用者名稱
        String username = (String) principal.getPrimaryPrincipal();
        //獲取使用者
        User user = userService.findUserByName(username);
        //遍歷角色和許可權,並把名稱加入到authorizationInfo中
        for (SysRole role:user.getRoles()) {
            authorizationInfo.addRole(role.getRole());
            for(SysPermission permission:role.getPermissions()) {
                authorizationInfo.addStringPermission(permission.getName());
            }
        }
        return authorizationInfo;
    }

    /**
     * 登入驗證
     * @param token
     * @return
     * @throws AuthenticationException
     */
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
        //獲取使用者名稱
        String username = (String)token.getPrincipal();
        //查尋使用者
        User user = userService.findUserByName(username);
        //邏輯
        if (user == null) {
            return null;
        }
        //包裝物件(使用者名稱、密碼、使用者Salt、抽象類CachingRealm的getName())
        SimpleAuthenticationInfo authenticationInfo = new SimpleAuthenticationInfo(user.getUsername(),user.getPassword(),
                ByteSource.Util.bytes(user.getCredentialsSalt()),getName());
        System.out.println("getName():"+getName());
        //返回SimpleAuthenticationInfo物件
        return authenticationInfo;
    }
}
View Code

 

PasswordHelper

package com.example.demo.shiro;

import com.example.demo.entity.User;
import org.apache.shiro.crypto.RandomNumberGenerator;
import org.apache.shiro.crypto.SecureRandomNumberGenerator;
import org.apache.shiro.crypto.hash.SimpleHash;
import org.apache.shiro.util.ByteSource;

/**
 * Created by hly on 2018\11\14 0014.
 * 對密碼進行迭代加密,保證使用者密碼的安全
 */
public class PasswordHelper {
    //安全的隨機字元
    private RandomNumberGenerator randomNumberGenerator = new SecureRandomNumberGenerator();
    //演算法名稱
    public static final String ALGORITHM_NAME = "md5";
    //迭代次數
    public static final int HASH_ITERATIONS = 2;

    public void encryptPassword(User user) {
        //隨機字串作為使用者的Salt
        user.setSalt(randomNumberGenerator.nextBytes().toHex());
        //演算法、使用者密碼、使用者Salt、迭代次數
        String newPassword = new SimpleHash(ALGORITHM_NAME,user.getPassword(),
                ByteSource.Util.bytes(user.getCredentialsSalt()),HASH_ITERATIONS).toHex();
        //對使用者設定新密碼
        user.setPassword(newPassword);
    }


}
View Code

 

Controller包

AuthcController

package com.example.demo.controller;

import com.example.demo.entity.User;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.subject.Subject;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

/**
 * 驗證的介面
 */
@RestController
@RequestMapping("authc")
public class AuthcController {

    @GetMapping("index")
    public Object index() {
        Subject subject = SecurityUtils.getSubject();
        User user = (User) subject.getSession().getAttribute("user");
        return user.toString();
    }

    @GetMapping("admin")
    public Object admin() {
        return "Welcome Admin";
    }

    // delete
    @GetMapping("removable")
    public Object removable() {
        return "removable";
    }

    // creat & update
    @GetMapping("renewable")
    public Object renewable() {
        return "renewable";
    }

    @GetMapping("retrievable")
    public Object retrievable() {return "retrievable";}

}
View Code

 

HomeController

package com.example.demo.controller;

import com.example.demo.entity.User;
import com.example.demo.service.UserService;
import com.example.demo.shiro.PasswordHelper;
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.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

/**
 * 不驗證的介面
 */
@RestController
@RequestMapping
public class HomeController {

    @Autowired
    private UserService userService;

    @Autowired
    private PasswordHelper passwordHelper;

    @GetMapping("/login")
    public Object login() {
        return "Here is Login page";
    }

    @GetMapping("/unauthc")
    public Object unauthc() {
        return "Here is Unauthc page";
    }

    @GetMapping("doLogin")
    public Object doLogin(@RequestParam String username, @RequestParam String password) {
        UsernamePasswordToken token = new UsernamePasswordToken(username, password);
        Subject subject = SecurityUtils.getSubject();
        try {
            subject.login(token);
        } catch (IncorrectCredentialsException ice) {
            return "password error!";
        } catch (UnknownAccountException uae) {
            return "username error!";
        }

        User user = userService.findUserByName(username);
        subject.getSession().setAttribute("user", user);
        return "SUCCESS";
    }

    @GetMapping("/register")
    public Object register(@RequestParam String username, @RequestParam String password) {
        User user = new User();
        user.setUsername(username);
        user.setPassword(password);
        passwordHelper.encryptPassword(user);

        userService.saveUser(user);
        return "註冊使用者SUCCESS";
    }
}
View Code

 

之後執行專案通過rest介面測試

localhost:8088/login
localhost:8088/unauthc
localhost:8088/doLogin?username=hly&password=123
等等通過controller裡的介面進行執行測試就好了,看執行效果,我就不一一往下copy了