Spring Security(18)——Jsp標籤
Spring Security也有對Jsp標籤的支援的標籤庫。其中一共定義了三個標籤:authorize、authentication和accesscontrollist。其中authentication標籤是用來代表當前Authentication物件的,我們可以利用它來展示當前Authentication物件的相關資訊。另外兩個標籤是用於許可權控制的,可以利用它們來包裹需要保護的內容,通常是超連結和按鈕。
如果需要使用Spring Security的標籤庫,那麼首先我們應當將對應的jar包spring-security-taglibs-xxx.jar放入WEB-INF/lib下;其次我們需要在頁面上引入Spring Security的標籤庫。
<%@ taglib prefix="sec" uri="http://www.springframework.org/security/tags" %>
接下來就可以在頁面上自由的使用Spring Security的標籤庫提供的標籤了。
1.1 authorize
authorize是用來判斷普通許可權的,通過判斷使用者是否具有對應的許可權而控制其所包含內容的顯示,其可以指定如下屬性。
1、access
access屬性需要使用表示式來判斷許可權,當表示式的返回結果為true時表示擁有對應的許可權。
<sec:authorize
<a href="admin.jsp">admin page</a>
</sec:authorize>
需要注意的是因為access屬性是使用表示式的,所以我們必須確保ApplicationContext中存在一個WebSecurityExpressionHandler,最簡單的辦法就是直接使用NameSpace,通過設定http元素的use-expressions="true"讓NameSpace自動為我們建立一個WebSecurityExpressionHandler。
2、ifAllGranted、ifAnyGranted和ifNotGranted
這三個屬性的用法類似,它們都接收以逗號分隔的許可權列表,且不能使用表示式。ifAllGranted表示需要包含所有的許可權,ifAnyGranted表示只需要包含其中的任意一個即可,ifNotGranted表示不能包含指定的任意一個許可權。
<!-- 需要擁有所有的許可權 -->
<sec:authorize ifAllGranted="ROLE_ADMIN">
<a href="admin.jsp">admin</a>
</sec:authorize>
<!-- 只需擁有其中任意一個許可權 -->
<sec:authorize ifAnyGranted="ROLE_USER,ROLE_ADMIN">hello</sec:authorize>
<!-- 不允許擁有指定的任意許可權 -->
<sec:authorize ifNotGranted="ROLE_ADMIN">
<a href="user.jsp">user</a>
</sec:authorize>
3、url
url表示如果使用者擁有訪問指定url的許可權即表示可以顯示authorize標籤包含的內容。
<!-- 擁有訪問指定url的許可權才顯示其中包含的內容 -->
<sec:authorize url="/admin.jsp">
<a href="admin.jsp">admin</a>
</sec:authorize>
4、method
method屬性是配合url屬性一起使用的,表示使用者應當具有指定url指定method訪問的許可權,method的預設值為GET,可選值為http請求的7種方法。
<!-- 擁有訪問指定url的許可權才顯示其中包含的內容 -->
<sec:authorize url="/admin.jsp">
<a href="admin.jsp">admin</a>
</sec:authorize>
限制訪問方法是通過http元素下的intercept-url元素的method屬性來指定的,如:
<security:intercept-url pattern="/admin.jsp" access="ROLE_ADMIN" method="POST"/>
5、var
用於指定將許可權鑑定的結果存放在pageContext的哪個屬性中。該屬性的主要作用是對於在同一頁面的多個地方具有相同許可權鑑定時,我們只需要定義一次,然後將鑑定結果以var指定的屬性名存放在pageContext中,其它地方可以直接使用之前的鑑定結果。
<sec:authorize access="isFullyAuthenticated()" var="isFullyAuthenticated">
只有通過登入介面進行登入的使用者才能看到1。<br/>
</sec:authorize>
上述許可權的鑑定結果是:${isFullyAuthenticated }<br/>
<%if((Boolean)pageContext.getAttribute("isFullyAuthenticated")) {%>
只有通過登入介面進行登入的使用者才能看到2。
<%}%>
各屬性對應的優先順序
既然我們可以通過屬性access、url、ifAllGranted、ifAnyGranted等來指定應當具有的許可權,那麼當同時指定多個屬性時,它們的作用效果是什麼樣的呢?authorize標籤進行許可權鑑定的屬性根據優先順序的不同可以分為三類,access為一類;url為一類;ifAllGranted、ifAnyGranted和ifNotGranted為一類。這三類將同時只有一類產生效果。它們的優先順序如下:
1、access具有最高的優先順序,如果指定了access屬性,那麼將以access屬性指定的表示式來鑑定當前使用者是否有許可權。不管結果如何,此時其它屬性都將被忽略。
2、如果沒有指定access屬性,那麼url屬性將具有最高優先順序,此時將直接通過url屬性和method屬性(預設為GET)來鑑定當前使用者是否有許可權。不管結果如何,此時都將忽略ifAllGranted、ifAnyGranted和ifNotGranted屬性。
3、如果access和url都沒有指定,那麼將使用第三類屬性來鑑定當前使用者的許可權。當第三類裡面同時指定了多個屬性時,它們將都發生效果,即必須指定的三類許可權都滿足才認為是有對應的許可權。如ifAllGranted要求有ROLE_USER的許可權,同時ifNotGranted要求不能有ROLE_ADMIN的許可權,則結果是它們的並集,即只有擁有ROLE_USER許可權,同時不擁有ROLE_ADMIN許可權的使用者才被允許獲取指定的內容。
1.2 authentication
authentication標籤用來代表當前Authentication物件,主要用於獲取當前Authentication的相關資訊。authentication標籤的主要屬性是property屬性,我們可以通過它來獲取當前Authentication物件的相關資訊。如通常我們的Authentication物件中存放的principle是一個UserDetails物件,所以我們可以通過如下的方式來獲取當前使用者的使用者名稱。
<sec:authentication property="principal.username"/>
當然,我們也可以直接通過Authentication的name屬性來獲取其使用者名稱。
<sec:authentication property="name"/>
property屬性只允許指定Authentication所擁有的屬性,可以進行屬性的級聯獲取,如“principle.username”,不允許直接通過方法進行呼叫。
除了property屬性之外,authentication還可以指定的屬性有:var、scope和htmlScape。
var屬性
var屬性用於指定一個屬性名,這樣當獲取到了authentication的相關資訊後會將其以var指定的屬性名進行存放,預設是存放在pageConext中。可以通過scope屬性進行指定。此外,當指定了var屬性後,authentication標籤不會將獲取到的資訊在頁面上進行展示,如需展示使用者應該通過var指定的屬性進行展示,或去掉var屬性。
<!-- 將獲取到的使用者名稱以屬性名username存放在session中 -->
<sec:authentication property="principal.username" scope="session" var="username"/>
${username }
scope屬性
與var屬性一起使用,用於指定存放獲取的結果的屬性名的作用範圍,預設我pageContext。Jsp中擁有的作用範圍都進行進行指定。
htmlScape屬性
表示是否需要將html進行轉義。預設為true。
1.3 accesscontrollist
accesscontrollist標籤是用於鑑定ACL許可權的。其一共定義了三個屬性:hasPermission、domainObject和var,其中前兩個是必須指定的。hasPermission屬性用於指定以逗號分隔的許可權列表;domainObject用於指定對應的域物件;而var則是用以將鑑定的結果以指定的屬性名存入pageContext中,以供同一頁面的其它地方使用。需要注意的是使用accesscontrollist標籤時ApplicationContext中必須存在一個PermissionEvaluator bean,因為accesscontrollist標籤就是通過PermissionEvaluator來鑑定對應的許可權的。如果我們正在使用Spring Security的ACL模組,那麼PermissionEvaluator通常就對應著AclPermissionEvaluator。此外,如果domainObject屬性指定的domainObject為null則預設認為是有許可權的,否則如果當前Authentication物件為null則預設認為是沒有許可權的。
<sec:accesscontrollist hasPermission="1,2" domainObject="${someTargetDomainObject }" >
如果當前Authentication對指定的domainObject擁有指定的hasPermission則將可以看到這部分內容。
</sec:accesscontrollist>
(注:本文是基於Spring Security3.1.6所寫)