我正在尝试对使用Postgresql数据库的REST控制器使用JDBC身份验证。 以下是管理身份验证的Configuration类:
@Configuration
@EnableAutoConfiguration
public class JDBCSecurityConfig extends WebSecurityConfigurerAdapter {
@Autowired
DataSource dataSource;
@Autowired
public void configAuthentication(AuthenticationManagerBuilder auth) throws Exception {
auth.jdbcAuthentication().dataSource(dataSource)
.usersByUsernameQuery("select username,password, enabled from users where username=?")
.authoritiesByUsernameQuery("select username, role from user_roles where username=?");
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http
//HTTP Basic authentication
.httpBasic()
.and()
.authorizeRequests()
.antMatchers(HttpMethod.GET, "/**").hasRole("USER")
.antMatchers(HttpMethod.POST, "/").hasRole("ADMIN")
.and()
.csrf().disable()
.formLogin().disable();
}
}
数据源配置应该可以:
spring.datasource.url=jdbc:postgresql://localhost:5432/springdb
spring.datasource.username=user
spring.datasource.password=password
但是,当我尝试使用用户角色来调用Controller的方法时:
@RequestMapping(path= "/", method = RequestMethod.GET, produces = {"application/json"})
public List<Customer> find()
{
return repository.getCustomers();
}
然后导致以下错误:
java.lang.IllegalArgumentException: There is no PasswordEncoder mapped for the id "null"
at org.springframework.security.crypto.password.DelegatingPasswordEncoder$UnmappedIdPasswordEncoder.matches(DelegatingPasswordEncoder.java:244) ~[spring-security-core-5.1.6.RELEASE.jar:5.1.6.RELEASE]
at org.springframework.security.crypto.password.DelegatingPasswordEncoder.matches(DelegatingPasswordEncoder.java:198) ~[spring-security-core-5.1.6.RELEASE.jar:5.1.6.RELEASE]
at org.springframework.security.config.annotation.authentication.configuration.AuthenticationConfiguration$LazyPasswordEncoder.matches(AuthenticationConfiguration.java:289) ~[spring-security-config-5.1.6.RELEASE.jar:5.1.6.RELEASE]
配置类有什么问题吗? 谢谢
答案 0 :(得分:2)
问题
hasRole("USER")
的角色,例如hasAuthority("ROLE_USER")
解决方案:
要解决密码问题,可以使用以下中的任何,但不能同时使用:
如果密码为testing1
,则必须将密码存储为{noop}testing1
。因此,请相应地更新数据库中的密码。
定义为NoOpPasswordEncoder
bean作为密码编码器。
要解决authorisation
问题:
ROLE_
@Bean
public PasswordEncoder passwordEncoder() {
return NoOpPasswordEncoder.getInstance();
}
说明
DelegatingPasswordEncoder
作为密码编码器。它实际上是以下编码器的列表。 public static PasswordEncoder createDelegatingPasswordEncoder() {
String encodingId = "bcrypt";
Map<String, PasswordEncoder> encoders = new HashMap<>();
encoders.put(encodingId, new BCryptPasswordEncoder());
encoders.put("ldap", new LdapShaPasswordEncoder());
encoders.put("MD4", new Md4PasswordEncoder());
encoders.put("MD5", new MessageDigestPasswordEncoder("MD5"));
encoders.put("noop", NoOpPasswordEncoder.getInstance());
encoders.put("pbkdf2", new Pbkdf2PasswordEncoder());
encoders.put("scrypt", new SCryptPasswordEncoder());
encoders.put("SHA-1", new MessageDigestPasswordEncoder("SHA-1"));
encoders.put("SHA-256", new MessageDigestPasswordEncoder("SHA-256"));
encoders.put("sha256", new StandardPasswordEncoder());
encoders.put("argon2", new Argon2PasswordEncoder());
return new DelegatingPasswordEncoder(encodingId, encoders);
}
由于它具有密码编码器列表,因此在检索用户和密码后,它不知道使用哪个密码编码器来加密密码。
为解决此问题,Spring Security希望在密码中添加前缀。因此,如果密码是使用BCryptPasswordEncoder
创建的,则将其存储为{bcrypt}xxx-sdsa-bcrypt-pasa
。因此,在检索时,可以决定使用哪个密码编码器。