最新Spring Security实战教程(四)基于内存的用户认证

最新Spring Security实战教程(四)基于内存的用户认证
在这里插入图片描述
🌷 古之立大事者,不惟有超世之才,亦必有坚忍不拔之志
🎐 个人CSND主页——Micro麦可乐的博客
🐥《Docker实操教程》专栏以最新的Centos版本为基础进行Docker实操教程,入门到实战
🌺《RabbitMQ》专栏主要介绍使用JAVA开发RabbitMQ的系列教程,从基础知识到项目实战
🌸《设计模式》专栏以实际的生活场景为案例进行讲解,让大家对设计模式有一个更清晰的理解
💕《Jenkins实战》专栏主要介绍Jenkins+Docker的实战教程,让你快速掌握项目CI/CD,是2024年最新的实战教程
🌞《Spring Boot》专栏主要介绍我们日常工作项目中经常应用到的功能以及技巧,代码样例完整
🌞《Spring Security》专栏中我们将逐步深入Spring Security的各个技术细节,带你从入门到精通,全面掌握这一安全技术
如果文章能够给大家带来一定的帮助!欢迎关注、评论互动~

最新Spring Security实战教程(四)基于内存的用户认证 - UserDetailsService实战开发

回顾链接:
最新Spring Security实战教程(一)初识Spring Security安全框架
最新Spring Security实战教程(二)表单登录定制到处理逻辑的深度改造
最新Spring Security实战教程(三)Spring Security 的底层原理解析

1. 前言

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

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

2. 因何选择内存认证?

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

  • 简单快捷:配置简单,不需要依赖数据库或外部存储,适用于快速构建和测试。
  • 易于调试:所有用户信息存储在代码中,方便开发过程中快速定位问题。
  • 适用于小型应用:对于用户数量较少的应用或者临时验证原型,内存认证是个不错的选择
当然,内存认证也有局限性:用户数据不持久化、无法扩展到分布式系统等。因此,在生产环境中,通常会采用基于数据库或其他外部认证机制的方式。

与数据库认证对比

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

3. 基础配置实战

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

❶ 创建Spring Security配置文件

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

@ConfigurationpublicclassInMemorySecurityConfig{// 手动配置用户信息@BeanpublicUserDetailsServiceusers(){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();returnnewInMemoryUserDetailsManager(user, admin, anonymous);}// 配置安全策略 并配置/admin/** 只允许ADMIN角色用户访问@BeanpublicSecurityFilterChainfilterChain(HttpSecurity http)throwsException{ http.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

@ControllerpublicclassDemoMemoryController{//返回用户信息及角色权限@GetMapping("/")publicResponseEntity<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());//返回用户信息returnResponseEntity.ok(Map.of("username", username,"principal", principal,"roles", roles));}//测试管理员权限@GetMapping("/admin/view")publicResponseEntity<String>admin(){returnResponseEntity.ok("管理员ADMIN角色访问ok");}}

代码说明

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

❸ 运行测试

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

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

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

4. 追加密码编码器

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

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

@BeanpublicPasswordEncoderpasswordEncoder(){returnnewBCryptPasswordEncoder();}@BeanpublicUserDetailsServiceusers(PasswordEncoder encoder){UserDetails user =User.builder().username("user").password(encoder.encode("secret")).roles("USER").build();returnnewInMemoryUserDetailsManager(user);}

支持的编码格式:

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

5. 总结

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

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

如果本本章内容对您有所帮助,希望一键三连给博主一点点鼓励,如果您有任何疑问或建议,请随时留言讨论!


下一章节:最新Spring Security实战教程(五)基于数据库的动态认证 - UserDetailsService实战开发

Read more

MySQL 安装配置(完整教程)

MySQL 安装配置(完整教程)

文章目录 * 一、MySQL 简介 * 二、下载 MySQL * 三、安装 MySQL * 四、配置环境变量 * 五、配置 MySQL * 5.1 初始化 MySQL * 5.2 搭建 MySQL 环境 * 六、修改 MySQL 密码 * 七、卸载 MySQL * 八、结语 一、MySQL 简介 MySQL 是一款广泛使用的开源关系型数据库管理系统(RDBMS),由瑞典 MySQL AB 公司开发,目前属于 Oracle 公司旗下产品。 发展历史: * MySQL 于 1995

By Ne0inhk
大数据新视界 -- Impala 性能优化:分布式环境中的优化新视野(下)(28 / 30)

大数据新视界 -- Impala 性能优化:分布式环境中的优化新视野(下)(28 / 30)

💖💖💖亲爱的朋友们,热烈欢迎你们来到 青云交的博客!能与你们在此邂逅,我满心欢喜,深感无比荣幸。在这个瞬息万变的时代,我们每个人都在苦苦追寻一处能让心灵安然栖息的港湾。而 我的博客,正是这样一个温暖美好的所在。在这里,你们不仅能够收获既富有趣味又极为实用的内容知识,还可以毫无拘束地畅所欲言,尽情分享自己独特的见解。我真诚地期待着你们的到来,愿我们能在这片小小的天地里共同成长,共同进步。💖💖💖 本博客的精华专栏: 1. 大数据新视界专栏系列:聚焦大数据,展技术应用,推动进步拓展新视野。 2. Java 大厂面试专栏系列:提供大厂面试的相关技巧和经验,助力求职。 3. Python 魅力之旅:探索数据与智能的奥秘专栏系列:走进 Python 的精彩天地,感受数据处理与智能应用的独特魅力。 4. Java 性能优化传奇之旅:铸就编程巅峰之路:如一把神奇钥匙,深度开启 JVM 等关键领域之门。丰富案例似璀璨繁星,引领你踏上编程巅峰的壮丽征程。 5. Java 虚拟机(

By Ne0inhk
Flutter for OpenHarmony 实战:Hive CE — 极速 NoSQL 本地存储

Flutter for OpenHarmony 实战:Hive CE — 极速 NoSQL 本地存储

欢迎加入开源鸿蒙跨平台社区:https://openharmonycrossplatform.ZEEKLOG.net 前言 在 Flutter for OpenHarmony 应用开发中,数据持久化是构建流畅体验的核心基石。无论是用户的登录状态、应用主题偏好,还是海量的离线缓存数据,都需要一套既快速又可靠的存储方案。 传统的 SQLite 虽然功能强大,但在处理简单的键值对(Key-Value)时往往显得过于沉重。Hive CE (Community Edition) 凭借其纯 Dart 编写、读写性能卓越的优势,成为了鸿蒙开发者的首选。本文将结合鸿蒙插件适配的最佳实践,带你构建一个工业级的加密存储方案。 一、Hive CE 的底层优势解析 1.1 纯 Dart 的并行优势 Hive 完全由 Dart 实现。在鸿蒙系统上,这意味着它避开了复杂的 JNI 调用开销。

By Ne0inhk