JDBC 驗證
Spring Security 的 JdbcDaoImpl
實作 UserDetailsService
,以提供透過 JDBC 檢索的使用者名稱和密碼基礎驗證支援。JdbcUserDetailsManager
擴充 JdbcDaoImpl
以透過 UserDetailsManager
介面提供 UserDetails
的管理。當 Spring Security 設定為接受使用者名稱/密碼進行驗證時,Spring Security 會使用 UserDetails
基礎驗證。
在以下章節中,我們將討論
-
Spring Security JDBC 驗證使用的預設結構描述
預設結構描述
Spring Security 為 JDBC 基礎驗證提供預設查詢。本節提供與預設查詢相對應的預設結構描述。您需要調整結構描述,以符合對查詢和您使用的資料庫方言所做的任何自訂。
使用者結構描述
JdbcDaoImpl
需要資料表來載入使用者的密碼、帳戶狀態(啟用或停用)和權限(角色)清單。
預設結構描述也以類別路徑資源的形式公開,名為 |
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 是一種熱門的資料庫選擇,但需要稍微不同的結構描述
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;
群組結構描述
如果您的應用程式使用群組,您需要提供群組結構描述
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)
);
設定 DataSource
在我們設定 JdbcUserDetailsManager
之前,我們必須建立 DataSource
。在我們的範例中,我們設定一個嵌入式 DataSource,該資料來源使用預設使用者結構描述初始化。
-
Java
-
XML
-
Kotlin
@Bean
DataSource dataSource() {
return new EmbeddedDatabaseBuilder()
.setType(H2)
.addScript(JdbcDaoImpl.DEFAULT_USER_SCHEMA_DDL_LOCATION)
.build();
}
<jdbc:embedded-database>
<jdbc:script location="classpath:org/springframework/security/core/userdetails/jdbc/users.ddl"/>
</jdbc:embedded-database>
@Bean
fun dataSource(): DataSource {
return EmbeddedDatabaseBuilder()
.setType(H2)
.addScript(JdbcDaoImpl.DEFAULT_USER_SCHEMA_DDL_LOCATION)
.build()
}
在生產環境中,您會希望確保您設定與外部資料庫的連線。
JdbcUserDetailsManager Bean
在本範例中,我們使用 Spring Boot CLI 編碼 password
的密碼值,並取得編碼後的密碼 {bcrypt}$2a$10$GRLdNijSQMUvl/au9ofL.eDwmoohzzS7.rmNSJZ.0FxO/BTk76klW
。如需有關如何儲存密碼的更多詳細資訊,請參閱 PasswordEncoder 章節。
-
Java
-
XML
-
Kotlin
@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;
}
<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>
@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
}