本文来说下Spring Security:基于MySQL数据库的身份认证和角色授权 。本文为了上手简单,只用了一张user表。

文章目录

  • 概述
  • 创建项目
  • 基于数据库的身份认证
  • 本文小结

概述

需求缘起

在前面我们使用基于内存的方式体验了下Spring Security,在实际项目中,都是需要数据库进行操作的。

编码思路

本节使用MySQL数据库进行操作,需要添加MySQL数据库的驱动包以及配置好数据源和mybatis。


创建项目

创建一个 SpringBoot 模块项目,选择相关依赖:


先搭建项目正常访问,在pom.xml中,先把Spring Security依赖注释

创建一张用户表,并且在里面添加两条数据

在MySQL数据库中创建一张用户表,id主键自增,并添加两个用户如下:

create database Security;use Security;drop table if exists user;create table user
(id       int auto_increment primary key comment '用户ID',username varchar(20) comment '用户名字',password varchar(100) comment '用户密码(加密后的)',role     varchar(10) comment '用户角色(可以把这个抽出来,因为一个用户可能不止一个角色)'
);insert into user (username, password, role)
VALUES ('root', '123456', 'root'),('admin', '123456', 'admin');

创建pojo实体类

创建一个创建pojo实体类

package cn.wideth.entity.security;import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;@Data
@NoArgsConstructor
@AllArgsConstructor
public class UserInfo {private int id;private String username;private String password;private String role;
}

创建UserMapper接口

package cn.wideth.mapper;import cn.wideth.entity.security.UserInfo;
import org.apache.ibatis.annotations.Param;
import org.springframework.stereotype.Repository;@Repository
public interface UserMapper {//通过用户名查询用户UserInfo getUserByName(@Param("username") String username);}

创建UserMapper.xml文件

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" ><mapper namespace="cn.wideth.mapper.UserMapper"><select id="getUserByName" resultType="cn.wideth.entity.security.UserInfo">select * from user where username = #{username}</select></mapper>

创建IUserService

package cn.wideth.service;import cn.wideth.entity.security.UserInfo;public interface IUserService {UserInfo getUserByName(String username);
}

创建UserServiceImpl

package cn.wideth.service.impl;import cn.wideth.entity.security.UserInfo;
import cn.wideth.mapper.UserMapper;
import cn.wideth.service.IUserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;@Service
public class UserServiceImpl implements IUserService {@Autowiredprivate UserMapper userMapper;@Overridepublic UserInfo getUserByName(String username) {return userMapper.getUserByName(username);}
}

配置application.yml文件

server:port: 9090spring:datasource:driver-class-name: com.mysql.cj.jdbc.Driverurl: jdbc:mysql://localhost:3306/security?serverTimezone=Asia/Shanghai&useUnicode=true&characterEncoding=UTF-8username: rootpassword: we18256987759
#  redis:
#    host: localhost
#    port: 6379profiles:include: configmybatis:config-location: classpath:mybatis/mybatis-config.xmlmapper-locations: classpath:mybatis/mapper/*.xmluser:name: admin

编写UserController

package cn.wideth.controller;import cn.wideth.entity.security.UserInfo;
import cn.wideth.service.IUserService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
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("/api/user")
@Api(description = "权限测试", tags = "权限测试")
public class UserController {@Autowiredprivate IUserService iUserService;@GetMapping("/getUser")@ApiOperation(value = "用户权限测试接口", notes = "用户权限测试接口")public UserInfo getUser(@RequestParam String username) {return iUserService.getUserByName(username);}
}

启动项目,进行测试

访问http://localhost:9090/api/user/getUser?username=root


基于数据库的身份认证

把pom.xml中的Spring Security依赖注释去掉

出现默认的登录页面

自定义LoginUserDetailsService

自定义一个UserDetailsService,取名为LoginUserDetailService,该类需要实现接口UserDetailsService,主要是实现loadUserByUsername方法

package cn.wideth.config;import cn.wideth.entity.security.UserInfo;
import cn.wideth.service.IUserService;
import lombok.extern.slf4j.Slf4j;
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.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Component;
import java.util.ArrayList;
import java.util.List;/**** 该类需要实现接口UserDetailsService,* 主要是实现loadUserByUsername方法:* 用来加载用户保存在数据库中的登录信息*/
@Component
@Slf4j
public class LoginUserDetailService implements UserDetailsService {@Autowiredprivate IUserService iUserService;@Autowiredprivate PasswordEncoder passwordEncoder;@Overridepublic UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {log.info("用户的登录信息被加载了");//通过username获取用户信息UserInfo userInfo = iUserService.getUserByName(username);log.info("数据库中保存的用户信息" + userInfo);if(userInfo == null) {throw new UsernameNotFoundException("not found");}//定义权限列表.List<GrantedAuthority> authorities = new ArrayList<>();// 用户可以访问的资源名称(或者说用户所拥有的权限) 注意:必须"ROLE_"开头authorities.add(new SimpleGrantedAuthority("ROLE_"+userInfo.getRole()));//注意这里的user为security内置的用户类型,类型为org.springframework.security.core.userdetails.UserUser userDetails = new User(userInfo.getUsername(),passwordEncoder.encode(userInfo.getPassword()),authorities);log.info(userDetails.toString());return userDetails;}}

说明:

(1) 通过username获取用户的信息。
 
(2) 定义一个User(实现了接口UserDetails)对象,返回用户的username,passowrd和权限列表。
 
(3) 需要注意,定义角色集的时候,需要添加前缀“ROLE_”。
 
(4) 这里的密码需要使用PasswordEncoder进行加密,否则会报“无效的凭证”。

配置SecurityConfig

package cn.wideth.config;import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;/*** Security配置*/
@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {@Autowiredprivate LoginUserDetailService loginUserDetailService;/*** 强散列哈希加密实现*/@Beanpublic PasswordEncoder passwordEncoder() {return new BCryptPasswordEncoder();}/*** 身份认证接口*/@Overrideprotected void configure(AuthenticationManagerBuilder auth) throws Exception {// 从数据库读取的用户进行身份认证auth.userDetailsService(loginUserDetailService).passwordEncoder(passwordEncoder());}}

启动项目,进行测试

输入数据库中不存在的用户名或者密码,无法登录


输入正确的用户名和密码,可以登录


本文小结

本文简单介绍了Spring Security,基于MySQL数据库的身份认证,后面会在此基础之上进行详细的后续知识介绍。

Spring Security:基于MySQL数据库的身份认证相关推荐

  1. emq auth mysql_EMQ X 认证鉴权(一)——基于 MySQL 的 MQTT 连接认证

    前言 安全保护几乎对于所有的项目都是一个挑战,对于物联网项目更是如,自普及应用以来物联网业内已经发生过多起安全事故. 作为物联网通信协议事实标准,MQTT 保持着较高的安全性,提供了多层次的安全设计: ...

  2. emqx接通mysql_EMQ X 认证鉴权(一)——基于 MySQL 的 MQTT 连接认证

    前言 安全保护几乎对于所有的项目都是一个挑战,对于物联网项目更是如,自普及应用以来物联网业内已经发生过多起安全事故. 作为物联网通信协议事实标准,MQTT 保持着较高的安全性,提供了多层次的安全设计: ...

  3. 实现账号在一端登入_跟我学spring security 基于数据库实现一个基本的登入登出...

    第一章我们基于内存中的用户信息实现了一个基本的登入功能,不过实际的项目中用户信息一般都是存在数据库中的.本章我们来实现一个比较接近真实项目的登入登出,同时引入UserDetailsService的概念 ...

  4. idea查询类_Spring Security入门(三): 基于自定义数据库查询的认证实战

    0 引言 在笔者的上一篇文章中Spring Security入门(二):基于内存的认证一文中有提到过Spring Security实现自定义数据库查询需要你实现UserDetailsService接口 ...

  5. Spring全家桶-Spring Security之自定义数据库表认证和鉴权

    Spring全家桶-Spring Security之自定义数据库表认证和鉴权 Spring Security是一个能够为基于Spring的企业应用系统提供声明式的安全访问控制解决方案的安全框架.它提供 ...

  6. 数据库与身份认证(数据库的基本概念,安装并配置 MySQL,MySQL 的基本使用,在项目中操作 MySQL,前后端的身份认证)

    theme: channing-cyan 数据库与身份认证 1. 数据库的基本概念 1.1 什么是数据库 数据库(database)是用来组织.存储和管理数据的仓库. 当今世界是一个充满着数据的互联网 ...

  7. Springboot + Spring Security 实现前后端分离登录认证及权限控制

    Spring Security简介 Spring Security 是 Spring 家族中的一个安全管理框架,实际上,在 Spring Boot 出现之前,Spring Security 就已经发展 ...

  8. 如何使用Java和XML Config在Spring Security中启用HTTP基本身份验证

    在上一篇文章中,我向您展示了如何在Java应用程序中启用Spring安全性 ,今天我们将讨论如何使用Spring Security 在Java Web应用程序中启用Basic HTTP身份验证 . 如 ...

  9. 使用Spring Security对RESTful服务进行身份验证

    1.概述 本文重点介绍如何针对提供安全服务的安全REST API进行身份验证 -主要是RESTful用户帐户和身份验证服务. 2.目标 首先,让我们看一下参与者-典型的启用了Spring Securi ...

最新文章

  1. 对于神经网络,硕博士不需要弄明白原理,只需要应用,是这样吗?
  2. 重要的事情说三遍!网站如何改版才能最大限度降低影响率?
  3. python 如果你的年龄大于18_python基础
  4. No PIL installation found INFO:superset.utils.screenshots:No PIL installation found
  5. 在MATLAB function中可变的变量数据类型
  6. c语言面试题大汇总之华为面试题,计算机c语言面试题大汇总之华为面试题6.doc...
  7. ssl初一组周六模拟赛【2018.3.24】
  8. 93. Restore IP Addresses 1
  9. java计算器如何实现运算_用java编写了一个模拟计算器的界面设计,怎么实现运算功能呢...
  10. zTree节点增删改
  11. Shell: 文本文件操作
  12. 翻译 - 元编程动态方法之public_send
  13. Python Compiling Environment (Anaconda+VS code+GitKraken+Github)
  14. 数据中心201812-4
  15. 耳挂式蓝牙耳机原理_专为运动而生的DOSS T63无线蓝牙耳挂式运动耳机
  16. 【转】VNode节点
  17. 【读书笔记】-《软件测试的艺术》
  18. 保研至暗时,九推可能是你最后的机会!
  19. chrome js 读取文件夹_javascript – 如何从chrome扩展程序读取文件?
  20. Java由浅入深,考试or面试专用(自我整理)

热门文章

  1. 用Mindjet MindManager 15 打开文件后停止响应的解决方法
  2. python3.4学习笔记(二十一) python实现指定字符串补全空格、前面填充0的方法
  3. 人魔比妖都恶的时代...
  4. 端口映射原理,公网,内网,NA
  5. Bash(Shell)基础知识
  6. webpack 热加载你站住,我对你好奇很久了
  7. 浅析android应用增量升级
  8. 常见错误:未能加载文件或程序集
  9. 用AJAX编写一个简单的相册
  10. kubeadm部署K8S集群并使用containerd做容器运行时