Spring 安全 OAuth2 数据库 -- 错误凭证错误
Spring Security OAuth2 Database -- Bad Credentials Error
我正在构建一个 Spring 应用程序,它使用数据库作为 OAuth2 配置中的授权服务。
这是我的安全配置 class Spring 安全
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {
@Autowired
private CustomUserDetailsService userDetailsService;
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(userDetailsService)
.passwordEncoder(getPasswordEncoder());
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http.csrf().disable();
http.authorizeRequests()
.antMatchers("**/secured/**").authenticated()
.anyRequest().permitAll()
.and()
.formLogin().permitAll();
}
private PasswordEncoder getPasswordEncoder() {
return new PasswordEncoder() {
@Override
public String encode(CharSequence charSequence) {
return charSequence.toString();
}
@Override
public boolean matches(CharSequence charSequence, String s) {
return true;
}
};
}
}
这是我的数据库存储库,旨在通过电子邮件找到用户。
@Repository
public interface UsersRepository extends JpaRepository<User, Integer> {
@Query
Optional<User> findByEmail(String email);
}
这是我的服务class:
@Service("userDetailsService")
public class CustomUserDetailsService implements UserDetailsService {
@Autowired
private UsersRepository usersRepository;
@Override
public UserDetails loadUserByUsername(String email) throws UsernameNotFoundException {
Optional<User> optionalUsers = usersRepository.findByEmail(email);
optionalUsers
.orElseThrow(() -> new UsernameNotFoundException("Username not found"));
return optionalUsers
.map(CustomUserDetails::new).get();
}
}
当我输入数据库中的电子邮件和密码时,它会返回
"Bad Credentials"
有人能发现我的设置有什么问题吗?
如果我删除
@PreAuthorise("hasRole('ROLE_admin')")
在控制器中可以去掉登录屏幕,但我希望有登录屏幕。
根据评论的要求,这是我的数据库架构。我使用 H2 来提供内存数据库。
DROP TABLE IF EXISTS 'User'
CREATE TABLE IF NOT EXISTS User (
id INT,
role VARCHAR(5),
title VARCHAR(5),
firstname VARCHAR(20),
lastname VARCHAR(20),
email VARCHAR(50),
password VARCHAR(50),
modified DATETIME,
accessed DATETIME
)
INSERT INTO User VALUES
(
'1',
'admin',
'mr',
'bob',
'smith',
'bob.smith@example.com',
'gobob',
'1993-10-25 22:10:00',
'2018-04-09 08:30:00'
),
....
spring.h2.console.enabled=true
spring.h2.console.path=/h2
# Datasource
spring.datasource.url=jdbc:h2:file:path/to/application/src/main/resources/DATA-DUMP.sql
spring.datasource.username=<user>
spring.datasource.password=<pass>
spring.datasource.driver-class-name=org.h2.Driver
spring.datasource.testWhileIdle=true
spring.datasource.validationQuery=SELECT 1
spring.jpa.show-sql=true
spring.jpa.hibernate.ddl-auto=update
spring.jpa.hibernate.naming- strategy=org.hibernate.cfg.ImprovedNamingStrategy
spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.MySQL5Dialect
我不认为我的 H2 正在填充我的 Table 它创建:
2018-04-17 13:52:43.523 INFO 4407 --- [ main] o.hibernate.annotations.common.Version : HCANN000001: Hibernate Commons Annotations {5.0.1.Final}
2018-04-17 13:52:43.583 INFO 4407 --- [ main] org.hibernate.dialect.Dialect : HHH000400: Using dialect: org.hibernate.dialect.MySQL5Dialect
Hibernate: create table hibernate_sequence (next_val bigint) engine=MyISAM
Hibernate: insert into hibernate_sequence values ( 1 )
Hibernate: create table user (id integer not null, accessed datetime, email varchar(255), firstname varchar(255), lastname varchar(255), modified datetime, password varchar(255), role varchar(255), title varchar(255), primary key (id)) engine=MyISAM
2018-04-17 13:52:43.881 INFO 4407 --- [ main] j.LocalContainerEntityManagerFactoryBean : Initialized JPA EntityManagerFactory for persistence unit 'default'
虽然您当前收到 Bad Credentials
消息,但之后您可能 运行 遇到另一个问题:
@PreAuthorise("hasRole('ROLE_admin')")
请注意 hasRole
区分大小写,正确的角色可能是 ROLE_ADMIN
。此外,根据您的 Spring 安全版本,您可能需要省略 ROLE_
并简单地使用
@PreAuthorise("hasRole('ADMIN')")
问题
就像我在评论中提到的那样,在您实施 PasswordEncoder 时,只要用户名存在,您用于登录的密码并不重要,因为您实施的 matches
方法始终 return true .
换句话说,问题很可能是您的存储库找不到任何具有您要测试的用户名的用户。
您的数据库很可能是空的。
更新
User
table 是 Hibernate 在读取所有 class 用 @Entity
注释后自动创建的,而不是因为你在模式文件中写了它。
在 src/main/resources
中创建一个名为 data-h2.sql
的文件,并将所有插入内容移到那里,例如:
INSERT INTO User VALUES (
'1',
'admin',
'mr',
'bob',
'smith',
'bob.smith@example.com',
'gobob',
'1993-10-25 22:10:00',
'2018-04-09 08:30:00'
),
...
有关详细信息,请参阅 Spring Boot - Loading Initial Data
我正在构建一个 Spring 应用程序,它使用数据库作为 OAuth2 配置中的授权服务。
这是我的安全配置 class Spring 安全
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {
@Autowired
private CustomUserDetailsService userDetailsService;
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(userDetailsService)
.passwordEncoder(getPasswordEncoder());
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http.csrf().disable();
http.authorizeRequests()
.antMatchers("**/secured/**").authenticated()
.anyRequest().permitAll()
.and()
.formLogin().permitAll();
}
private PasswordEncoder getPasswordEncoder() {
return new PasswordEncoder() {
@Override
public String encode(CharSequence charSequence) {
return charSequence.toString();
}
@Override
public boolean matches(CharSequence charSequence, String s) {
return true;
}
};
}
}
这是我的数据库存储库,旨在通过电子邮件找到用户。
@Repository
public interface UsersRepository extends JpaRepository<User, Integer> {
@Query
Optional<User> findByEmail(String email);
}
这是我的服务class:
@Service("userDetailsService")
public class CustomUserDetailsService implements UserDetailsService {
@Autowired
private UsersRepository usersRepository;
@Override
public UserDetails loadUserByUsername(String email) throws UsernameNotFoundException {
Optional<User> optionalUsers = usersRepository.findByEmail(email);
optionalUsers
.orElseThrow(() -> new UsernameNotFoundException("Username not found"));
return optionalUsers
.map(CustomUserDetails::new).get();
}
}
当我输入数据库中的电子邮件和密码时,它会返回
"Bad Credentials"
有人能发现我的设置有什么问题吗?
如果我删除
@PreAuthorise("hasRole('ROLE_admin')")
在控制器中可以去掉登录屏幕,但我希望有登录屏幕。
根据评论的要求,这是我的数据库架构。我使用 H2 来提供内存数据库。
DROP TABLE IF EXISTS 'User'
CREATE TABLE IF NOT EXISTS User (
id INT,
role VARCHAR(5),
title VARCHAR(5),
firstname VARCHAR(20),
lastname VARCHAR(20),
email VARCHAR(50),
password VARCHAR(50),
modified DATETIME,
accessed DATETIME
)
INSERT INTO User VALUES
(
'1',
'admin',
'mr',
'bob',
'smith',
'bob.smith@example.com',
'gobob',
'1993-10-25 22:10:00',
'2018-04-09 08:30:00'
),
....
spring.h2.console.enabled=true
spring.h2.console.path=/h2
# Datasource
spring.datasource.url=jdbc:h2:file:path/to/application/src/main/resources/DATA-DUMP.sql
spring.datasource.username=<user>
spring.datasource.password=<pass>
spring.datasource.driver-class-name=org.h2.Driver
spring.datasource.testWhileIdle=true
spring.datasource.validationQuery=SELECT 1
spring.jpa.show-sql=true
spring.jpa.hibernate.ddl-auto=update
spring.jpa.hibernate.naming- strategy=org.hibernate.cfg.ImprovedNamingStrategy
spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.MySQL5Dialect
我不认为我的 H2 正在填充我的 Table 它创建:
2018-04-17 13:52:43.523 INFO 4407 --- [ main] o.hibernate.annotations.common.Version : HCANN000001: Hibernate Commons Annotations {5.0.1.Final}
2018-04-17 13:52:43.583 INFO 4407 --- [ main] org.hibernate.dialect.Dialect : HHH000400: Using dialect: org.hibernate.dialect.MySQL5Dialect
Hibernate: create table hibernate_sequence (next_val bigint) engine=MyISAM
Hibernate: insert into hibernate_sequence values ( 1 )
Hibernate: create table user (id integer not null, accessed datetime, email varchar(255), firstname varchar(255), lastname varchar(255), modified datetime, password varchar(255), role varchar(255), title varchar(255), primary key (id)) engine=MyISAM
2018-04-17 13:52:43.881 INFO 4407 --- [ main] j.LocalContainerEntityManagerFactoryBean : Initialized JPA EntityManagerFactory for persistence unit 'default'
虽然您当前收到 Bad Credentials
消息,但之后您可能 运行 遇到另一个问题:
@PreAuthorise("hasRole('ROLE_admin')")
请注意 hasRole
区分大小写,正确的角色可能是 ROLE_ADMIN
。此外,根据您的 Spring 安全版本,您可能需要省略 ROLE_
并简单地使用
@PreAuthorise("hasRole('ADMIN')")
问题
就像我在评论中提到的那样,在您实施 PasswordEncoder 时,只要用户名存在,您用于登录的密码并不重要,因为您实施的 matches
方法始终 return true .
换句话说,问题很可能是您的存储库找不到任何具有您要测试的用户名的用户。
您的数据库很可能是空的。
更新
User
table 是 Hibernate 在读取所有 class 用 @Entity
注释后自动创建的,而不是因为你在模式文件中写了它。
在 src/main/resources
中创建一个名为 data-h2.sql
的文件,并将所有插入内容移到那里,例如:
INSERT INTO User VALUES (
'1',
'admin',
'mr',
'bob',
'smith',
'bob.smith@example.com',
'gobob',
'1993-10-25 22:10:00',
'2018-04-09 08:30:00'
),
...
有关详细信息,请参阅 Spring Boot - Loading Initial Data