前提:

本文主要讲解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文件

 




CodeSys 字符 codesys 字符串为中文_CodeSys 字符

CodeSys 字符 codesys 字符串为中文_CodeSys 字符_02

/*
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>



 

 整体项目结构:

CodeSys 字符 codesys 字符串为中文_测试_03

 

application.yml




CodeSys 字符 codesys 字符串为中文_CodeSys 字符

CodeSys 字符 codesys 字符串为中文_CodeSys 字符_02

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类




CodeSys 字符 codesys 字符串为中文_CodeSys 字符

CodeSys 字符 codesys 字符串为中文_CodeSys 字符_02

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类 




CodeSys 字符 codesys 字符串为中文_CodeSys 字符

CodeSys 字符 codesys 字符串为中文_CodeSys 字符_02

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类




CodeSys 字符 codesys 字符串为中文_CodeSys 字符

CodeSys 字符 codesys 字符串为中文_CodeSys 字符_02

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接口




CodeSys 字符 codesys 字符串为中文_CodeSys 字符

CodeSys 字符 codesys 字符串为中文_CodeSys 字符_02

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




CodeSys 字符 codesys 字符串为中文_CodeSys 字符

CodeSys 字符 codesys 字符串为中文_CodeSys 字符_02

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




CodeSys 字符 codesys 字符串为中文_CodeSys 字符

CodeSys 字符 codesys 字符串为中文_CodeSys 字符_02

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




CodeSys 字符 codesys 字符串为中文_CodeSys 字符

CodeSys 字符 codesys 字符串为中文_CodeSys 字符_02

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




CodeSys 字符 codesys 字符串为中文_CodeSys 字符

CodeSys 字符 codesys 字符串为中文_CodeSys 字符_02

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




CodeSys 字符 codesys 字符串为中文_CodeSys 字符

CodeSys 字符 codesys 字符串为中文_CodeSys 字符_02

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




CodeSys 字符 codesys 字符串为中文_CodeSys 字符

CodeSys 字符 codesys 字符串为中文_CodeSys 字符_02

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了