Spring Boot+Spring Security:基于MySQL数据库的身份认证和角色授权

说明

(1)JDK版本:1.8

(2)Spring Boot 2.0.6

(3)Spring Security 5.0.9

(4)Spring Data JPA 2.0.11.RELEASE

(5)hibernate5.2.17.Final

(6)MySQLDriver 5.1.47

(7)MySQL 8.0.12

 

需求缘起

       在前面使用的是内存数据库,本节使用MySQL数据库进行操作。

 

编码思路

       在《基于内存数据库的身份认证和角色授权》的代码转换为MySQL数据库的存储方式的话,非常的简单,只需要添加MySQL数据库的驱动包以及配置好数据源和JPA。

 

一、基于MySQL数据库的身份认证和角色授权

1.1 添加依赖

       在pom.xml文件中去掉hsqldb的依赖,然后添加mysql的依赖:

 


        mysql
        mysql-connector-java

 

 

1.2 添加配置信息

       在application.properties文件中添加配置信息:

 
spring.datasource.url = jdbc:mysql://localhost:3306/spring-security
spring.datasource.username = root
spring.datasource.password = root
spring.datasource.driverClassName = com.mysql.jdbc.Driver

# Specify the DBMS  
spring.jpa.database = MYSQL
# Show or not log for each sql query  
spring.jpa.show-sql = true
# Hibernate ddl auto (create, create-drop, update)  
spring.jpa.hibernate.ddl-auto = create-drop

 

1.3 启动测试

启动应用程序,成功的话可以看到数据库的数据:

Spring Boot+Spring Security:基于MySQL数据库的身份认证和角色授权_第1张图片

 

       按照之前的流程测试下,结果是一样的。到这里的话,我并没有做过多的编码,那么这么轻松从内存数据库转换到MySQL数据库,这就是框架给我们提供的便利。

 

二、数据库密码加密保存

       到这里基本的流程都是没有问题的,但是我们发现数据库的密码都是明文显示的,这个就要命了,那么数据库的密码怎么加密保存呢?其实也很简单,在初始化用户信息的时候,就进行加密就可以了,具体的操作如下:

2.1 修改DataInit

       修改DataInit类,注入PasswordEncoder,使用PasswordEncoder的encode方法对密码进行加密:

 

package com.kfit.permission.init;

import javax.annotation.PostConstruct;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;
import com.kfit.permission.bean.UserInfo;
import com.kfit.permission.bean.UserInfo.Role;
import com.kfit.permission.repository.UserInfoRepository;

@Service
public class DataInit {

    @Autowired 
    private UserInfoRepository userInfoRepository;

    @Autowired 
    private PasswordEncoder passwordEncoder;

    @PostConstruct
    public void dataInit() {

        UserInfo admin = new UserInfo();
        admin.setUsername("admin");
        admin.setPassword(passwordEncoder.encode("123"));
        admin.setRole(Role.admin);
        userInfoRepository.save(admin);


        UserInfo user = new UserInfo();
        user.setUsername("user");
        user.setPassword(passwordEncoder.encode("123"));
        user.setRole(Role.normal);
        userInfoRepository.save(user);
    }

}

 

2.2 修改CustomUserDetailService

       在添加用户的时候,已经加密了,那么在loadUserByUsername方法中返回的UserDetails就不需要再加密了,修改为如下:

 

package com.kfit.config;

import java.util.ArrayList;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.stereotype.Component;

import com.kfit.permission.bean.UserInfo;
import com.kfit.permission.service.UserInfoService;

@Component
public class CustomUserDetailService implements UserDetailsService{
    @Autowired
    private UserInfoService userInfoService;

    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        System.out.println("CustomUserDetailService.loadUserByUsername()");
        //通过username获取用户信息
        UserInfo userInfo = userInfoService.findByUsername(username);
        if(userInfo == null) {
            throw new UsernameNotFoundException("not found");
        }

        //定义权限列表.
        List authorities = new ArrayList<>();
        // 用户可以访问的资源名称(或者说用户所拥有的权限) 注意:必须"ROLE_"开头
        authorities.add(new SimpleGrantedAuthority("ROLE_"+userInfo.getRole().name()));

        User userDetails = new User(userInfo.getUsername(),userInfo.getPassword(),authorities);
        return userDetails;
    }

}

 

2.3 启动测试

       启动应用,查看数据库的用户信息:

Spring Boot+Spring Security:基于MySQL数据库的身份认证和角色授权_第2张图片

 

       此时看到的密码已经是加密的了,访问下如下的地址:

http://127.0.0.1:8080/hello/helloUser

输入账号user/123看是否可以正常登录吧。

 

三、其他

3.1 Mac下安装MySQL

       在Mac下安装MySQL常用的有两种方式,第一种方式就是下载官网的dmg文件,直接进行安装;第二种方式,就是命令方式,这里使用的是brew命令。

3.1.1 安装brew

       由于使用的是brew install mysql安装的mysql,所以需要先安装brew,安装指令如下:

$ruby -e "$(curl -fsSLhttps://raw.githubusercontent.com/Homebrew/install/master/install)"

 

3.1.2 安装mysql

       已经安装神奇brew的话,那么安装mysql就很简单了,安装指令如下:

$ brew install mysql

 

3.1.2 mysql启动指令

       Mysql启动指令:

$  mysql.server start

 

3.2 navicat连接MySQL8+时出现2059错误解决方法

3.2.1 原因分析

安装完数据库,使用select version()数据库版本是8.0.12的,在用navicat连接MySQL8+时会出现2059错误,,这是由于新版本的MySQL使用的是caching_sha2_password验证方式,但此时的navicat还没有支持这种验证方式。

3.2.2 解决方法

解决方法就是将验证方式改为以前版本(5.7及以下)使用的验证方式mysql_native_password。具体的验证方式可以查看默认数据库'mysql'中user表plugin字段。

在命令行中登录数据库时不会出现2059错误,在命令行中登录数据库,执行下面的命令:

$ ALTER USER 'root'@'localhost' IDENTIFIED WITHmysql_native_password BY 'password';

'password'是你想使用的验证密码。

    

3.2.2 解决方法二

       另外一种方法就是升级navicat到最新版本,最新版本已经支持新的密码验证方式了。

你可能感兴趣的:(SpringSecurity)