返回顶部
首页 > 资讯 > 后端开发 > Python >Spring Security PasswordEncoder密码加密实现过程讲解
  • 840
分享到

Spring Security PasswordEncoder密码加密实现过程讲解

Spring Security PasswordEncoderSpring Security密码加密 2023-01-03 09:01:30 840人浏览 八月长安

Python 官方文档:入门教程 => 点击学习

摘要

目录PassWordEncoder注入BSryptPasswordEncoder实例BSryptPasswordEncoder详解父接口PasswordEncoderBSryptPa

PasswordEncoder

PasswordEncoder是spring Security框架默认使用的密码加密器,对应的数据表sys_user的密码password字段需要以明文存储,并且要加上前缀{noop}password,否则就会抛出异常java.lang.IllegalArgumentException: There is no PasswordEncoder mapped for the id "null"(如下图所示),这样使用起来是极其不方便的,但是,Spring Security也允许我们自己替换这个默认使用的PasswordEncoder

注入BSryptPasswordEncoder实例

在实际开发中,我们一般使用spring security框架中提供的BSryptPasswordEncoder

因此,只需要将BSryptPasswordEncoder对象注入到Spring容器中,Spring Security就会使用该对象替换掉默认使用的PasswordEncoder对象,来进行密码校验。

所以,接下来的工作,就是定义一个SpringSecurityConfig配置类(SpringSecurity框架要求这个配置类需要继承WEBSecurityConfigureAdapter)。示例代码如下,

package com.xwd.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
@Configuration
public class SpringSecurityConfig extends WebSecurityConfigurerAdapter {
    //properties
    //methods
    
    @Bean
    public PasswordEncoder getBCryptPasswordEncoder(){
        return new BCryptPasswordEncoder();
    }
}

BSryptPasswordEncoder详解

父接口PasswordEncoder

PasswordEncoderSpring Security框架默认使用的密码加密器。但是Spring Security框架也提供了多个具体的实现子类(如上图所示)。


public interface PasswordEncoder {
    ...
}

其中,Spring Security框架源码中建议:在开发中,首选BCryptPasswordEncoder进行使用。

public interface PasswordEncoder {
	
	String encode(CharSequence rawPassword);
	
	boolean matches(CharSequence rawPassword, String encodedPassword);
	
	default boolean upgradeEncoding(String encodedPassword) {
		return false;
	}
}

PasswordEncoder接口中只提供了3个待实现的抽象方法(源码如上),分别如下,

String encode(CharSequence rawPassword);

密码加密:通常地,一个好的加密算法可以是`SHA-1`或者更大的hash与8字节、或者更大的随机生成盐的组合。

boolean matches(CharSequence rawPassword, String encodedPassword);

其中:rawPassword对应用户提交的密码;encodedPassword对应正确密码编码后得到的字符串。 密码校验:校验密码编码后的字符串,与用户登录时提交的密码是否匹配,返回一个boolean布尔值表示是否校验通过。

default boolean upgradeEncoding(String encodedPassword) {

return false;

}

如果为了更好的安全性,应当对一次编码后的密码进行二次编码,返回一个boolean值标识是否进行了二次编码。

BSryptPasswordEncoder及其使用

成员方法

BCryptPasswordEncoderPasswordEncoder的实现子类:使用了BCrypt强散列函数。客户端可以选择性的提供一个版本号(version,可选值:$2a, $2b, $2y)和一个加密强度(strength,可选值:a.k.a. log rounds in BCrypt),以及一个SecureRandom实例。

strength加密强度默认值为10,值越大,安全性就越可靠。

除了对PasswordEncoder接口提供的3个方法做了实现之外,也提供了用于获取加密盐的方法getSalt()

	private String getSalt() {
		if (this.random != null) {
			return BCrypt.gensalt(this.version.getVersion(), this.strength, this.random);
		}
		return BCrypt.gensalt(this.version.getVersion(), this.strength);
	}

SecurityUtils安全服务工具类

在实际开发中使用时,面向密码加密、密码匹配两项操作,参考若依框架中:SecurityUtils安全服务工具类的写法,摘录代码如下,

PS:可以看到,BCryptPasswordEncoder类在使用时,主要还是调用密码加密方法encode()、密码匹配/校验方法matchesPassword()。

 
    public static String encryptPassword(String password)
    {
        BCryptPasswordEncoder passwordEncoder = new BCryptPasswordEncoder();
        return passwordEncoder.encode(password);
    }
    
    public static boolean matchesPassword(String rawPassword, String encodedPassword)
    {
        BCryptPasswordEncoder passwordEncoder = new BCryptPasswordEncoder();
        return passwordEncoder.matches(rawPassword, encodedPassword);
    }

测试代码

@SpringBootTest
@RunWith(SpringRunner.class)
public class SpringBoot_Demo_Test {
    //properties
    @Autowired
    @Qualifier(value = "BCryptPasswordEncoder") //Bean实例注入已经在本部分开头进行介绍
    private PasswordEncoder passwordEncoder;
    //methods
    @Test
    public void BCryptPasswordEncoder_test(){
        
        String encode = passwordEncoder.encode("123456");//密码加密操作-将加密之后的结果存储到数据库中
        String encode1 = passwordEncoder.encode("123456");
        System.out.println(encode); // $2a$10$J0HqjTj2g98KceRapnRqW.Y4uQkPzGASFstgx1yba2JQG1muHj7L2
        System.out.println(encode1); //$2a$10$foxH4yrARWiaWwxyTXjFMOkSqkiOXsMaiQ6/oWbxxond5/BZqi1ke
        
        boolean matches = passwordEncoder.matches("123456", "$2a$10$foxH4yrARWiaWwxyTXjFMOkSqkiOXsMaiQ6/oWbxxond5/BZqi1ke");
        System.out.println("检验结果:"+matches); //检验结果:true
    }
}

到此这篇关于Spring Security PasswordEncoder密码加密实现过程讲解的文章就介绍到这了,更多相关Spring Security PasswordEncoder内容请搜索编程网以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程网!

--结束END--

本文标题: Spring Security PasswordEncoder密码加密实现过程讲解

本文链接: https://lsjlt.com/news/176427.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

猜你喜欢
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作