Spring Security是用于解决认证与授权的框架。
创建spring项目,添加依赖

<!-- Spring Boot Security:处理认证与授权 --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-security</artifactId></dependency>

如:

<?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 https://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><!-- 父级项目 --><parent><groupId>cn.tedu</groupId><artifactId>csmall-server</artifactId><version>0.0.1-SNAPSHOT</version></parent><!-- 当前项目的信息 --><groupId>cn.tedu</groupId><artifactId>csmall-passport</artifactId><version>0.0.1-SNAPSHOT</version><!-- 当前项目需要使用的依赖项 --><dependencies><!-- Spring Boot Web:支持Spring MVC --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><!-- Spring Boot Security:处理认证与授权 --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-security</artifactId></dependency><!-- Spring Boot Test:测试 --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId><scope>test</scope></dependency></dependencies></project>

调整完成后,即可启动项目,在启动的日志中,可以看到类似以下内容:

Using generated security password: 2abb9119-b5bb-4de9-8584-9f893e4a5a92

Spring Security有默认登录的账号和密码(以上提示的值),密码是随机的,每次启动项目都会不同。

Spring Security默认要求所有的请求都是必须先登录才允许的访问,可以使用默认的用户名user和自动生成的随机密码来登录。在测试登录时,在浏览器访问当前主机的任意网址都可以(包括不存在的资源),会自动跳转到登录页(是由Spring Security提供的,默认的URL是:http://localhost:8080/login),当登录成功后,会自动跳转到此前访问的URL(跳转登录页之前的URL),另外,还可以通过 http://localhost:8080/logout 退出登录。

Spring Security的依赖项中包括了Bcrypt算法的工具类,Bcrypt是一款非常优秀的密码加密工具,适用于对需要存储下来的密码进行加密处理。

public class BcryptPasswordEncoderTests {private BCryptPasswordEncoder passwordEncoder = new BCryptPasswordEncoder();@Testpublic void testEncode() {// 原文相同的情况,每次加密得到的密文都不同for (int i = 0; i < 10; i++) {String rawPassword = "123456";String encodedPassword = passwordEncoder.encode(rawPassword);System.out.println("rawPassword = " + rawPassword);System.out.println("encodedPassword = " + encodedPassword);}// rawPassword = 123456// encodedPassword = $2a$10$HWuJ9WgPazrwg9.isaae4u7XdP7ohH7LetDwdlTWuPC4ZAvG.Uc7W// encodedPassword = $2a$10$rOwgZMpDvZ3Kn7CxHWiEbeC6bQMGtfX.VYc9DCzx9BxkWymX6FbrS// encodedPassword = $2a$10$H8ehVGsZx89lSVHwBVI37OkxWm8LXei4T1o5of82Hwc1rD0Yauhky// encodedPassword = $2a$10$meBbCiHZBcYn7zMrZ4fPd.hizrsiZhAu8tmDk.P8QJcCzSQGhXSvq// encodedPassword = $2a$10$bIRyvV29aoeJLo6hh1M.yOvKoOud5kC7AXDMSUW4tF/DlcG0bLj9C// encodedPassword = $2a$10$eq5BuoAiQ6Uo0.TOPZOFPuRNlPl3t2GoTlaFoYfBu3/Bo3tLzx.v2// encodedPassword = $2a$10$DhTSwQfNdqrGgHRmILmNLeV0jt3ZXL435xz0fwyZ315ciI5AuI5gi// encodedPassword = $2a$10$T.8/ISoLOdreEEkp4py36O0ZYfihDbdHDuIElZVF3uEgMOX.8sPcK// encodedPassword = $2a$10$hI4wweFOGJ7FMduSmcjNBexbKFOjYMWl8hkug0n0k1LNR5vEyhhMW// encodedPassword = $2a$10$b4ztMI6tWoiJuoDYKwr7DOywsPkkCdvDxbPfmEsLdp11NdABS7wyy}@Testpublic void testMatches() {String rawPassword = "123456";String encodedPassword = "$2a$10$hI4wweFOGJ7FMduSmCjNBexbKFOjYMWl8hkug0n0k1LNR5vEyhhMW";boolean matchResult = passwordEncoder.matches(rawPassword, encodedPassword);System.out.println("match result : " + matchResult);}}

如果要使得Spring Security能使用数据库中的信息(数据库中的用户名与密码)来验证用户身份(认证),首先,必须实现“根据用户名查询此用户的登录信息(应该包括权限信息)”的查询功能,要实现此查询,需要执行的SQL语句大致是:

select    ams_admin.id,    ams_admin.username,    ams_admin.password,    ams_admin.is_enable,    ams_permission.value
from ams_admin
left join ams_admin_role on ams_admin.id = ams_admin_role.admin_id
left join ams_role_permission on ams_admin_role.role_id = ams_role_permission.role_id
left join ams_permission on ams_role_permission.permission_id = ams_permission.id
where username='root';

Spring Security的认证机制中包含:当客户端提交登录后,会自动调用UserDetailsService接口(Spring Security定义的)的实现类对象中的UserDetails loadUserByUsername(String username)方法(根据用户名加载用户数据),将得到UserDetails类型的对象,此对象中应该至少包括此用户名对应的密码、权限等信息,接下来,Spring Security会自动完成密码的对比,并确定此次客户端提交的信息是否允许登录!类似于:

// Spring Security的行为
UserDetails userDetails = userDetailsService.loadUserByUsername("chengheng");
// Spring Security将从userDetails中获取密码,用于验证客户端提交的密码,判断是否匹配

所以,要实现Spring Security通过数据库的数据来验证用户名与密码(而不是采用默认的user用户名和随机的密码),则在cn.tedu.csmall.passport包下创建security.UserDetailsServiceImpl类,实现UserDetailsService接口,并重写接口中的抽象方法:

package cn.tedu.csmall.passport.security;import cn.tedu.csmall.passport.mapper.AdminMapper;
import cn.tedu.csmall.pojo.vo.AdminLoginVO;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.BadCredentialsException;
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.Service;@Service
public class UserDetailsServiceImpl implements UserDetailsService {@Autowiredprivate AdminMapper adminMapper;@Overridepublic UserDetails loadUserByUsername(String s) throws UsernameNotFoundException {System.out.println("根据用户名查询尝试登录的管理员信息,用户名=" + s);AdminLoginVO admin = adminMapper.getLoginInfoByUsername(s);System.out.println("通过持久层进行查询,结果=" + admin);if (admin == null) {System.out.println("根据用户名没有查询到有效的管理员数据,将抛出异常");throw new BadCredentialsException("登录失败,用户名不存在!");}System.out.println("查询到匹配的管理员数据,需要将此数据转换为UserDetails并返回");UserDetails userDetails = User.builder().username(admin.getUsername()).password(admin.getPassword()).accountExpired(false).accountLocked(false).disabled(admin.getIsEnable() != 1).credentialsExpired(false).authorities(admin.getPermissions().toArray(new String[] {})).build();System.out.println("转换得到UserDetails=" + userDetails);return userDetails;}}

完成后,再配置密码加密器即可:

package cn.tedu.csmall.passport.config;import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;@Configuration
public class SecurityConfiguration {@Beanpublic PasswordEncoder passwordEncoder() {return new BCryptPasswordEncoder();}}

重启项目,可以发现在启动过程中不再生成随机的密码值,在浏览器上访问此项目的任何URL,进入登录页,即可使用数据库中的管理员数据进行登录。

在Spring Security,默认使用Session机制存储成功登录的用户信息(因为HTTP协议是无状态协议,并不保存客户端的任何信息,所以,同一个客户端的多次访问,对于服务器而言,等效于多个不同的客户端各访问一次,为了保存用户信息,使得服务器端能够识别客户端的身份,必须采取某种机制),当下,更推荐使用Token或相关技术(例如JWT)来解决识别用户身份的问题。

JWT = JSON Web Token,它是通过JSON格式组织必要的数据,将数据记录在票据(Token)上,并且,结合一定的算法,使得这些数据会被加密,然后在网络上传输,服务器端收到此数据后,会先对此数据进行解密,从而得到票据上记录的数据(JSON数据),从而识别用户的身份,或者处理相关的数据。

其实,在客户端第1次访问服务器端时,是“空着手”访问的,不会携带任何票据数据,当服务器进行响应时,会将JWT响应到客户端,客户端从第2次访问开始,每次都应该携带JWT发起请求,则服务器都会收到请求中的JWT并进行处理。

要使用JWT,需要添加相关的依赖项,可以实现生成JWT、解析JWT的框架较多,目前,主流的JWT框架可以是jjwt

<!-- https://mvnrepository.com/artifact/io.jsonwebtoken/jjwt -->
<dependency><groupId>io.jsonwebtoken</groupId><artifactId>jjwt</artifactId><version>0.9.1</version>
</dependency>

Spring Security关于用户身份认证与授权相关推荐

  1. shiro中的验证用户身份认证以及授权

    目录 1.运用shiro进行用户身份认证: 1.1导入基于Shiro的数据库脚本 1.2.引入依赖(shiro-1.4.1) shiro-core  shiro-web  shiro-spring 1 ...

  2. 结合 Authing 实现 AWS 云上的身份认证与授权

    身份认证与 Cognito 服务介绍 在 Web 或 App 开发过程中,用户的认证和权限处理是非常重要的一个模块,这里包括用户注册.登录认证及管理对应的权限.除了用户名密码登录外,通过第三方社交帐号 ...

  3. 3.Spring Security 自定义用户认证

    Spring Security自定义用户认证 自定义认证过程 自定义认证的过程需要实现Spring Security提供的UserDetailService接口,该接口只有一个抽象方法loadUser ...

  4. Spring Security使用数据库登录认证授权

    一.搭建项目环境 1.创建 RBAC五张表 RBAC,即基于角色的权限访问控制(Role-Based Access Control),就是用户通过角色与权限进行关联. 在这种模型中,用户与角色之间,角 ...

  5. Spring Security | 轻松搞定认证授权~

    文章目录 一.Spring Security 简介 二.整合 Spring Security 1.创建项目,导入依赖 2.创建数据库,搭建环境 3.配置数据库 4.创建实体类 5.实现 UserMap ...

  6. Spring Security OAuth2 微服务认证中心自定义授权模式扩展以及常见登录认证场景下的应用实战

    本文源码地址 后端:https://gitee.com/youlaitech/youlai-mall/tree/v2.0.1 前端:https://gitee.com/youlaiorg/mall-a ...

  7. HDFS权限管理、用户身份认证和数据访问授权、UGO权限管理、umask权限掩码、UGO权限相关命令、Web页面修改UGO权限

    HDFS权限管理 1.1 总览概述 作为分布式文件系统,HDFS也集成了一套兼容POSIX的权限管理系统.客户端在进行每次文件操时,系统会从用户身份认证和数据访问授权两个环节进行验证: 客户端的操作请 ...

  8. 构建具有用户身份认证的 Ionic 应用

    序言:本文主要介绍了使用 Ionic 和 Cordova 开发混合应用时如何添加用户身份认证.教程简易,对于 Ionic 入门学习有一定帮助.因为文章是去年发表,所以教程内关于 Okta 的一些使用步 ...

  9. Spring Security 集成 Authing CAS 认证(一)

    01 集成介绍 单点登录 (Single Sign On),英文名称缩写 SSO,意思是在多系统的环境中,登录单方系统,就可以无须再次登录,访问相关受信任的系统.也就是说,只要登录一次单体系统即可. ...

最新文章

  1. symfony2是什么?
  2. java 技术 管理_java技术转型产品或者项目管理,请大神指导?
  3. Java多线程分析案例
  4. Android性能测试-分析工具
  5. Lexer的设计--中(4)
  6. Spring SqlRowSet example--转载
  7. Android热更新方案Robust
  8. C++二叉搜索树(Binary Search Tree)(附完整源码)
  9. java代码轻量级锁_Java轻量级锁原理详解(Lightweight Locking)
  10. voc_eval.py:41: RuntimeWarning: invalid value encountered in greater_equal if np.sum(rec = t) ==
  11. 10.15 iptables filter表小案例10.16/10.17/10.18 iptables nat表应用
  12. python批量写入数据库engine_python 快速写入postgresql数据库方法
  13. C++程序运行时内存布局之--无继承情况下的虚函数
  14. Hibernate 学习(一)
  15. Redis 与 key 相关的常用命令
  16. 解决在Linux下安装Oracle时的中文乱码问题
  17. JavaWeb 利用jsp 实现分页查询
  18. 牛津大学教授Michael Wooldridge:AI社区40+年如何看待神经网络
  19. Serverless 极致弹性解构在线游戏行业痛点
  20. 实验吧-因缺思汀的绕过WriteUp

热门文章

  1. 计算机中级培训计划,2021年计算机操作员中级培训专项计划.doc
  2. 洛阳智能交通网络升级 辐射西部造福百姓
  3. Python3 读取中文文件txt编码问题
  4. Vue3二维码(QRCode)
  5. Java内存的一点理解, 静态方法和实例方法的区别及使用场景
  6. Nuxt3 简单集成 GoogleMap
  7. 微软Windows多媒体技术介绍
  8. 几何拓扑不变量——欧拉示性数
  9. C++ 系列:C++ 内存布局
  10. s5pv210开发板linux ac97 alsa驱动