我正在使用Sping Boot 3。我正在尝试允许所有请求到特定端点。我在mysql表(users)中保存了用户的详细信息,其中存储了用户名,密码和角色。密码是使用Bcrypt加密的。我使用https://bcrypt-generator.com/生成加密代码并将其存储在数据库中。下面是表中的密码示例- {bcrypt}$2a$12$2mERuojKpXO8N2qX2OXmBOAIuVM6pSImxlcrrJXHNyI3iowgHe5Zi
这里的代码
import javax.sql.DataSource;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.HttpMethod;
import org.springframework.security.config.Customizer;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.provisioning.JdbcUserDetailsManager;
import org.springframework.security.provisioning.UserDetailsManager;
import org.springframework.security.web.SecurityFilterChain;
@Configuration
@EnableWebSecurity
public class RestSecurityConfig {
@Bean
public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
http.authorizeHttpRequests( configurer ->
configurer
.requestMatchers(HttpMethod.POST, "/api/auth/**").permitAll()
);
// use HTTP Basic Authentication
http.httpBasic(Customizer.withDefaults());
// disable Cross Site Request Forgery (CSRF)
http.csrf(csrf -> csrf.disable());
return http.build();
}
@Bean
public UserDetailsManager userDetailsManager(DataSource dataSource){
JdbcUserDetailsManager jdbcUserDetailsManager = new JdbcUserDetailsManager(dataSource);
jdbcUserDetailsManager.setUsersByUsernameQuery(
"select username, password, enabled from users where username=?"
);
jdbcUserDetailsManager.setAuthoritiesByUsernameQuery(
"select username, role from users where username=?"
);
return jdbcUserDetailsManager;
}
@Bean
public PasswordEncoder encoder() {
return new BCryptPasswordEncoder();
}
}
字符串
但是,当我尝试访问此端点时,我得到一个401 Unauthorized。看起来似乎是Unauthorized()不起作用。它仍然需要我提供登录凭据。我如何解决这个问题?
我想知道的另一件事是,我如何发送加密的密码以进行Postman上的身份验证?
编辑1:
这是日志
2023-12-21T17:01:31.411+05:30 WARN 22830 --- [nio-8080-exec-2] o.s.s.c.bcrypt.BCryptPasswordEncoder : Encoded password does not look like BCrypt
2023-12-21T17:01:31.411+05:30 DEBUG 22830 --- [nio-8080-exec-2] o.s.s.a.dao.DaoAuthenticationProvider : Failed to authenticate since password does not match stored value
2023-12-21T17:01:31.412+05:30 DEBUG 22830 --- [nio-8080-exec-2] o.s.s.w.a.www.BasicAuthenticationFilter : Failed to process authentication request
型
2条答案
按热度按时间aurhwmvo1#
身份验证不是授权。
permitAll
是授权的一部分,并在 * 身份验证后应用。是的,身份验证 * 可能 * 会让没有凭据的请求匿名,然后permitAll
会接受。但当身份验证过程本身遇到处理凭据的异常时,情况就不同了-您的凭据格式错误。所以,401的发生是因为身份验证过程检测到请求有凭据,但仍然无法做出决定。是的,这是预期的行为。解决方案是修复凭证处理。(
{bcrypt}....
)你应该使用委托编码器。不同的是BCryptPasswordEncoder
只处理一种类型的令牌,不需要任何前缀,而DelegatingPasswordEncoder
可以处理各种类型的令牌,并且需要前缀来区分它们。一组可能的前缀:字符串
qyuhtwio2#
基于this article,你必须像这样使用spring Boot 的passwordEncoder:
字符串
根据您的日志,您需要更改您的bcrypt密码和重新生成的密码与此方法一样:
型
并将其设置为数据库