Spring jdbcAuthentication 的安全性抛出没有为 id "null" 映射的 PasswordEncoder
Spring Security with jdbcAuthentication throws There is no PasswordEncoder mapped for the id "null"
我目前正在学习 SpringSecurity spring 使用 h2
数据库启动。
当我尝试通过它抛出的用户名和密码登录时,我正在使用 jdbcAuthentication 进行身份验证:
java.lang.IllegalArgumentException: There is no PasswordEncoder mapped for the id "null"
我将密码编码器用作:
PasswordEncoderFactories.createDelegatingPasswordEncoder()
.
这是错误日志
. ____ _ __ _ _
/\ / ___'_ __ _ _(_)_ __ __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
\/ ___)| |_)| | | | | || (_| | ) ) ) )
' |____| .__|_| |_|_| |_\__, | / / / /
=========|_|==============|___/=/_/_/_/
:: Spring Boot :: (v2.2.6.RELEASE)
2020-04-28 01:55:46.232 INFO 22525 --- [ main] c.s.s.SpringSecurityJdbcApplication : Starting SpringSecurityJdbcApplication on harsh with PID 22525 (/home/harsh/rapid/chatak-pg-microservices/spring-security-jdbc/target/classes started by harsh in /home/harsh/rapid/chatak-pg-microservices/spring-security-jdbc)
2020-04-28 01:55:46.235 INFO 22525 --- [ main] c.s.s.SpringSecurityJdbcApplication : No active profile set, falling back to default profiles: default
2020-04-28 01:55:46.943 INFO 22525 --- [ main] .s.d.r.c.RepositoryConfigurationDelegate : Bootstrapping Spring Data JDBC repositories in DEFAULT mode.
2020-04-28 01:55:46.966 INFO 22525 --- [ main] .s.d.r.c.RepositoryConfigurationDelegate : Finished Spring Data repository scanning in 16ms. Found 0 JDBC repository interfaces.
2020-04-28 01:55:47.467 INFO 22525 --- [ main] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat initialized with port(s): 8080 (http)
2020-04-28 01:55:47.475 INFO 22525 --- [ main] o.apache.catalina.core.StandardService : Starting service [Tomcat]
2020-04-28 01:55:47.475 INFO 22525 --- [ main] org.apache.catalina.core.StandardEngine : Starting Servlet engine: [Apache Tomcat/9.0.33]
2020-04-28 01:55:47.527 INFO 22525 --- [ main] o.a.c.c.C.[Tomcat].[localhost].[/] : Initializing Spring embedded WebApplicationContext
2020-04-28 01:55:47.527 INFO 22525 --- [ main] o.s.web.context.ContextLoader : Root WebApplicationContext: initialization completed in 1242 ms
2020-04-28 01:55:47.686 INFO 22525 --- [ main] com.zaxxer.hikari.HikariDataSource : HikariPool-1 - Starting...
2020-04-28 01:55:47.784 INFO 22525 --- [ main] com.zaxxer.hikari.HikariDataSource : HikariPool-1 - Start completed.
2020-04-28 01:55:47.993 INFO 22525 --- [ main] o.s.s.web.DefaultSecurityFilterChain : Creating filter chain: any request, [org.springframework.security.web.context.request.async.WebAsyncManagerIntegrationFilter@46678e49, org.springframework.security.web.context.SecurityContextPersistenceFilter@3fae596, org.springframework.security.web.header.HeaderWriterFilter@1d25c1c, org.springframework.security.web.csrf.CsrfFilter@27b000f7, org.springframework.security.web.authentication.logout.LogoutFilter@67e28be3, org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter@6f3f0fae, org.springframework.security.web.authentication.ui.DefaultLoginPageGeneratingFilter@4a5905d9, org.springframework.security.web.authentication.ui.DefaultLogoutPageGeneratingFilter@748e9b20, org.springframework.security.web.savedrequest.RequestCacheAwareFilter@42fcc7e6, org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter@73017a80, org.springframework.security.web.authentication.AnonymousAuthenticationFilter@2063c53e, org.springframework.security.web.session.SessionManagementFilter@5bca7664, org.springframework.security.web.access.ExceptionTranslationFilter@333cb916, org.springframework.security.web.access.intercept.FilterSecurityInterceptor@1b29d52b]
2020-04-28 01:55:48.147 INFO 22525 --- [ main] o.s.s.concurrent.ThreadPoolTaskExecutor : Initializing ExecutorService 'applicationTaskExecutor'
2020-04-28 01:55:48.533 INFO 22525 --- [ main] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat started on port(s): 8080 (http) with context path ''
2020-04-28 01:55:48.536 INFO 22525 --- [ main] c.s.s.SpringSecurityJdbcApplication : Started SpringSecurityJdbcApplication in 2.688 seconds (JVM running for 3.258)
2020-04-28 01:55:51.231 INFO 22525 --- [nio-8080-exec-1] o.a.c.c.C.[Tomcat].[localhost].[/] : Initializing Spring DispatcherServlet 'dispatcherServlet'
2020-04-28 01:55:51.231 INFO 22525 --- [nio-8080-exec-1] o.s.web.servlet.DispatcherServlet : Initializing Servlet 'dispatcherServlet'
2020-04-28 01:55:51.240 INFO 22525 --- [nio-8080-exec-1] o.s.web.servlet.DispatcherServlet : Completed initialization in 9 ms
2020-04-28 01:55:57.071 ERROR 22525 --- [nio-8080-exec-3] o.a.c.c.C.[.[.[/].[dispatcherServlet] : Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception
java.lang.IllegalArgumentException: There is no PasswordEncoder mapped for the id "null"
at org.springframework.security.crypto.password.DelegatingPasswordEncoder$UnmappedIdPasswordEncoder.matches(DelegatingPasswordEncoder.java:250) ~[spring-security-core-5.2.2.RELEASE.jar:5.2.2.RELEASE]
这是我的 SpringSecurity class
SpringSecurity.java
安全配置:
@Configuration
@EnableWebSecurity
public class SpringSecurity extends WebSecurityConfigurerAdapter {
@Autowired
DataSource dataSource;
@Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests()
.antMatchers("/admin").hasRole("ADMIN")
.antMatchers("/user").hasAnyRole("ADMIN","USER")
.antMatchers("/home").permitAll()
.and()
.formLogin();
}
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.jdbcAuthentication()
.dataSource(dataSource)
.passwordEncoder(getPassword());
}
public PasswordEncoder getPassword() {
//actually do nothing
return PasswordEncoderFactories.createDelegatingPasswordEncoder();
}
}
HomeController.java
@RestController
public class HomeController {
@GetMapping("/home")
public String home() {
return ("<h1>Welome to Spring Security</h1>");
}
@GetMapping("/admin")
public String admin() {
return ("<h1>Welome ADMIN user to Spring Security</h1>");
}
@GetMapping("/user")
public String user() {
return ("<h1>Welome USER user to Spring Security</h1>");
}
}
application.properties
spring.datasource.continue-on-error=true
spring.datasource.initialize=true
spring.datasource.separator=;
spring.datasource.sql-script-encoding=UTF-8
data.sql
insert into users (username,password,enabled) values ('user','user',true);
insert into users (username,password,enabled) values ('sadmin','admin',true);
insert into authorities(username,authority) values ('user','ROLE_USER');
insert into authorities(username,authority) values ('sadmin','ROLE_ADMIN');
schema.sql
drop table users;
drop table authorities;
drop index ix_auth_username;
create table users(
username varchar_ignorecase(50) not null primary key,
password varchar_ignorecase(50) not null,
enabled boolean not null
);
create table authorities (
username varchar_ignorecase(50) not null,
authority varchar_ignorecase(50) not null,
constraint fk_authorities_users foreign key(username) references users(username)
);
create unique index ix_auth_username on authorities (username,authority);
附上项目截图:
你应该把@Bean:
@Bean
public PasswordEncoder getPassword() {
return PasswordEncoderFactories.createDelegatingPasswordEncoder();
}
此外,我个人使用 BCrypt 并将其设置在身份验证提供商上:
@Override
protected void configure(AuthenticationManagerBuilder auth) {
auth.authenticationProvider(authenticationProvider());
}
@Bean
PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
@Bean
DaoAuthenticationProvider authenticationProvider(){
DaoAuthenticationProvider daoAuthenticationProvider = new DaoAuthenticationProvider();
daoAuthenticationProvider.setPasswordEncoder(passwordEncoder());
daoAuthenticationProvider.setUserDetailsService(YourUserDetailsService);
return daoAuthenticationProvider;
}
如果您想确保您的密码编码器真的什么都不做,您可以使用:
@Bean
public PasswordEncoder passwordEncoder() {
return NoOpPasswordEncoder.getInstance();
}
这只是出于教育原因。
不要在实际项目中使用它。
我目前正在学习 SpringSecurity spring 使用 h2
数据库启动。
当我尝试通过它抛出的用户名和密码登录时,我正在使用 jdbcAuthentication 进行身份验证:
java.lang.IllegalArgumentException: There is no PasswordEncoder mapped for the id "null"
我将密码编码器用作:
PasswordEncoderFactories.createDelegatingPasswordEncoder()
.
这是错误日志
. ____ _ __ _ _
/\ / ___'_ __ _ _(_)_ __ __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
\/ ___)| |_)| | | | | || (_| | ) ) ) )
' |____| .__|_| |_|_| |_\__, | / / / /
=========|_|==============|___/=/_/_/_/
:: Spring Boot :: (v2.2.6.RELEASE)
2020-04-28 01:55:46.232 INFO 22525 --- [ main] c.s.s.SpringSecurityJdbcApplication : Starting SpringSecurityJdbcApplication on harsh with PID 22525 (/home/harsh/rapid/chatak-pg-microservices/spring-security-jdbc/target/classes started by harsh in /home/harsh/rapid/chatak-pg-microservices/spring-security-jdbc)
2020-04-28 01:55:46.235 INFO 22525 --- [ main] c.s.s.SpringSecurityJdbcApplication : No active profile set, falling back to default profiles: default
2020-04-28 01:55:46.943 INFO 22525 --- [ main] .s.d.r.c.RepositoryConfigurationDelegate : Bootstrapping Spring Data JDBC repositories in DEFAULT mode.
2020-04-28 01:55:46.966 INFO 22525 --- [ main] .s.d.r.c.RepositoryConfigurationDelegate : Finished Spring Data repository scanning in 16ms. Found 0 JDBC repository interfaces.
2020-04-28 01:55:47.467 INFO 22525 --- [ main] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat initialized with port(s): 8080 (http)
2020-04-28 01:55:47.475 INFO 22525 --- [ main] o.apache.catalina.core.StandardService : Starting service [Tomcat]
2020-04-28 01:55:47.475 INFO 22525 --- [ main] org.apache.catalina.core.StandardEngine : Starting Servlet engine: [Apache Tomcat/9.0.33]
2020-04-28 01:55:47.527 INFO 22525 --- [ main] o.a.c.c.C.[Tomcat].[localhost].[/] : Initializing Spring embedded WebApplicationContext
2020-04-28 01:55:47.527 INFO 22525 --- [ main] o.s.web.context.ContextLoader : Root WebApplicationContext: initialization completed in 1242 ms
2020-04-28 01:55:47.686 INFO 22525 --- [ main] com.zaxxer.hikari.HikariDataSource : HikariPool-1 - Starting...
2020-04-28 01:55:47.784 INFO 22525 --- [ main] com.zaxxer.hikari.HikariDataSource : HikariPool-1 - Start completed.
2020-04-28 01:55:47.993 INFO 22525 --- [ main] o.s.s.web.DefaultSecurityFilterChain : Creating filter chain: any request, [org.springframework.security.web.context.request.async.WebAsyncManagerIntegrationFilter@46678e49, org.springframework.security.web.context.SecurityContextPersistenceFilter@3fae596, org.springframework.security.web.header.HeaderWriterFilter@1d25c1c, org.springframework.security.web.csrf.CsrfFilter@27b000f7, org.springframework.security.web.authentication.logout.LogoutFilter@67e28be3, org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter@6f3f0fae, org.springframework.security.web.authentication.ui.DefaultLoginPageGeneratingFilter@4a5905d9, org.springframework.security.web.authentication.ui.DefaultLogoutPageGeneratingFilter@748e9b20, org.springframework.security.web.savedrequest.RequestCacheAwareFilter@42fcc7e6, org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter@73017a80, org.springframework.security.web.authentication.AnonymousAuthenticationFilter@2063c53e, org.springframework.security.web.session.SessionManagementFilter@5bca7664, org.springframework.security.web.access.ExceptionTranslationFilter@333cb916, org.springframework.security.web.access.intercept.FilterSecurityInterceptor@1b29d52b]
2020-04-28 01:55:48.147 INFO 22525 --- [ main] o.s.s.concurrent.ThreadPoolTaskExecutor : Initializing ExecutorService 'applicationTaskExecutor'
2020-04-28 01:55:48.533 INFO 22525 --- [ main] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat started on port(s): 8080 (http) with context path ''
2020-04-28 01:55:48.536 INFO 22525 --- [ main] c.s.s.SpringSecurityJdbcApplication : Started SpringSecurityJdbcApplication in 2.688 seconds (JVM running for 3.258)
2020-04-28 01:55:51.231 INFO 22525 --- [nio-8080-exec-1] o.a.c.c.C.[Tomcat].[localhost].[/] : Initializing Spring DispatcherServlet 'dispatcherServlet'
2020-04-28 01:55:51.231 INFO 22525 --- [nio-8080-exec-1] o.s.web.servlet.DispatcherServlet : Initializing Servlet 'dispatcherServlet'
2020-04-28 01:55:51.240 INFO 22525 --- [nio-8080-exec-1] o.s.web.servlet.DispatcherServlet : Completed initialization in 9 ms
2020-04-28 01:55:57.071 ERROR 22525 --- [nio-8080-exec-3] o.a.c.c.C.[.[.[/].[dispatcherServlet] : Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception
java.lang.IllegalArgumentException: There is no PasswordEncoder mapped for the id "null"
at org.springframework.security.crypto.password.DelegatingPasswordEncoder$UnmappedIdPasswordEncoder.matches(DelegatingPasswordEncoder.java:250) ~[spring-security-core-5.2.2.RELEASE.jar:5.2.2.RELEASE]
这是我的 SpringSecurity class
SpringSecurity.java
安全配置:
@Configuration
@EnableWebSecurity
public class SpringSecurity extends WebSecurityConfigurerAdapter {
@Autowired
DataSource dataSource;
@Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests()
.antMatchers("/admin").hasRole("ADMIN")
.antMatchers("/user").hasAnyRole("ADMIN","USER")
.antMatchers("/home").permitAll()
.and()
.formLogin();
}
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.jdbcAuthentication()
.dataSource(dataSource)
.passwordEncoder(getPassword());
}
public PasswordEncoder getPassword() {
//actually do nothing
return PasswordEncoderFactories.createDelegatingPasswordEncoder();
}
}
HomeController.java
@RestController
public class HomeController {
@GetMapping("/home")
public String home() {
return ("<h1>Welome to Spring Security</h1>");
}
@GetMapping("/admin")
public String admin() {
return ("<h1>Welome ADMIN user to Spring Security</h1>");
}
@GetMapping("/user")
public String user() {
return ("<h1>Welome USER user to Spring Security</h1>");
}
}
application.properties
spring.datasource.continue-on-error=true
spring.datasource.initialize=true
spring.datasource.separator=;
spring.datasource.sql-script-encoding=UTF-8
data.sql
insert into users (username,password,enabled) values ('user','user',true);
insert into users (username,password,enabled) values ('sadmin','admin',true);
insert into authorities(username,authority) values ('user','ROLE_USER');
insert into authorities(username,authority) values ('sadmin','ROLE_ADMIN');
schema.sql
drop table users;
drop table authorities;
drop index ix_auth_username;
create table users(
username varchar_ignorecase(50) not null primary key,
password varchar_ignorecase(50) not null,
enabled boolean not null
);
create table authorities (
username varchar_ignorecase(50) not null,
authority varchar_ignorecase(50) not null,
constraint fk_authorities_users foreign key(username) references users(username)
);
create unique index ix_auth_username on authorities (username,authority);
附上项目截图:
你应该把@Bean:
@Bean
public PasswordEncoder getPassword() {
return PasswordEncoderFactories.createDelegatingPasswordEncoder();
}
此外,我个人使用 BCrypt 并将其设置在身份验证提供商上:
@Override
protected void configure(AuthenticationManagerBuilder auth) {
auth.authenticationProvider(authenticationProvider());
}
@Bean
PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
@Bean
DaoAuthenticationProvider authenticationProvider(){
DaoAuthenticationProvider daoAuthenticationProvider = new DaoAuthenticationProvider();
daoAuthenticationProvider.setPasswordEncoder(passwordEncoder());
daoAuthenticationProvider.setUserDetailsService(YourUserDetailsService);
return daoAuthenticationProvider;
}
如果您想确保您的密码编码器真的什么都不做,您可以使用:
@Bean
public PasswordEncoder passwordEncoder() {
return NoOpPasswordEncoder.getInstance();
}
这只是出于教育原因。
不要在实际项目中使用它。