首页IT科技springboot+security+jwt(springboot3 security 从始至终–02 PasswordEncoder)

springboot+security+jwt(springboot3 security 从始至终–02 PasswordEncoder)

时间2025-08-04 18:43:14分类IT科技浏览4608
导读:接下来几个章节,将逐个介绍身份验证流程中主要接口 接口 描述 UserDetails 代表SpringSecurity所看到的用户 GrantedAuthority 定义应用程序目的范围内允许用户执行的操作(读、写、删...

接下来几个章节              ,将逐个介绍身份验证流程中主要接口

接口 描述 UserDetails 代表SpringSecurity所看到的用户 GrantedAuthority 定义应用程序目的范围内允许用户执行的操作(读             、写                    、删除等) UserDetailsService 表示用于按用户名检索用户详细信息的对象 UserDetailsManager 一个较为特殊的UserDetailsService接口             。除了按用户名检索用户外                     ,它还可以用于更改用户集合或特定用户 PasswordEncoder 指定如何对密码进行加密或哈希化      ,以及检查给定的已编码字符串是由与明文密码匹配

本文将一起学习相对独立的PasswordEncoder                    。

一        、先看看定义

package org.springframework.security.crypto.password; /** * Service interface for encoding passwords. * * The preferred implementation is {@code BCryptPasswordEncoder}. * * @author Keith Donald */ public interface PasswordEncoder { /** * Encode the raw password. Generally, a good encoding algorithm applies a SHA-1 or * greater hash combined with an 8-byte or greater randomly generated salt. */ String encode(CharSequence rawPassword); /** * Verify the encoded password obtained from storage matches the submitted raw * password after it too is encoded. Returns true if the passwords match, false if * they do not. The stored password itself is never decoded. * @param rawPassword the raw password to encode and match * @param encodedPassword the encoded password from storage to compare with * @return true if the raw password, after encoding, matches the encoded password from * storage */ boolean matches(CharSequence rawPassword, String encodedPassword); /** * Returns true if the encoded password should be encoded again for better security, * else false. The default implementation always returns false. * @param encodedPassword the encoded password to check * @return true if the encoded password should be encoded again for better security, * else false. */ default boolean upgradeEncoding(String encodedPassword) { return false; } }

该接口定义了两个抽象方法          ,其中几个具有默认实现        。在处理PasswordEncoder实现时                      ,最常见的是抽象的encode()和matches()方法          。

encode(CharSequence rawPassword)方法的目的是返回所提供字符串的转换                   。就SpringSecurity功能而言         ,它用于为指定密码提供加密或哈希化            。

之后可以使用matches(CharSequence rawPassword, String encodedPassword)方法检查已编码的字符串是否与演示密码匹配       。可以在身份验证过程中使用matches()方法根据一组已知凭据来检验所提供的的密码                  。

第三个方法被称为upgradeEncoding(String encodedPassword)      ,在接口中默认设置为false               。如果重写它以返回true,那么为了更好的安全性                      ,将重新对已编码的密码进行编码(不推荐这种方式)    。

二          、接口的作用

一般而言            ,系统并不以明文形式管理密码   ,因此密码通常要经过某种转换                      ,这使得读取和窃取密码变得较为困难                   。为此                ,SpringSecurity定义了一个单独的接口                  。

实现这个接口是为了告知SpringSecurity如何验证用户的密码。在身份验证过程中,PasswordEncoder会判定密码是否有效                。每个系统都会存储以某种方式编码过的密码                     。最好把密码哈希化存储起来                  ,这样别人就不会读到明文密码了    。PasswordEncoder还可以对密码进行编码             。接口声明的encode()和matches()方式实际上是对其职责的定义                    。这两个方法都是同一接口的一部分                    ,因此它们紧密相连        。应用程序对密码进行编码的方式与验证密码的方式相关          。

三                   、实现PasswordEncoder

3.1 使用默认的PasswordEncoder

在 Spring Security 5.0 之前   ,PasswordEncoder 默认值是 NoOpPasswordEncoder              ,这需要纯文本密码                   。 但现在您可能期望现在的默认值类似于BCryptPasswordEncoder            。但是                     ,这忽略了三个现实世界的问题:

许多应用程序使用无法轻松迁移的旧密码编码       。 密码存储的最佳做法将再次更改                  。 作为一个框架      ,Spring 安全性不能经常进行重大更改               。

相反          ,Spring Security 引入了 DelegatingPasswordEncoder                      ,它通过以下方式解决了所有问题:

确保使用当前密码存储建议对密码进行编码 允许以现代和传统格式验证密码 允许将来升级编码

您可以使用PasswordEncoderFactories轻松构造DelegatingPasswordEncoder 的实例:

PasswordEncoder passwordEncoder = PasswordEncoderFactories.createDelegatingPasswordEncoder();

当然也可以选择其它实例:

String idForEncode = "bcrypt"; Map encoders = new HashMap<>(); encoders.put(idForEncode, new BCryptPasswordEncoder()); encoders.put("noop", NoOpPasswordEncoder.getInstance()); encoders.put("pbkdf2", Pbkdf2PasswordEncoder.defaultsForSpringSecurity_v5_5()); encoders.put("pbkdf2@SpringSecurity_v5_8", Pbkdf2PasswordEncoder.defaultsForSpringSecurity_v5_8()); encoders.put("scrypt", SCryptPasswordEncoder.defaultsForSpringSecurity_v4_1()); encoders.put("scrypt@SpringSecurity_v5_8", SCryptPasswordEncoder.defaultsForSpringSecurity_v5_8()); encoders.put("argon2", Argon2PasswordEncoder.defaultsForSpringSecurity_v5_2()); encoders.put("argon2@SpringSecurity_v5_8", Argon2PasswordEncoder.defaultsForSpringSecurity_v5_8()); encoders.put("sha256", new StandardPasswordEncoder()); PasswordEncoder passwordEncoder = new DelegatingPasswordEncoder(idForEncode, encoders); 3.2 使用自定义的的PasswordEncoder

通常情况下         ,使用spring boot security自带的password encoder已经足够满足使用场景了    。笔者也不建议自己实现password encoder                   。

3.3 注入PasswordEncoder

在开发中      ,我们将 BCryptPasswordEncoder 的实例放入Spring容器即可

//密码编码器 @Bean public PasswordEncoder passwordEncoder() { return new BCryptPasswordEncoder(); }

创心域SEO版权声明:以上内容作者已申请原创保护,未经允许不得转载,侵权必究!授权事宜、对本内容有异议或投诉,敬请联系网站管理员,我们将尽快回复您,谢谢合作!

展开全文READ MORE
kb4579311安装失败(KB4509476安装失败怎么办) opencv库(openCV第三篇)