Spring Security默認提供的表結構太過簡單了,其實就算默認提供的表結構很復雜,也無法滿足所有企業內部對用戶信息和權限信息管理的要求。基本上每個企業內部都有一套自己的用戶信息管理結構,同時也會有一套對應的權限信息體系,如何讓Spring Security在這些已有的數據結構之上運行呢?
自定義表結構
-- 角色 create table role( id bigint, name varchar(50), descn varchar(200) ); alter table role add constraint pk_role primary key(id); alter table role alter column id bigint generated by default as identity(start with 1); -- 用戶 create table user( id bigint, username varchar(50), password varchar(50), status integer, descn varchar(200) ); alter table user add constraint pk_user primary key(id); alter table user alter column id bigint generated by default as identity(start with 1); -- 用戶角色連接表 create table user_role( user_id bigint, role_id bigint ); alter table user_role add constraint pk_user_role primary key(user_id, role_id); alter table user_role add constraint fk_user_role_user foreign key(user_id) references user(id); alter table user_role add constraint fk_user_role_role foreign key(role_id) references role(id);
上述共有三張表,其中user用戶表,role角色表為保存用戶權限數據的主表,user_role為關聯表。user用戶表,role角色表之間為多對多關系,就是說一個用戶可以有多個角色。ER圖如下所示:
初始化數據
創建兩個用戶,admin和user。admin用戶擁有“管理員”角色,user用戶擁有“用戶”角色。
insert into user(id,username,password,status,descn) values(1,'admin','admin',1,'管理員'); insert into user(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=?"/>
將語句配置到xml中
<authentication-provider>
<jdbc-user-service data-source-ref="dataSource"
1users-by-username-query="select username,password,status as enabled
from user
where username=?"
2authorities-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為根據用戶名查找權限,系統通過傳入的用戶名查詢當前用戶已被授予的所有權限。
