Spring Security逐步深入

      上面的一個 Spring Security 的 demo 雖然使用了數據庫來實現權限的控制,但是對於在項目中的應用來說這樣的表結構過於簡單,遠遠無法滿足我們的需求。現在來實現自定義數據表從而達到權限的控制。下面給出創建自定義數據表的SQL(MySQL)語句。

SQL語句:

-- 角色
create table role(
  id bigint,
  name varchar(50),
  descn varchar(200)
);

ALTER TABLE `role` MODIFY COLUMN `id` BIGINT(20) NOT NULL AUTO_INCREMENT,
ADD PRIMARY KEY (`id`);

-- 用戶
create table user(
  id bigint,
  username varchar(50),
  password varchar(50),
  status integer,
  descn varchar(200)
);

ALTER TABLE `user` MODIFY COLUMN `id` BIGINT(20) NOT NULL AUTO_INCREMENT,
ADD PRIMARY KEY (`id`);

-- 用戶角色連接表
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的配置:

<?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/security 
                        		http://www.springframework.org/schema/security/spring-security-3.0.xsd">

	<!-- 指定被拒絕的頁面 -->
	<http auto-config='true' access-denied-page="/accessDenied.jsp">
		<!--
			login-page表示用戶登陸時顯示我們自定義的login.jsp
			authentication-failure-url表示用戶登陸失敗時,跳轉到哪個頁面,並添加一個error=true參數作爲登陸失敗的標示
			default-target-url表示登陸成功時,跳轉到哪個頁面
		-->
		<form-login login-page="/login.jsp" 
			authentication-failure-url="/login.jsp?error=true" 
			default-target-url="/index.jsp" 
		/>
		<!--登錄頁面不進行過濾,後面加一個*那是因爲請求頁面後面會帶參數-->
		<intercept-url pattern="/login.jsp*" filters="none"/>
		<intercept-url pattern="/admin.jsp" access="ROLE_ADMIN" />
		<intercept-url pattern="/**" access="ROLE_USER" />
		<!-- 檢測失效的sessionId,超時時定位到另外一個URL -->
		<session-management invalid-session-url="/sessionTimeout.jsp" >
			 <!-- 
				防止第二次登錄
				如果想讓第一次登錄失效第二次登錄啓用則不要配置error-if-maximum-exceeded="true"
			  -->
			<concurrency-control max-sessions="1" error-if-maximum-exceeded="true"/>
		</session-management>
	</http>
	<authentication-manager>
		<authentication-provider>
			<!-- 
			(1) users-by-username-query:根據條件用戶名查找用戶的:username,passwd和enabled狀態;
			(2) authorities-by-username-query: 根據條件用戶名查找用戶被授予的權限;
			 -->
			<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>
	</authentication-manager>
	
	<!-- 國際化 -->
	<beans:bean id="messageSource" class="org.springframework.context.support.ReloadableResourceBundleMessageSource">
	  <!-- 如果不加載自己的國際化文件,去加載 Security 內部的國際化文件classpath:org/springframework/security/messages_zh_CN -->
	  <beans:property name="basename" value="classpath:messages_zh_CN"/>
	</beans:bean>
	
</beans:beans>

 關鍵的配置在此:

<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=?" 
/>

 在上一個的例子基礎之上進行如下的配置,運行程序達到自定義user用戶表與role角色表,並通過兩張表的中間表進行關聯實現權限控制。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章