前面幾節都是將用戶以及權限都配置在配置文件,在企業中,這種方法是不可取的,因此,我們今天來將用戶信息以及權限信息移到數據庫。
爲了從數據庫中獲取用戶權限信息,我們所需要的僅僅是修改配置文件中的authentication-provider部分,將文件中的user-service替換爲jdbc-user-service,替換內容如下所示:
<authentication-manager alias="authenticationManager"> <authentication-provider> <jdbc-user-service data-source-ref="dataSource"/> </authentication-provider> </authentication-manager>
從上面可以看出來需要數據源,現在我們就在Spring的dogstore-base.xml裏面添加數據源,典型的配置如下:
<context:property-placeholder location="/WEB-INF/jdbc.properties"/> <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource"> <property name="driverClassName" value="${jdbc.driverClassName}"/> <property name="url" value="${jdbc.url}"/> <property name="username" value="${jdbc.username}"/> <property name="password" value="${jdbc.password}"/> </bean>
jdbc.properties:
jdbc.driverClassName=oracle.jdbc.driver.OracleDriver jdbc.url=jdbc:oracle:thin:@localhost:1521:orcl jdbc.username=project jdbc.password=project
注意添加BasicDataSource數據源的三個jar以及jdbc所以jar。
Spring Security默認情況下需要兩張表,用戶表和權限表。以下是oracle中的建表語句:
create table users( username varchar(50) not null primary key, password varchar(50) not null, enabled char(2) ); create table authorities ( username varchar(50) not null, authority varchar(50) not null );
Spring Security會在初始化時,從這兩張表中獲得用戶信息和對應權限,將這些信息保存到緩存中。其中users表中的登錄名和密碼用來控制用戶的登錄,而權限表中的信息用來控制用戶登陸後是否有權限訪問受保護的系統資源。
insert into users(username,password,enabled) values('admin','admin',1); insert into users(username,password,enabled) values('user','user',1); insert into authorities(username,authority) values('admin','ROLE_ADMIN'); insert into authorities(username,authority) values('admin','ROLE_USER'); insert into authorities(username,authority) values('user','ROLE_USER');
注意將前一章節做的ipTokenBasedRememberMeServicesBean這個註釋掉,因爲沒有提供userService。
其實在企業中,上面兩張表關於權限控制過於簡單,因此很多企業都是自己設計滿足自身業務的表單以及自身對應的權限控制體系,那我們怎麼讓Spring Security來運行在自身設計的權限控制上呢?
普遍的企業做法是,用戶表、角色表、角色用戶關聯表這三張表來設計權限控制,我們下面也是基於這種思想來設計:
-- 角色 create table role( id number(11), name varchar(50), descn varchar(200) ); -- 用戶 create table USERS( id number(11), username varchar(50), password varchar(50), status number(11), descn varchar(200) ); -- 用戶角色連接表 create table user_role( user_id number(11), role_id number(11) ); --添加主鍵、外鍵 alter table role add constraint pk_role primary key(id); alter table "USER" add constraint pk_user primary key(id); ALTER TABLE user_role ADD CONSTRAINT FK_user_id FOREIGN KEY(user_id) REFERENCES "USER"(id); ALTER TABLE user_role add constraint fk_role_id foreign key(role_id) references role(id); --添加數據insert into USERS(id,username,password,status,descn) values(1,'admin','admin',1,'管理員');
insert into USERS(id,username,password,status,descn) values(2,'user','user',1,'用戶');
insert into role(id,name,descn) values(1,'ROLE_ADMIN','管理員角色');
insert into role(id,name,descn) values(2,'ROLE_USER','用戶角色');
insert into user_role(user_id,role_id) values(1,1);
insert into user_role(user_id,role_id) values(1,2);
insert into user_role(user_id,role_id) values(2,2);
現在我們要在這樣的數據結構基礎上使用Spring Security,Spring Security所需要的數據只是爲了處理兩種情況,一是判斷登錄用戶是否合法,二是判斷登陸的用戶是否有權限訪問受保護的系統資源。
我們所要做的工作就是在現有數據結構的基礎上,爲Spring Security提供這兩種數據:
處理用戶登陸
select username,password,status as enabled from user where username=?
檢驗用戶權限
select u.username,r.name as authority from user u join user_role ur on u.id=ur.user_id join role r on r.id=ur.role_id where u.username=?
現在我們修改一下配置文件:
<authentication-provider> <jdbc-user-service data-source-ref="dataSource" users-by-username-query="select username,password,status as enabled from user where username=?" authorities-by-username-query="select u.username,r.name as authority from user u join user_role ur on u.id=ur.user_id join role r on r.id=ur.role_id where u.username=?"/> </authentication-provider>
users-by-username-query爲根據用戶名查找用戶,系統通過傳入的用戶名查詢當前用戶的登錄名,密碼和是否被禁用這一狀態。 | |
authorities-by-username-query爲根據用戶名查找權限,系統通過傳入的用戶名查詢當前用戶已被授予的所有權限。 |