最新Spring Security的基于内存用户认证方式

2025-07-28 20:50

本文主要是介绍最新Spring Security的基于内存用户认证方式,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

《最新SpringSecurity的基于内存用户认证方式》本文讲解SpringSecurity内存认证配置,适用于开发、测试等场景,通过代码创建用户及权限管理,支持密码加密,虽简单但不持久化,生产环...

1. 前言

又是新的一周,博主继续来给大家更新 Spring Security 实战教程了,在上一个章节中我们详细介绍了 Spring Security 的底层原理,本章节博主将带着大家介绍如何在 Spring Security 中实现基于内存的用户认证。

虽然 Spring Security 基于内存的用户认证,实际开发来说相对来说用的比较少,但某些场景下(如:开发阶段、原型验证、演示环境搭建、单元测试/集成测试、或甚至不需要数据库的简单系统),基于内存的用户认证方式就足以满足需求,为了应对这样需求,博主觉得还是要必要聊一聊基于内存的用户认证。

2. 因何选择内存认证?

就如前面说的场景,总结内存认证主要有以下几个优点:

  • 简单快捷:配置简单,不需要依赖数据库或外部存储,适用于快速构建和测试。
  • 易于调试:所有用户信息存储在代码中,方便开发过程中快速定位问题。
  • 适用于小型应用:对于用户数量较少的应用或者临时验证原型,内存认证是个不错的选择

当然,内存认证也有局限性:用户数据不持久化、无法扩展到分布式系统等。因此,在生产环境中,通常会采用基于数据库或其他外部认证机制的方式。

与数据库认证对比

特性内存认证数据库认证
用户存储位置应用内存持久化存储
用户管理灵活性配置硬编码动态增删改查
生产环境适用性不推荐推荐

3. 基础配置实战

接下来在之前的Maven项目中还是创建第三个子模块 memory-spring-security ,完整的maven项目结构如下:

最新Spring Security的基于内存用户认证方式

❶ 创建Spring Security配置文件

现在我们来创建一个Spring Security 配置文件 InMemorySecurityConfig

@Configurajstion
public class InMemorySecurityConfig {
    // 手动配置用户信息
    @Bean
    public UserDetailsService users() {
        UserDetails user = User.withUsername("user")
                .password("{noop}user") // {noop}表示不加密
                .roles("USER")
                .build();
        UserDetails admin = User.withUsername("admin")
                .password("{noop}admin")
                .roles("ADMIN")
                .build();
		//可以继续追加其它用户...
        UserDetails anonymous = User.withUsername("anonymous")
                .password("{noop}anonymous")
                .roles("ANONYMOUS")
                .build();
        return new InMemoryUserDetailsManager(user, admin, anonymous);
    }
    // 配置安全策略 并配置/admin/** 只允许ADMIN角色用户访问
    @Bean
    public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
        http.
   python             authorizeHttpRequests(authorize -> authorize
                        .requestMatchers("/admin/**").hasRole("ADMIN")
                        .anyRequest().authenticated()
                )
                .formLogin(withDefaults())
                .logout(withDefaults())
        ;
        return http.build();
    }
}

配置说明

  • 构建UserDetailsService
    创建两个用户信息分别是:admin、user ,并由InMemoryUserDetailsManager进行在内存中保存用户数据
  • SecurityFilterChain
    SecurityFilterChain中,默认采用了Spring Security表单登陆登出方式,并配置/admin/**请求路径下需要管理员角色方可访问

❷ 创建Controller测试

接下来我们创建用以测试的Controller :DemoMemoryController

@Controller
public class DemoMemoryController {
    //返回用户信息及角色权限
    @GetMapping("/")
    public ResponseEntity<Map<String, Object>> index(Authentication authentication) {
        String username = authentication.getName();//用户名
        Object principal =authentication.getPrincipal();//身份
        // 获取用户拥有的权限列表
        List<String> roles = authentication.getAuthorities().stream()
                .map(GrantedAuthority::getAuthority)
                .collect(Collectors.toList());
        //返回用户信息
        return ResponseEntity.ok(Map.of(
                "username", username,
                "principal", principal,
                "roles", roles));
    }
	//测试管理员权限
    @GetMapping("/admin/view")
    public ResponseEntity<String> admin() {
        return ResponseEntity.ok("管理员ADMIN角色访问ok");
    }
}

代码说明

  • 注入 Authentication 对象
    index 方法中,通过方法参数直接注入 Authentication 对象,Spring Security android会自动传入当前认证信息。
  • 提取用户信息
    通过 authentication.getName() 获取当前登录用户的用户名;通过 authentication.getAuthorities() 获取用户的权限列表,并将每个权限的 getAuthority() 值收集成一个字符串列表。

❸ 运行测试

启动项目访问,登陆页中分别测试两个用户登陆查看信息,如user用户:

最新Spring Security的基于内存用户认证方式

接下来尝试使用user用户访问 /admin/view 路径,会出现 403 访问错误提示:即您无权访问此地址

切换admin用户登陆,继续访问 /admin/view 路径,出现 管理员ADMIN角色访问ok 文字显示即代表管理员角色允许访问

4. 追加密码编码器

在上述代码中,我们使用了 password(“{nChina编程oop}admin”) 声明了密码明文存储,如果我们需要对密码加密,如何操作? 实际上 Spring Security 为我们提供了非常方便的密码编码器

密码编码器配置
只需要创建 PasswordEncoder Bean,并返回加密类型,如下代码样例:

@Bean
public PasswordEncoder passwordEncoder() {
    return new BCryptPasswordEncoder();
}
@Bean
public UserDetailsService users(PasswordEncoder encoder) {
    UserDetails user = User.builder()
            .username("user")
            .password(encoder.encode("secret"))
            .roles("USER")
            .build();
    return new InMemoryUserDetailsManager(user);
}

支持的编码格式:

# 不同前缀对应不同编码器
{noop} → NoOpPasswordEncoder (明文)
{bcrypt} → BCryptPasswordEncoder
{pbkdf2} → Pbkdf2PasswordEncoder
{scrypt} → SCryptPasswordEncoder
{sha256} → StandardPasswordEncoder

5. 总结

通过本章节的配置示例,相信你已经可以使用 Spring Security 的基于内存认证方式来快速搭建安全认证体系。

注意章节中提到的基于内存的用户认证适用的场景,更多情况下还是建议使用 更为健全的认证方式,如 基于数据库的认证、JWT 令牌认证或 OAuth2,在下一章节我们将重点讲述数据库的认证,敬请期待…

到此这篇关于最新Spring Security的基于内存用户认证方式的文章就介绍到这了,更多相关Spring Security内存用户认证内容请搜索China编程(www.chinasem.cn)以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程China编程(wwphpw.chinasem.cn)!

这篇关于最新Spring Security的基于内存用户认证方式的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1155510

相关文章

Java中流式并行操作parallelStream的原理和使用方法

《Java中流式并行操作parallelStream的原理和使用方法》本文详细介绍了Java中的并行流(parallelStream)的原理、正确使用方法以及在实际业务中的应用案例,并指出在使用并行流... 目录Java中流式并行操作parallelStream0. 问题的产生1. 什么是parallelS

Java中Redisson 的原理深度解析

《Java中Redisson的原理深度解析》Redisson是一个高性能的Redis客户端,它通过将Redis数据结构映射为Java对象和分布式对象,实现了在Java应用中方便地使用Redis,本文... 目录前言一、核心设计理念二、核心架构与通信层1. 基于 Netty 的异步非阻塞通信2. 编解码器三、

SpringBoot基于注解实现数据库字段回填的完整方案

《SpringBoot基于注解实现数据库字段回填的完整方案》这篇文章主要为大家详细介绍了SpringBoot如何基于注解实现数据库字段回填的相关方法,文中的示例代码讲解详细,感兴趣的小伙伴可以了解... 目录数据库表pom.XMLRelationFieldRelationFieldMapping基础的一些代

一篇文章彻底搞懂macOS如何决定java环境

《一篇文章彻底搞懂macOS如何决定java环境》MacOS作为一个功能强大的操作系统,为开发者提供了丰富的开发工具和框架,下面:本文主要介绍macOS如何决定java环境的相关资料,文中通过代码... 目录方法一:使用 which命令方法二:使用 Java_home工具(Apple 官方推荐)那问题来了,

Java HashMap的底层实现原理深度解析

《JavaHashMap的底层实现原理深度解析》HashMap基于数组+链表+红黑树结构,通过哈希算法和扩容机制优化性能,负载因子与树化阈值平衡效率,是Java开发必备的高效数据结构,本文给大家介绍... 目录一、概述:HashMap的宏观结构二、核心数据结构解析1. 数组(桶数组)2. 链表节点(Node

Java AOP面向切面编程的概念和实现方式

《JavaAOP面向切面编程的概念和实现方式》AOP是面向切面编程,通过动态代理将横切关注点(如日志、事务)与核心业务逻辑分离,提升代码复用性和可维护性,本文给大家介绍JavaAOP面向切面编程的概... 目录一、AOP 是什么?二、AOP 的核心概念与实现方式核心概念实现方式三、Spring AOP 的关

详解SpringBoot+Ehcache使用示例

《详解SpringBoot+Ehcache使用示例》本文介绍了SpringBoot中配置Ehcache、自定义get/set方式,并实际使用缓存的过程,文中通过示例代码介绍的非常详细,对大家的学习或者... 目录摘要概念内存与磁盘持久化存储:配置灵活性:编码示例引入依赖:配置ehcache.XML文件:配置

Java 虚拟线程的创建与使用深度解析

《Java虚拟线程的创建与使用深度解析》虚拟线程是Java19中以预览特性形式引入,Java21起正式发布的轻量级线程,本文给大家介绍Java虚拟线程的创建与使用,感兴趣的朋友一起看看吧... 目录一、虚拟线程简介1.1 什么是虚拟线程?1.2 为什么需要虚拟线程?二、虚拟线程与平台线程对比代码对比示例:三

Java中的.close()举例详解

《Java中的.close()举例详解》.close()方法只适用于通过window.open()打开的弹出窗口,对于浏览器的主窗口,如果没有得到用户允许是不能关闭的,:本文主要介绍Java中的.... 目录当你遇到以下三种情况时,一定要记得使用 .close():用法作用举例如何判断代码中的 input

Linux挂载linux/Windows共享目录实现方式

《Linux挂载linux/Windows共享目录实现方式》:本文主要介绍Linux挂载linux/Windows共享目录实现方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地... 目录文件共享协议linux环境作为服务端(NFS)在服务器端安装 NFS创建要共享的目录修改 NFS 配