• Spring Security 密码编码


    本页将介绍 Spring Security 密码编码示例。在 Spring Security 中,PasswordEncoder实现了该接口以提供不同类型的密码编码器,例如Argon2PasswordEncoderBCryptPasswordEncoder。在 Spring Security 5.0 中,默认密码编码器是DelegatingPasswordEncoder

    要在 中配置密码编码器DaoAuthenticationProvider,它提供了setPasswordEncoder方法。
    对于 LDAP 身份验证提供程序,我们可以使用passwordEncoder以下内部类的方法。

    LdapAuthenticationProviderConfigurer.PasswordCompareConfigurer 

    在 XML 配置中,要使用密码编码器,请为密码编码器创建一个 bean,并使用元素内的元素对其进行分配。
    在此页面上,我们将通过示例讨论使用不同类型的密码编码器。


     


     

    使用的技术

    找出我们示例中使用的技术。
    1.Java 11
    2.Spring 5.2.1.RELEASE 3.Spring
    Boot 2.2.1.RELEASE 4.Maven
    3.5.2

    密码编码器

    Spring Security 提供PasswordEncoder的接口具有不同的密码编码实现。有以下PasswordEncoder方法。
    1.

    String encode(CharSequence rawPassword) 

    编码原始密码。
    2.

    boolean  matches(CharSequence rawPassword, String encodedPassword) 

    验证编码的密码。
    3.

    default boolean	 upgradeEncoding(String encodedPassword) 

    检查编码的密码是否应该再次编码。

    找到PasswordEncoder接口的实现。
    1. Argon2PasswordEncoder, 2. BCryptPasswordEncoder
    3. DelegatingPasswordEncoder, 4. LdapShaPasswordEncoder
    5. Md4PasswordEncoder, 6. MessageDigestPasswordEncoder
    7. NoOpPasswordEncoder, 8. Pbkdf2PasswordEncoder
    9. SCryptPasswordEncoder, 10. StandardPasswordEncoder

    找到使用不同密码编码器显示编码和匹配密码的测试类。
    PasswordEncoderTest.java

    1. package com.concretepage;
    2. import static org.junit.jupiter.api.Assertions.assertTrue;
    3. import org.junit.jupiter.api.Test;
    4. import org.junit.jupiter.api.extension.ExtendWith;
    5. import org.springframework.security.crypto.argon2.Argon2PasswordEncoder;
    6. import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
    7. import org.springframework.security.crypto.factory.PasswordEncoderFactories;
    8. import org.springframework.security.crypto.password.PasswordEncoder;
    9. import org.springframework.security.crypto.password.Pbkdf2PasswordEncoder;
    10. import org.springframework.security.crypto.scrypt.SCryptPasswordEncoder;
    11. import org.springframework.test.context.ContextConfiguration;
    12. import org.springframework.test.context.junit.jupiter.SpringExtension;
    13. @ExtendWith(SpringExtension.class)
    14. @ContextConfiguration
    15. public class PasswordEncoderTest {
    16. @Test
    17. public void testBCrypt() {
    18. BCryptPasswordEncoder encoder = new BCryptPasswordEncoder();
    19. String result = encoder.encode("ram123");
    20. assertTrue(encoder.matches("ram123", result));
    21. }
    22. @Test
    23. public void testArgon2() {
    24. Argon2PasswordEncoder encoder = new Argon2PasswordEncoder();
    25. String result = encoder.encode("ram123");
    26. assertTrue(encoder.matches("ram123", result));
    27. }
    28. @Test
    29. public void testPbkdf2() {
    30. Pbkdf2PasswordEncoder encoder = new Pbkdf2PasswordEncoder();
    31. String result = encoder.encode("ram123");
    32. assertTrue(encoder.matches("ram123", result));
    33. }
    34. @Test
    35. public void testSCrypt() {
    36. SCryptPasswordEncoder encoder = new SCryptPasswordEncoder();
    37. String result = encoder.encode("ram123");
    38. assertTrue(encoder.matches("ram123", result));
    39. }
    40. @Test
    41. public void testDelegatingPasswordEncoder() {
    42. PasswordEncoder encoder = PasswordEncoderFactories.createDelegatingPasswordEncoder();
    43. String result = encoder.encode("ram123");
    44. System.out.println(result);
    45. assertTrue(encoder.matches("ram123", result));
    46. }
    47. }

    找到测试结果的打印屏幕。

    BCryptPasswordEncoder

    BCryptPasswordEncoder是使用BCrypt强哈希函数的PasswordEncoder接口的实现。要实例化,我们可以选择传递BCrypt版本和强度。强度值越大,对密码进行哈希处理的工作就越多。我们使用如下 编码和匹配密码。BCryptPasswordEncoderBCryptPasswordEncoder

    1. BCryptPasswordEncoder encoder = new BCryptPasswordEncoder();
    2. String result = encoder.encode("ram123");
    3. assertTrue(encoder.matches("ram123", result));

    在我们的 Spring Security Java 配置中,要启用特定的密码编码器,只需为该密码编码器创建一个 bean。

    1. @Configuration
    2. @EnableWebSecurity
    3. public class SecurityConfig extends WebSecurityConfigurerAdapter {
    4. @Override
    5. protected void configure(AuthenticationManagerBuilder auth) throws Exception {
    6. auth.inMemoryAuthentication()
    7. .withUser("lakhan")
    8. .password("$2a$10$q5pHs1fyVDbQSnBu3Il/meAONlMYFT1RhGlT2OC6IXX5.bp2JBZU6")
    9. .roles("USER");
    10. }
    11. @Bean
    12. public PasswordEncoder passwordEncoder() {
    13. BCryptPasswordEncoder passwordEncoder = new BCryptPasswordEncoder();
    14. return passwordEncoder;
    15. }
    16. ------
    17. }

    在 XML 配置中找到要创建的 bean,并使用element 分配它。

    1. password="$2a$10$q5pHs1fyVDbQSnBu3Il/meAONlMYFT1RhGlT2OC6IXX5.bp2JBZU6"
    2. authorities="ROLE_USER" />
    3. class="org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder"/>


     

    Argon2PasswordEncoder

    Argon2PasswordEncoder是使用Argon2散列函数的PasswordEncoder接口的实现。要实例化,我们可以选择传递盐的长度、生成的哈希长度、CPU 成本参数、内存成本参数和并行化参数。要使用,我们需要解决 Bouncy castle 依赖。 Argon2PasswordEncoderArgon2PasswordEncoder

    1. org.bouncycastle
    2. bcprov-jdk15on
    3. 1.64

    Argon2PasswordEncoder我们可以使用如下 编码和匹配密码。

    1. Argon2PasswordEncoder encoder = new Argon2PasswordEncoder();
    2. String result = encoder.encode("ram123");
    3. assertTrue(encoder.matches("ram123", result));

    在 Spring Security Java 配置中,要启用Argon2PasswordEncoder,只需创建它的 bean。

    1. @Configuration
    2. @EnableWebSecurity
    3. public class SecurityConfig extends WebSecurityConfigurerAdapter {
    4. @Override
    5. protected void configure(AuthenticationManagerBuilder auth) throws Exception {
    6. auth.inMemoryAuthentication()
    7. .withUser("ram")
    8. .password("$argon2id$v=19$m=4096,t=3,p=1$JudTbnHxqeGVs608XXVcTA$WB7CJvel59tcXBbsXhyq60et7wutd1DYSFufFX9uhtM")
    9. .roles("USER");
    10. }
    11. @Bean
    12. public PasswordEncoder passwordEncoder() {
    13. Argon2PasswordEncoder passwordEncoder = new Argon2PasswordEncoder();
    14. return passwordEncoder;
    15. }
    16. ------
    17. }

    在 XML 配置中找到要创建的 bean,并使用element 分配它。

    1. class="org.springframework.security.crypto.argon2.Argon2PasswordEncoder"/>

    Pbkdf2PasswordEncoder

    这是使用PBKDF2散列函数Pbkdf2PasswordEncoder的接口的实现。要实例化,我们可以选择传递要包含在密码哈希、迭代次数和哈希大小中的秘密值。使用 查找对密码进行编码和匹配的示例。 PasswordEncoderPbkdf2PasswordEncoderPbkdf2PasswordEncoder

    1. Pbkdf2PasswordEncoder encoder = new Pbkdf2PasswordEncoder();
    2. String result = encoder.encode("ram123");
    3. assertTrue(encoder.matches("ram123", result));

    Pbkdf2PasswordEncoder在 Spring Security Java 配置中使用,只需创建它的 bean。

    1. @Configuration
    2. @EnableWebSecurity
    3. public class SecurityConfig extends WebSecurityConfigurerAdapter {
    4. @Override
    5. protected void configure(AuthenticationManagerBuilder auth) throws Exception {
    6. auth.inMemoryAuthentication()
    7. .withUser("bharat")
    8. .password("77a366e9ba2d6830b64d1b86eb7462996f3102d2b76562de3e56e5f13543a02486e1ee553cef18de")
    9. .roles("USER");
    10. }
    11. @Bean
    12. public PasswordEncoder passwordEncoder() {
    13. Pbkdf2PasswordEncoder passwordEncoder = new Pbkdf2PasswordEncoder();
    14. return passwordEncoder;
    15. }
    16. ------
    17. }

    在 XML 配置中找到要创建的 bean,并使用element 分配它。

    1. class="org.springframework.security.crypto.password.Pbkdf2PasswordEncoder"/>

    SCryptPasswordEncoder

    SCryptPasswordEncoderPasswordEncoder使用SCrypt散列函数的接口的实现。要实例化SCryptPasswordEncoder,我们可以选择传递 CPU 成本、内存成本、并行化参数、算法的密钥长度和盐长度。要使用SCryptPasswordEncoder,我们需要解决 Bouncy castle 依赖。使用 查找对密码进行编码和匹配的示例SCryptPasswordEncoder

    1. SCryptPasswordEncoder encoder = new SCryptPasswordEncoder();
    2. String result = encoder.encode("ram123");
    3. assertTrue(encoder.matches("ram123", result));

    SCryptPasswordEncoder在 Spring Security Java 配置中使用,只需创建它的 bean。

    1. @Configuration
    2. @EnableWebSecurity
    3. public class SecurityConfig extends WebSecurityConfigurerAdapter {
    4. @Override
    5. protected void configure(AuthenticationManagerBuilder auth) throws Exception {
    6. auth.inMemoryAuthentication()
    7. .withUser("shatru")
    8. .password("$e0801$VoXA+5ot9fXbuLaOj5izqgd3JrOtBjvsqpbwssgHIA3omPpNB8t+FYtnsVpxx5DJjAvFtrA/klDstepB320TSw==$CLsjnAxzzNof2jkDrSBeoCTvuxO8qi67FRDY0vrCZwY=")
    9. .roles("USER");
    10. }
    11. @Bean
    12. public PasswordEncoder passwordEncoder() {
    13. SCryptPasswordEncoder passwordEncoder = new SCryptPasswordEncoder();
    14. return passwordEncoder;
    15. }
    16. ------
    17. }

    在 XML 配置中找到要创建的 bean,并使用element 分配它。

    1. class="org.springframework.security.crypto.scrypt.SCryptPasswordEncoder"/>

    委托密码编码器

    DelegatingPasswordEncoder是 Spring Security 5.0 中的默认密码编码器。基于前缀标识符的DelegatingPasswordEncoder委托给另一个。PasswordEncoder例如,
    1。

    {noop}ram123 

    DelegatingPasswordEncoder将此密码委托给NoOpPasswordEncoder.
    2.

    {bcrypt}$2a$10$q5pHs1fyVDbQSnBu3Il/meAONlMYFT1RhGlT2OC6IXX5.bp2JBZU6 

    DelegatingPasswordEncoder将此密码委托给BCryptPasswordEncoder.
    3.

    {pbkdf2}77a366e9ba2d6830b64d1b86eb7462996f3102d2b76562de3e56e5f13543a02486e1ee553cef18de 

    DelegatingPasswordEncoder将此密码委托给Pbkdf2PasswordEncoder.

    找到一个完整的例子。
    SecurityConfig.java

    1. package com.concretepage;
    2. import org.springframework.context.annotation.Configuration;
    3. import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
    4. import org.springframework.security.config.annotation.web.builders.HttpSecurity;
    5. import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
    6. import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
    7. @Configuration
    8. @EnableWebSecurity
    9. public class SecurityConfig extends WebSecurityConfigurerAdapter {
    10. @Override
    11. protected void configure(HttpSecurity http) throws Exception {
    12. http.authorizeRequests()
    13. .antMatchers("/**").access("hasRole('USER')")
    14. .and().formLogin();
    15. }
    16. @Override
    17. protected void configure(AuthenticationManagerBuilder auth) throws Exception {
    18. auth.inMemoryAuthentication().withUser("ram")
    19. .password("{noop}ram123") //ram123
    20. .roles("USER")
    21. .and()
    22. .withUser("lakhan")
    23. .password("{bcrypt}$2a$10$q5pHs1fyVDbQSnBu3Il/meAONlMYFT1RhGlT2OC6IXX5.bp2JBZU6") //lakhan123
    24. .roles("USER");
    25. }
    26. }

    找到等效的 XML 配置。
    security-config.xml

    1. xmlns:beans="http://www.springframework.org/schema/beans"
    2. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    3. xsi:schemaLocation="http://www.springframework.org/schema/beans
    4. http://www.springframework.org/schema/beans/spring-beans.xsd
    5. http://www.springframework.org/schema/security
    6. http://www.springframework.org/schema/security/spring-security.xsd">
    7. password="{noop}ram123"
    8. authorities="ROLE_USER" />
    9. password="{bcrypt}$2a$10$q5pHs1fyVDbQSnBu3Il/meAONlMYFT1RhGlT2OC6IXX5.bp2JBZU6"
    10. authorities="ROLE_USER" />

    pom.xml

    1. org.springframework.boot
    2. spring-boot-starter-parent
    3. 2.2.1.RELEASE
    4. spring-app
    5. 11
    6. org.springframework.boot
    7. spring-boot-starter-web
    8. org.springframework.boot
    9. spring-boot-starter-security
    10. org.springframework.boot
    11. spring-boot-starter-test
    12. org.junit.jupiter
    13. junit-jupiter-api
    14. 5.3.2
    15. test
    16. org.junit.jupiter
    17. junit-jupiter-engine
    18. 5.3.2
    19. test
    20. org.junit.jupiter
    21. junit-jupiter-params
    22. 5.3.2
    23. test
    24. org.junit.platform
    25. junit-platform-launcher
    26. 1.3.2
    27. test
    28. org.bouncycastle
    29. bcprov-jdk15on
    30. 1.64

    AppController.java

    1. package com.concretepage;
    2. import org.springframework.security.core.Authentication;
    3. import org.springframework.stereotype.Controller;
    4. import org.springframework.web.bind.annotation.GetMapping;
    5. import org.springframework.web.bind.annotation.ResponseBody;
    6. @Controller
    7. public class AppController {
    8. @GetMapping("/app")
    9. public @ResponseBody String helloUser(Authentication authentication) {
    10. return "Welcome! " + authentication.getName();
    11. }
    12. }

    Main.java

    1. package com.concretepage;
    2. import org.springframework.boot.SpringApplication;
    3. import org.springframework.boot.autoconfigure.SpringBootApplication;
    4. @SpringBootApplication
    5. public class Main {
    6. public static void main(String[] args) {
    7. SpringApplication.run(Main.class, args);
    8. }
    9. }

    输出

    下载项目并使用命令提示符从项目的根文件夹运行以下命令。

    mvn spring-boot:run 

    访问网址。

    http://localhost:8080/app 

    输入凭据lakhan/lakhan123

    我们将看到如下欢迎页面。

    参考

    Spring 安全参考

    下载源代码

  • 相关阅读:
    如何查看 Windows 服务器中的登录事件
    排序算法总结-C语言
    Kafka多生产者消费者自动配置
    docker 安装cloudreve
    C#实现全盘扫描,找到符合要求的文件,并把路径写入到TXT中
    rocketmq各类问题
    C/S架构学习之TCP服务器
    IDEA转换编码格式
    mulesoft Module 10 quiz 解析
    2022 需求工程综合论述题【太原理工大学】
  • 原文地址:https://blog.csdn.net/allway2/article/details/126734173