通過ch04,我們已經(jīng)知道Spring Security是通過UserDetailsService獲取用戶信息的,ch04中我們建立了基于內(nèi)存的用戶信息獲取服務(wù),并預(yù)先定義了一個(gè)用戶。那么在實(shí)際生產(chǎn)中,不可能采用這種方式,一般都是通過數(shù)據(jù)庫獲取用戶信息。那么我們就可以借助擴(kuò)展UserDetailsService實(shí)現(xiàn)。
1.內(nèi)存用戶信息獲取方式的流程
該圖為Spring Security3.0的說明,4.0后InMemoryDaoImpl已經(jīng)替換為InMemoryUserDetailsMananger
通過該圖我們可以知道,獲取用戶信息的需求是由DaoAuthenticationProvider要求的,該類包含類型為UserDetailsService成員變量,該變量就是用戶信息獲取服務(wù),也是我們需要替換的部分。
Spring Security提供了基于Jdbc的用戶信息獲取服務(wù)JdbcUserDetailsManager,該類實(shí)現(xiàn)了UserDetailsManager接口,后者繼承了UserDetailsService接口,增加了create、update、delete等方法,此外該類還包括DataSource屬性,實(shí)現(xiàn)了用戶信息與具體的數(shù)據(jù)庫的解耦。
Spring Security默認(rèn)提供了基于HSQLDB內(nèi)存數(shù)據(jù)庫的建表腳本,如果切換成其他數(shù)據(jù)庫需要修改腳本。默認(rèn)腳本位于classpath:org/springframework/security/core/userdetails/jdbc/users.ddl,下面給出MySql的腳本
SET FOREIGN_KEY_CHECKS=0;
-- ----------------------------
-- Table structure for authorities
-- ----------------------------
DROP TABLE IF EXISTS `authorities`;
CREATE TABLE `authorities` (
`username` varchar(50) NOT NULL,
`authority` varchar(50) NOT NULL,
UNIQUE KEY `ix_auth_username` (`username`,`authority`),
CONSTRAINT `fk_authorities_users` FOREIGN KEY (`username`) REFERENCES `users` (`username`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
-- ----------------------------
-- Records of authorities
-- ----------------------------
INSERT INTO `authorities` VALUES ('admin', 'ROLE_ADMIN');
INSERT INTO `authorities` VALUES ('admin', 'ROLE_USER');
INSERT INTO `authorities` VALUES ('user', 'ROLE_USER');
-- ----------------------------
-- Table structure for users
-- ----------------------------
DROP TABLE IF EXISTS `users`;
CREATE TABLE `users` (
`username` varchar(50) NOT NULL,
`password` varchar(500) NOT NULL,
`enabled` tinyint(1) NOT NULL,
PRIMARY KEY (`username`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
-- ----------------------------
-- Records of users
-- ----------------------------
INSERT INTO `users` VALUES ('admin', 'password', '1');
INSERT INTO `users` VALUES ('user', 'password', '1');
SET FOREIGN_KEY_CHECKS=1;
該腳本創(chuàng)建了user表并插入了兩條數(shù)據(jù)。
數(shù)據(jù)庫準(zhǔn)備好了,只需要增加一項(xiàng)配置即可將內(nèi)存用戶信息服務(wù)替換為數(shù)據(jù)庫服務(wù)。修改WebSecurityConfigurerAdapter,增加數(shù)據(jù)庫獲取用戶信息服務(wù)配置。
@Autowired
public void configureGlobal(AuthenticationManagerBuilder auth, DataSource dataSource) throws Exception {
auth
.jdbcAuthentication()
.dataSource(dataSource);
}
其中dataSource為我們配置的MySql的數(shù)據(jù)源。
啟動(dòng)服務(wù)器,可以測(cè)試user和admin連個(gè)用戶的登錄、注銷與Remember Me.
代碼示例https://github.com/wexgundam/spring.security/tree/master/ch05