在上一篇博客中講解了用Spring Security自帶的默認數據庫存儲用戶和權限的數據,但是Spring Security默認提供的表結構太過簡單了,其實就算默認提供的表結構很復雜,也不一定能滿足項目對用戶信息和權限信息管理的要求。那么接下來就講解如何自定義數據庫實現對用戶信息和權限信息的管理。
一 自定義表結構
這里還是用的mysql數據庫,所以pom.xml文件都不用修改。這里只要新建三張表即可,user表、role表、user_role表。其中user用戶表,role角色表為保存用戶權限數據的主表,user_role為關聯表。user用戶表,role角色表之間為多對多關系,就是說一個用戶可以有多個角色。ER圖如下所示:
建表語句:
-- 角色
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);
插入數據:
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的配置文件(applicationContext.xml)
現在我們要在這樣的數據結構基礎上使用Spring Security,Spring Security所需要的數據無非就是為了處理兩種情況,一是判斷登錄用戶是否合法,二是判斷登陸的用戶是否有權限訪問受保護的系統資源。因此我們所要做的工作就是在現有數據結構的基礎上,為Spring Security提供這兩種數據。
在jdbc-user-service標簽中有這樣兩個屬性:
1. users-by-username-query為根據用戶名查找用戶,系統通過傳入的用戶名查詢當前用戶的登錄名,密碼和是否被禁用這一狀態。
2.authorities-by-username-query為根據用戶名查找權限,系統通過傳入的用戶名查詢當前用戶已被授予的所有權限。
同時通過代碼提示能看到這兩個屬性的sql語句格式:


從圖中可以看到第一個屬性要的是通過username來查詢用戶名、密碼和是否可用;第二個屬性是通過username來查詢用戶權限,所以在我們自定義的表結構的基礎上對sql語句進行修改,得到如下語句:
select username,password,status as enabled from user where username = ?
select user.username,role.name from user,role,user_role where user.id=user_role.user_id and user_role.role_id=role.id and user.username=?
這樣最終得到的配置文件如下:
<?xml version="1.0" encoding="UTF-8"?>
<beans:beans xmlns="http://www.springframework.org/schema/security"
xmlns:beans="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.1.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-3.0.xsd
http://www.springframework.org/schema/security
http://www.springframework.org/schema/security/spring-security.xsd">
<http auto-config='true'>
<intercept-url pattern="/adminPage.jsp" access="ROLE_ADMIN" />
<intercept-url pattern="/**" access="ROLE_USER" />
</http>
<!-- 數據源 -->
<beans:bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource"
destroy-method="close">
<!-- 此為c3p0在spring中直接配置datasource c3p0是一個開源的JDBC連接池 -->
<beans:property name="driverClass" value="com.mysql.jdbc.Driver" />
<beans:property name="jdbcUrl"
value="jdbc:mysql://localhost:3306/springsecuritydemo?useUnicode=true&characterEncoding=UTF-8" />
<beans:property name="user" value="root" />
<beans:property name="password" value="" />
<beans:property name="maxPoolSize" value="50"></beans:property>
<beans:property name="minPoolSize" value="10"></beans:property>
<beans:property name="initialPoolSize" value="10"></beans:property>
<beans:property name="maxIdleTime" value="25000"></beans:property>
<beans:property name="acquireIncrement" value="1"></beans:property>
<beans:property name="acquireRetryAttempts" value="30"></beans:property>
<beans:property name="acquireRetryDelay" value="1000"></beans:property>
<beans:property name="testConnectionOnCheckin" value="true"></beans:property>
<beans:property name="idleConnectionTestPeriod" value="18000"></beans:property>
<beans:property name="checkoutTimeout" value="5000"></beans:property>
<beans:property name="automaticTestTable" value="t_c3p0"></beans:property>
</beans:bean>
<authentication-manager>
<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 user.username,role.name from user,role,user_role
where user.id=user_role.user_id and
user_role.role_id=role.id and user.username=?"/>
</authentication-provider>
</authentication-manager>
</beans:beans>
其他的文件和配置和教程二(Spring Security教程(二))完全一樣,請參考教程二
三 結果
---------------------
作者:AirMario
來源:CSDN
原文:https://blog.csdn.net/AirMario/article/details/53976993
