程序员scholar 程序员scholar
首页
  • Java 基础

    • JavaSE
    • JavaIO
    • JavaAPI速查
  • Java 高级

    • JUC
    • JVM
    • Java新特性
    • 设计模式
  • Web 开发

    • Servlet
    • Java网络编程
  • Web 标准

    • HTML
    • CSS
    • JavaScript
  • 前端框架

    • Vue2
    • Vue3
    • Vue3 + TS
    • 微信小程序
    • uni-app
  • 工具与库

    • jQuery
    • Ajax
    • Axios
    • Webpack
    • Vuex
    • WebSocket
    • 第三方登录
  • 后端与语言扩展

    • ES6
    • Typescript
    • node.js
  • Element-UI
  • Apache ECharts
  • 数据结构
  • HTTP协议
  • HTTPS协议
  • 计算机网络
  • Linux常用命令
  • Windows常用命令
  • SQL数据库

    • MySQL
    • MySQL速查
  • NoSQL数据库

    • Redis
    • ElasticSearch
  • 数据库

    • MyBatis
    • MyBatis-Plus
  • 消息中间件

    • RabbitMQ
  • 服务器

    • Nginx
  • Spring框架

    • Spring6
    • SpringMVC
    • SpringBoot
    • SpringSecurity
  • SpringCould微服务

    • SpringCloud基础
    • 微服务之DDD架构思想
  • 日常必备

    • 开发常用工具包
    • Hutoll工具包
    • IDEA常用配置
    • 开发笔记
    • 日常记录
    • 项目部署
    • 网站导航
    • 产品学习
    • 英语学习
  • 代码管理

    • Maven
    • Git教程
    • Git小乌龟教程
  • 运维工具

    • Docker
    • Jenkins
    • Kubernetes
  • 算法笔记

    • 算法思想
    • 刷题笔记
  • 面试问题常见

    • 十大经典排序算法
    • 面试常见问题集锦
关于
GitHub (opens new window)
首页
  • Java 基础

    • JavaSE
    • JavaIO
    • JavaAPI速查
  • Java 高级

    • JUC
    • JVM
    • Java新特性
    • 设计模式
  • Web 开发

    • Servlet
    • Java网络编程
  • Web 标准

    • HTML
    • CSS
    • JavaScript
  • 前端框架

    • Vue2
    • Vue3
    • Vue3 + TS
    • 微信小程序
    • uni-app
  • 工具与库

    • jQuery
    • Ajax
    • Axios
    • Webpack
    • Vuex
    • WebSocket
    • 第三方登录
  • 后端与语言扩展

    • ES6
    • Typescript
    • node.js
  • Element-UI
  • Apache ECharts
  • 数据结构
  • HTTP协议
  • HTTPS协议
  • 计算机网络
  • Linux常用命令
  • Windows常用命令
  • SQL数据库

    • MySQL
    • MySQL速查
  • NoSQL数据库

    • Redis
    • ElasticSearch
  • 数据库

    • MyBatis
    • MyBatis-Plus
  • 消息中间件

    • RabbitMQ
  • 服务器

    • Nginx
  • Spring框架

    • Spring6
    • SpringMVC
    • SpringBoot
    • SpringSecurity
  • SpringCould微服务

    • SpringCloud基础
    • 微服务之DDD架构思想
  • 日常必备

    • 开发常用工具包
    • Hutoll工具包
    • IDEA常用配置
    • 开发笔记
    • 日常记录
    • 项目部署
    • 网站导航
    • 产品学习
    • 英语学习
  • 代码管理

    • Maven
    • Git教程
    • Git小乌龟教程
  • 运维工具

    • Docker
    • Jenkins
    • Kubernetes
  • 算法笔记

    • 算法思想
    • 刷题笔记
  • 面试问题常见

    • 十大经典排序算法
    • 面试常见问题集锦
关于
GitHub (opens new window)
npm

(进入注册为作者充电)

  • SpringSecurity

    • Spring Security是什么
    • 认证与授权的基本概念
    • Spring Security 的默认配置
    • SpringSecurity的默认登录页
    • Spring Security 的 Filter 机制
    • HttpSecurity 与自定义登录页面
    • Spring Security 的核心组件与扩展
      • 1. UserDetails 与 UserDetailsService
        • 1.1 UserDetails 是什么?
        • 1.2 UserDetailsService 是什么?
      • 2. AuthenticationManager 与 AuthenticationProvider
        • 2.1 AuthenticationManager 是什么?
        • 2.2 AuthenticationProvider 是什么?
      • 3. PasswordEncoder 密码加密与解密
        • 3.1 PasswordEncoder 是什么?
    • Spring Security 中的用户认证与角色管理
    • Spring Security 的授权机制与安全表达式
    • Security 的 Session 与 Token 管理
    • Spring Security 集成第三方登录
    • Spring Security 集成 QQ 登录与 JWT 认证
    • Spring Security 登录认证源码
    • Spring Security - JWT认证实战
    • Spring Security - JWT授权实战
    • Spring Security 异常处理与自定义逻辑
  • SpringSecurity
  • SpringSecurity
scholar
2024-08-20
目录

Spring Security 的核心组件与扩展

# Spring Security 的核心组件与扩展

前言

Spring Security 的认证与授权体系主要由多个核心组件构成,其中包括 UserDetails、UserDetailsService、AuthenticationManager、AuthenticationProvider 以及 PasswordEncoder 等。在实际开发中,理解这些核心组件的工作原理以及如何扩展它们非常重要。

# 1. UserDetails 与 UserDetailsService

# 1.1 UserDetails 是什么?

UserDetails 是一个接口,用于封装用户的基本信息,包括用户名、密码、权限、账户是否过期、账户是否锁定等信息。Spring Security 使用它来进行认证和授权操作。

主要方法:

  • getUsername():获取用户名。
  • getPassword():获取密码。
  • getAuthorities():获取用户的权限(角色)。
  • isAccountNonExpired():检查账户是否未过期。
  • isAccountNonLocked():检查账户是否未锁定。
  • isCredentialsNonExpired():检查凭证(密码)是否未过期。
  • isEnabled():检查账户是否启用。

# 1.2 UserDetailsService 是什么?

UserDetailsService 是一个接口,用于从数据源(如数据库)中加载用户信息。开发者可以自定义该接口的实现,来定义如何从数据库或其他数据源中获取用户信息。

实现示例:

import org.springframework.beans.factory.annotation.Autowired;
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 CustomUserDetailsService implements UserDetailsService {

    @Autowired
    private UserRepository userRepository;  // 依赖注入用户数据源

    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        // 从数据库加载用户信息
        User user = userRepository.findByUsername(username);
        if (user == null) {
            throw new UsernameNotFoundException("用户未找到");
        }
        // 将数据库用户信息转换为 UserDetails 对象
        return new org.springframework.security.core.userdetails.User(
                user.getUsername(),              // 用户名
                user.getPassword(),              // 密码
                getAuthorities(user)             // 用户权限(角色)
        );
    }

    private Collection<? extends GrantedAuthority> getAuthorities(User user) {
        // 获取用户的角色并封装为 GrantedAuthority 对象
        return user.getRoles().stream()
                   .map(role -> new SimpleGrantedAuthority("ROLE_" + role.getName()))  // 添加 "ROLE_" 前缀
                   .collect(Collectors.toList());
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34

重要参数说明:

  • UserDetailsService:用于从数据源加载用户信息,是 Spring Security 进行认证的基础。
  • UsernameNotFoundException:当用户未找到时抛出此异常。
  • SimpleGrantedAuthority:用于封装用户权限(角色),通常结合 getAuthorities() 方法使用。

使用场景: 在需要从数据库或其他外部数据源加载用户信息时,通过实现 UserDetailsService 来集成 Spring Security 的认证逻辑。

# 2. AuthenticationManager 与 AuthenticationProvider

# 2.1 AuthenticationManager 是什么?

AuthenticationManager 是 Spring Security 的核心接口,负责管理所有的认证逻辑。当用户登录时,AuthenticationManager 会根据传入的认证请求进行认证操作,成功后返回认证信息。

工作原理:

  • AuthenticationManager 会将认证请求委托给多个 AuthenticationProvider,每个 AuthenticationProvider 负责处理不同类型的认证。
  • 默认的实现是 ProviderManager,它可以持有多个 AuthenticationProvider。

# 2.2 AuthenticationProvider 是什么?

AuthenticationProvider 是用于处理具体认证逻辑的接口。开发者可以自定义实现该接口,添加自定义的认证逻辑,如基于数据库、LDAP 等的认证。

实现示例:

import org.springframework.security.authentication.AuthenticationProvider;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Component;

@Component
public class CustomAuthenticationProvider implements AuthenticationProvider {

    @Autowired
    private UserDetailsService userDetailsService;

    @Autowired
    private PasswordEncoder passwordEncoder;

    @Override
    public Authentication authenticate(Authentication authentication) throws AuthenticationException {
        String username = authentication.getName();
        String password = (String) authentication.getCredentials();

        // 加载用户信息
        UserDetails userDetails = userDetailsService.loadUserByUsername(username);

        // 验证密码
        if (!passwordEncoder.matches(password, userDetails.getPassword())) {
            throw new BadCredentialsException("密码不正确");
        }

        // 返回认证成功后的 Authentication 对象
        return new UsernamePasswordAuthenticationToken(
                userDetails, 
                password, 
                userDetails.getAuthorities()
        );
    }

    @Override
    public boolean supports(Class<?> authentication) {
        return UsernamePasswordAuthenticationToken.class.isAssignableFrom(authentication);
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43

重要参数说明:

  • authenticate(Authentication authentication):负责处理具体的认证逻辑,如用户名和密码验证。
  • supports(Class<?> authentication):用于判断当前 AuthenticationProvider 是否支持指定的认证类型。

使用场景: 适用于需要自定义认证逻辑的场景,如整合第三方认证系统、自定义的数据库认证等。

# 3. PasswordEncoder 密码加密与解密

# 3.1 PasswordEncoder 是什么?

PasswordEncoder 是用于密码加密和解密的接口。Spring Security 提供了多种实现,如 BCryptPasswordEncoder、NoOpPasswordEncoder(不加密)等。

常用实现类:

  • BCryptPasswordEncoder:基于 BCrypt 加密算法,适合生产环境。
  • NoOpPasswordEncoder:不加密,仅适用于开发和测试。

配置示例:

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 SecurityConfig {

    @Bean
    public PasswordEncoder passwordEncoder() {
        return new BCryptPasswordEncoder();  // 使用 BCrypt 进行密码加密
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13

使用场景: 适用于任何涉及用户密码的场景,如用户注册、登录时的密码验证、密码重置等。

密码加密与验证:

@Autowired
private PasswordEncoder passwordEncoder;

// 加密密码
String encodedPassword = passwordEncoder.encode("rawPassword");

// 验证密码
boolean matches = passwordEncoder.matches("rawPassword", encodedPassword);
1
2
3
4
5
6
7
8

重要参数说明:

  • encode(String rawPassword):用于将明文密码加密。
  • matches(CharSequence rawPassword, String encodedPassword):用于验证明文密码与加密后的密码是否匹配。

总结

  • UserDetails 和 UserDetailsService:用于加载和封装用户信息,是 Spring Security 认证的核心。
  • AuthenticationManager 和 AuthenticationProvider:负责管理和处理认证逻辑,开发者可以通过自定义 AuthenticationProvider 来扩展认证方式。
  • PasswordEncoder:用于密码加密和解密,在生产环境中推荐使用如 BCryptPasswordEncoder 的安全加密方式。
编辑此页 (opens new window)
上次更新: 2024/12/28, 18:32:08
HttpSecurity 与自定义登录页面
Spring Security 中的用户认证与角色管理

← HttpSecurity 与自定义登录页面 Spring Security 中的用户认证与角色管理→

Theme by Vdoing | Copyright © 2019-2025 程序员scholar
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式