1,配置過濾器
為了在項目中使用Spring
Security控制許可權,首先要在web.xml中配置過濾器,這樣我們就可以控制對這個項目的每個請求了。
<filter>
<filter-name>springSecurityFilterChain</filter-name>
<filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
</filter>
<filter-mapping>
<filter-name>springSecurityFilterChain</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
2,使用命名空間
在ApplicationContext.XML中配置或者另外單獨使用一個Security.XML都可以,我們這裡使用單獨的xml來對Security進行配置.
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:security="http://www.springframework.org/schema/security"
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">
</beans>
我們通常使用"security"作為預設的命名空間,而不是"beans",這意味著我們可以省略所有security命名空間元素的首碼,使上下文更容易閱讀
<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">
</beans:beans>
3,配置認證提供介面和使用者資訊(這裡使用記憶體使用者)
<global-method-security
pre-post-annotations="enabled">
</global-method-security>
<http
use-expressions="true"
access-denied-page="/AccessDenied.jsp">
<intercept-url
pattern="/**" access="hasRole('ROLE_USER')" />
<form-login />
</http>
<authentication-manager>
<authentication-provider>
<user-service>
<user
name="rod" password="rod"
authorities="ROLE_SUPERVISOR,
ROLE_USER, ROLE_TELLER" />
</user-service>
</authentication-provider>
</authentication-manager>
<beans:bean
id="loggerListener"
class="org.springframework.security.authentication.event.LoggerListener"
/>
這裡配置pre-post-annotations="enabled"可以在介面函數(必須在介面中聲明)/頁面使用標籤/運算式進行許可權判斷
- 如下運算式要求使用者必須具備ROLE_SUPERVISOR角色才能調用
import
org.springframework.security.access.prepost.PreAuthorize;
import
sshDemo.Entities.*;
public
interface IOwnerService {
@PreAuthorize("hasRole('ROLE_SUPERVISOR')")
public
List<Owners> getOwners();
}
運算式基於
org.springframework.security.access.expression.SecurityExpressionRoot類提供許可權判斷.
- 另外也可以在頁面中使用授權標籤如下的sec:authorize要求具備ROLE_SUPERVISOR或者ROLE_TELLER才能使用該連結.
<%@
taglib prefix="s" uri="/struts-tags"%>
<%@
taglib prefix="sec" uri="http://www.springframework.org/security/tags"
%>
<sec:authorize
access="hasAnyRole('ROLE_SUPERVISOR','ROLE_TELLER')">
<a
href="<s:url action='listAction'/>">List</a>
</sec:authorize>
security:authorize 標籤聲明下面的屬性:
- ifAllGranted:這個標籤列出的所有角色必須授權,才能輸出標籤的內容。
- ifAnyGranted:任何一個這個標籤列出的角色必須授權,才能輸出標籤的內容。
- ifNotGranted:這個標籤列出的角色沒有一個是授權的,才能輸出標籤的內容。
3,使用自訂登陸頁面
建立login.jsp
<%@
page language="java" import="java.util.*"
pageEncoding="UTF-8"%>
<%
String
path = request.getContextPath();
String
basePath =
request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>
<!DOCTYPE
HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<%@taglib
prefix="c" uri="http://java.sun.com/jstl/core_rt"%>
<html>
<head>
<base
href="<%=basePath%>">
<title>Login</title>
<meta
http-equiv="pragma" content="no-cache">
<meta
http-equiv="cache-control" content="no-cache">
<meta
http-equiv="expires" content="0">
<meta
http-equiv="keywords"
content="keyword1,keyword2,keyword3">
<meta
http-equiv="description" content="This is my page">
</head>
<body>
<c:if test="${param.error}">
<font color="red"> Your
login attempt was not successful, try
again.<br />
<br />
Reason: <c:out
value="${SPRING_SECURITY_LAST_EXCEPTION.message}"/>.
</font>
</c:if>
<form
action="${pageContext.request.contextPath}/j_spring_security_check"
style="width:260px;text-align:center;" method="post">
<fieldset>
<legend>登陸</legend>
使用者: <input type="text"
name="j_username" style="width:150px;"
value="${sessionScope['SPRING_SECURITY_LAST_USERNAME']}"/><br
/>
密碼: <input type="password"
name="j_password" style="width:150px;" /><br />
<input type="checkbox"
name="_spring_security_remember_me" />兩周之內不必登陸<br />
<input type="submit"
value="登陸"/>
<input type="reset"
value="重設"/>
</fieldset>
</form>
</body>
</html>
配置登陸介面
<http>
...
<form-login
login-page="/login.jsp"
authentication-failure-url="/login.jsp?error=true"
default-target-url="/"
/>
...
</http>
4,配置退出操作
在頁面中添加退出操作
<a
href="j_spring_security_logout">Logout</a>
配置退出操作
<http>
...
<logout
logout-success-url="/login.jsp" />
...
</http>
5,配置訪問拒絕操作
建立訪問拒絕頁面
<%@
page contentType="text/html; charset=GBK" %>
<html>
<head></head>
<body
>
<div
id="header"></div>
<div id="content"
style="width: 60%">
<strong>Access
Denied</strong>
</div>
</body>
</html>
配置訪問拒絕重新導向頁面
<http
access-denied-page="/AccessDenied.jsp">
...
</http>
6,運行調試
注意事項:
1,如果跟Struts2結合使用需要將spring
security的配置放在struts2前面防止struts2將相應的處理截取出現如下錯誤:
Q:為何登入時出現There is
no Action mapped for namespace
/ and action name j_spring_security_check.
A:這是因為登陸所發送的請求先被struts2的過濾器攔截了,為了試登陸請求可以被Spring Security正常處理,需要在web.xml中將Spring Security的過濾器放在struts2之前。
2,Struts結合Spring
Security使用時出現Access Denied但是沒有跳到對應的AccessDenied.jsp頁面.
Q:Access Denied但是沒有跳到對應的AccessDenied.jsp頁面.
A:解決方案還沒有