# JDBC 身份验证
Spring Security 的JdbcDaoImpl
实现了UserDetailsService,以提供对基于用户名/密码的身份验证的支持这是使用 JDBC 检索的。JdbcUserDetailsManager
扩展JdbcDaoImpl
以通过UserDetailsManager
接口提供UserDetails
的管理。当 Spring Security 将其配置为接受用户名/密码以进行身份验证时,将使用基于UserDetails
的身份验证。
在以下几节中,我们将进行讨论:
Spring 安全性 JDBC 身份验证使用的默认模式
# 默认模式
Spring 安全性为基于 JDBC 的身份验证提供了默认查询。本节提供了与默认查询一起使用的相应的默认模式。你将需要调整模式,以匹配对查询和正在使用的数据库方言的任何自定义。
# 用户模式
JdbcDaoImpl
要求表为用户加载密码、帐户状态(已启用或禁用)和权限列表(角色)。所需的默认模式可以在下面找到。
默认的模式也公开为 Classpath 名为org/springframework/security/core/userdetails/jdbc/users.ddl 的资源。 |
---|
例 1。默认用户模式
create table users(
username varchar_ignorecase(50) not null primary key,
password varchar_ignorecase(500) 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);
Oracle 是一个流行的数据库选择,但需要一个稍微不同的模式。你可以在下面找到用户的默认 Oracle 模式。
例 2。Oracle 数据库的默认用户模式
CREATE TABLE USERS (
USERNAME NVARCHAR2(128) PRIMARY KEY,
PASSWORD NVARCHAR2(128) NOT NULL,
ENABLED CHAR(1) CHECK (ENABLED IN ('Y','N') ) NOT NULL
);
CREATE TABLE AUTHORITIES (
USERNAME NVARCHAR2(128) NOT NULL,
AUTHORITY NVARCHAR2(128) NOT NULL
);
ALTER TABLE AUTHORITIES ADD CONSTRAINT AUTHORITIES_UNIQUE UNIQUE (USERNAME, AUTHORITY);
ALTER TABLE AUTHORITIES ADD CONSTRAINT AUTHORITIES_FK1 FOREIGN KEY (USERNAME) REFERENCES USERS (USERNAME) ENABLE;
# 组模式
如果你的应用程序正在利用组,那么你将需要提供组模式。可以在下面找到组的默认模式。
例 3。默认组模式
create table groups (
id bigint generated by default as identity(start with 0) primary key,
group_name varchar_ignorecase(50) not null
);
create table group_authorities (
group_id bigint not null,
authority varchar(50) not null,
constraint fk_group_authorities_group foreign key(group_id) references groups(id)
);
create table group_members (
id bigint generated by default as identity(start with 0) primary key,
username varchar(50) not null,
group_id bigint not null,
constraint fk_group_members_group foreign key(group_id) references groups(id)
);
# 建立数据源
在配置JdbcUserDetailsManager
之前,必须创建DataSource
。在我们的示例中,我们将设置一个嵌入式数据源 (opens new window),它是用默认用户模式初始化的。
例 4。嵌入式数据源
爪哇
@Bean
DataSource dataSource() {
return new EmbeddedDatabaseBuilder()
.setType(H2)
.addScript("classpath:org/springframework/security/core/userdetails/jdbc/users.ddl")
.build();
}
XML
<jdbc:embedded-database>
<jdbc:script location="classpath:org/springframework/security/core/userdetails/jdbc/users.ddl"/>
</jdbc:embedded-database>
Kotlin
@Bean
fun dataSource(): DataSource {
return EmbeddedDatabaseBuilder()
.setType(H2)
.addScript("classpath:org/springframework/security/core/userdetails/jdbc/users.ddl")
.build()
}
在生产环境中,你将需要确保设置到外部数据库的连接。
# JdbcUserDetailsManager Bean
在这个示例中,我们使用Spring Boot CLI对password
的密码进行编码,并获得{bcrypt}$2a$10$GRLdNijSQMUvl/au9ofL.eDwmoohzzS7.rmNSJZ.0FxO/BTk76klW
的编码密码。有关如何存储密码的更多详细信息,请参见PasswordEncoder小节。
例 5。JDBCuserDetailsManager
爪哇
@Bean
UserDetailsManager users(DataSource dataSource) {
UserDetails user = User.builder()
.username("user")
.password("{bcrypt}$2a$10$GRLdNijSQMUvl/au9ofL.eDwmoohzzS7.rmNSJZ.0FxO/BTk76klW")
.roles("USER")
.build();
UserDetails admin = User.builder()
.username("admin")
.password("{bcrypt}$2a$10$GRLdNijSQMUvl/au9ofL.eDwmoohzzS7.rmNSJZ.0FxO/BTk76klW")
.roles("USER", "ADMIN")
.build();
JdbcUserDetailsManager users = new JdbcUserDetailsManager(dataSource);
users.createUser(user);
users.createUser(admin);
return users;
}
XML
<jdbc-user-service>
<user name="user"
password="{bcrypt}$2a$10$GRLdNijSQMUvl/au9ofL.eDwmoohzzS7.rmNSJZ.0FxO/BTk76klW"
authorities="ROLE_USER" />
<user name="admin"
password="{bcrypt}$2a$10$GRLdNijSQMUvl/au9ofL.eDwmoohzzS7.rmNSJZ.0FxO/BTk76klW"
authorities="ROLE_USER,ROLE_ADMIN" />
</jdbc-user-service>
Kotlin
@Bean
fun users(dataSource: DataSource): UserDetailsManager {
val user = User.builder()
.username("user")
.password("{bcrypt}$2a$10\$GRLdNijSQMUvl/au9ofL.eDwmoohzzS7.rmNSJZ.0FxO/BTk76klW")
.roles("USER")
.build();
val admin = User.builder()
.username("admin")
.password("{bcrypt}$2a$10\$GRLdNijSQMUvl/au9ofL.eDwmoohzzS7.rmNSJZ.0FxO/BTk76klW")
.roles("USER", "ADMIN")
.build();
val users = JdbcUserDetailsManager(dataSource)
users.createUser(user)
users.createUser(admin)
return users
}