天天看點

Spring Security3 實踐

Spring Security還是很強大的,即支援粗粒度的通路控制,還能支援精确到web元素的的控制。

首先,spring配置中添加對security的支援:

<!-- security configurations begin -->
	<security:http pattern="/login.jsp*" security="none"/>
	<security:http pattern="/jsp/js/**" security="none"/>
	<security:http pattern="/jsp/css/**" security="none"/>
	
	<!-- use-expressions='true' needs 'access' to be 'hasRole(role)' -->
	<!-- use-expression is optional,when u not use this, hasRole() can not be used neither. -->
	<security:http access-denied-page="/denied.jsp" use-expressions="true">
		<security:intercept-url pattern="/jsp/admin/**" access="hasRole('ROLE_ADMIN')"/>
		<security:intercept-url pattern="/**" access="hasRole('ROLE_USER')"/>
		<security:logout delete-cookies="true" logout-url="/do_logout"/>
		<security:form-login login-page="/login.jsp" login-processing-url="/do_security_check"
			authentication-failure-url="/login.jsp?error=t"
			default-target-url="/viewAllContacts.do"/>
		<!-- <security:remember-me key="contact_key" token-validity-seconds="600"/> -->
		<security:remember-me key="contact_key" data-source-ref="dataSource" token-validity-seconds="30"/>
	</security:http>
	
	<security:authentication-manager>
		<security:authentication-provider>
			<security:password-encoder hash="md5"/>
			
			<security:jdbc-user-service data-source-ref="dataSource" 
				users-by-username-query="select name_f,password_f,status_f from user_t where name_f=?"
				authorities-by-username-query="select user_f,role_f from user_role_t where user_f=?"/>
			 
			 <!--
			<security:user-service>
				<security:user name="admin" password="21232f297a57a5a743894a0e4a801fc3" authorities="ROLE_USER,ROLE_ADMIN"/>
				<security:user name="hello" password="5d41402abc4b2a76b9719d911017c592" authorities="ROLE_USER"/>
			</security:user-service>
			 -->
		</security:authentication-provider>
	</security:authentication-manager>
	<!-- security configuratios end -->
           

其中定義了角色ROLE_ADMIN和ROLE_USER都能通路所有資源,但是隻有ROLE_ADMIN能通路基于url為/jsp/admin/* 的資源。

如果form-login不做配置,則如果通路被拒絕的時候,會跳轉到spring提供的一個login form。

form-login中 login-processing-url 配置的路徑必須和web form中送出的url一緻。

其中user-service配置了兩種:

1.被注釋掉的是基于jdbc的,這需要在資料庫中建立幾張表:

mysql> desc user_t;

+------------+--------------+------+-----+---------+----------------+

| Field      | Type         | Null | Key | Default | Extra          |

+------------+--------------+------+-----+---------+----------------+

| id_f       | int(11)      | NO   | PRI | NULL    | auto_increment |

| name_f     | varchar(100) | YES  |     | NULL    |                |

| password_f | varchar(32)  | YES  |     | NULL    |                |

| status_f   | int(11)      | YES  |     | 1       |                |

+------------+--------------+------+-----+---------+----------------+

mysql> desc role_t;

+----------+--------------+------+-----+---------+----------------+

| Field    | Type         | Null | Key | Default | Extra          |

+----------+--------------+------+-----+---------+----------------+

| id_f     | int(11)      | NO   | PRI | NULL    | auto_increment |

| name_f   | varchar(100) | YES  |     | NULL    |                |

| status_f | int(11)      | YES  |     | 1       |                |

+----------+--------------+------+-----+---------+----------------+

mysql> desc user_role_t;

+--------+--------------+------+-----+---------+----------------+

| Field  | Type         | Null | Key | Default | Extra          |

+--------+--------------+------+-----+---------+----------------+

| id_f   | int(11)      | NO   | PRI | NULL    | auto_increment |

| user_f | varchar(100) | NO   |     |         |                |

| role_f | varchar(100) | NO   |     |         |                |

+--------+--------------+------+-----+---------+----------------+

2.第二種基于配置檔案的使用者名密碼管理,密碼是md5加密的

下面是login form:

<s:url var="authUrl" value="/do_security_check"/>
	<div id="login_box">
	<h3>Login for Contact</h3>
	<p class="error">${param.error=="t"?"authentication failed!":"" }</p>
	<form action="${authUrl }" method="post">
		<p>
			<label for="username">Username:</label>
			<input id="username" name="j_username" class="ipt"/>
		</p>
		<p>
			<label for="password">Password:</label>
			<input id="password" name="j_password" type="password" class="ipt"/>
		</p>
		<p>
			<input id="remember_me" type="checkbox" name="_spring_security_remember_me"/>
			<label for="remember_me">remember me?</label>
		</p>
		<p><input type="submit" value="login" class="btn"/></p>
	</form>
	</div>
           

如果直接通路某個未授權的資源,會彈回這個登入頁面,密碼驗證成功之後,跳轉到之前通路的資源頁面。

如果想指定web中某個按鈕或者連結隻在登入者具有admin權限的時候顯示,可以這樣:

<div style="width:500px;text-align:right">
				<spring:url var="baseUrl" value="/"/>
				welcome,<span style="color:blue;"><se:authentication property="principal.username"/></span>
				<a href="${baseUrl }do_logout" target="_blank" rel="external nofollow" >logout</a> 
				<se:authorize access="hasRole('ROLE_ADMIN')">
					<a href="${baseUrl }jsp/admin/index.jsp" target="_blank" rel="external nofollow" >admin</a>
				</se:authorize>
			</div>
           

下面是使用到的标簽申明:

<%@ taglib uri="http://www.springframework.org/tags/form" prefix="form" %>
<%@ taglib uri="http://www.springframework.org/tags" prefix="spring" %>
<%@ taglib uri="http://www.springframework.org/security/tags" prefix="se" %>
           

如果想使用https協定通路admin相關資源,可以這樣:

首先,在修改security配置:

<security:intercept-url pattern="/jsp/admin/**" requires-channel="https" access="hasRole('ROLE_ADMIN')"/>
		<security:intercept-url pattern="/**" access="hasRole('ROLE_USER')" requires-channel="http"/>
           

然後,修改tomcat配置檔案server.xml

<Connector protocol="org.apache.coyote.http11.Http11NioProtocol"   
           port="8443" minSpareThreads="5" maxSpareThreads="75"   
           enableLookups="true" disableUploadTimeout="true"     
           acceptCount="100"  maxThreads="200"   
           scheme="https" secure="true" SSLEnabled="true"   
           clientAuth="false" sslProtocol="TLS"   
           keystoreFile="d:\server.key"     
           keystorePass="admins"/>
           

Tomcat6.0.35 security connection(https) 配置

繼續閱讀