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