使用Bcrypt加密InMemoryAuthentication密码

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了使用Bcrypt加密InMemoryAuthentication密码相关的知识,希望对你有一定的参考价值。

在我对UserDetailsS​​ervice的自定义实现使用Bcrypt之前,我首先想看看我是否可以在内存数据库中使用它。

package com.patrick.Security;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.HttpMethod;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.NoOpPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;

@EnableWebSecurity
@Configuration
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {

    private UserDetailsService userDetailsService;


    @Autowired
    public WebSecurityConfig(UserDetailsService userDetailsService) {
        this.userDetailsService = userDetailsService;
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.csrf().disable().authorizeRequests()
                .antMatchers("/").permitAll()
                .antMatchers(HttpMethod.POST, "/login").permitAll()
                .antMatchers(HttpMethod.POST, "/users").hasAuthority("ADMIN")
                .antMatchers(HttpMethod.POST, "/shifts").hasAnyAuthority("ADMIN", "SUPERVISOR")
                .anyRequest().authenticated()
                .and()
                .addFilter(new AuthenticationFilter(authenticationManager()))
                .addFilter(new AuthorizationFilter(authenticationManager()));
    }

    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.inMemoryAuthentication().passwordEncoder(passwordEncoder())
                .withUser("admin").password("password").roles("ADMIN");
    }

    @Bean
    public PasswordEncoder passwordEncoder(){
        return new BCryptPasswordEncoder();
    }
}

通过创建/公开PasswordEncoder bean,会弹出此警告,最终阻止我访问登录路径:

o.s.s.c.bcrypt.BCryptPasswordEncoder     : Encoded password does not look like BCrypt

添加Deprecated NoOpPasswordEncoder将暂时解决问题,但显然不会对密码进行编码:

@SuppressWarnings("deprecation")
@Bean
public static NoOpPasswordEncoder passwordEncoder() {
return (NoOpPasswordEncoder) NoOpPasswordEncoder.getInstance();
}

添加Bcrypt的正确方法是什么?

答案

通过创建/公开PasswordEncoder bean,会弹出此警告,最终阻止我访问登录路径:

o.s.s.c.bcrypt.BCryptPasswordEncoder     : Encoded password does not look like BCrypt

这是因为您提供的密码不是用BCrypt编码的。而不是直接传递"password"作为密码,它需要首先编码。

出于测试目的,一种简单的方法是只需获取密码编码器并在您的配置方法中对其进行编码,如下所示

@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
    String password = passwordEncoder().encode("password");
    auth.inMemoryAuthentication().withUser("admin").password(password).roles("ADMIN");
}

@Bean
public PasswordEncoder passwordEncoder() {
    return new BCryptPasswordEncoder();
}
另一答案

使用Spring Security 5,您可以使用选定idPasswordEncoder作为密码前缀。如果你想使用普通密码,那么只需使用{noop}前缀,这将委托密码编码器到NoOpPasswordEncoder

示例代码:

@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
   auth.inMemoryAuthentication()
          .withUser("admin").password("{noop}password").roles("ADMIN");
}

以上是关于使用Bcrypt加密InMemoryAuthentication密码的主要内容,如果未能解决你的问题,请参考以下文章

使用bcrypt在nodejs中进行密码加密

Java通过BCrypt加密

检查使用 bCrypt 加密的密码 .. 我需要通过网络发送密码吗?

使用Bcrypt加密InMemoryAuthentication密码

laravel5的Bcrypt加密方式对系统保存密码的小结

Bcrypt 是用于散列还是加密?有点迷茫