目錄
<a href="#_Toc437507343">1.1 authorize</a>
<a href="#_Toc437507344">1.2 authentication</a>
<a href="#_Toc437507345">1.3 accesscontrollist</a>
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的标簽庫提供的标簽了。
authorize是用來判斷普通權限的,通過判斷使用者是否具有對應的權限而控制其所包含内容的顯示,其可以指定如下屬性。
1、access
access屬性需要使用表達式來判斷權限,當表達式的傳回結果為true時表示擁有對應的權限。
<sec:authorize access="hasRole('admin')">
<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 ifAnyGranted="ROLE_USER,ROLE_ADMIN">hello</sec:authorize>
<!-- 不允許擁有指定的任意權限 -->
<sec:authorize ifNotGranted="ROLE_ADMIN">
<a href="user.jsp">user</a>
3、url
url表示如果使用者擁有通路指定url的權限即表示可以顯示authorize标簽包含的内容。
<!-- 擁有通路指定url的權限才顯示其中包含的内容 -->
<sec:authorize url="/admin.jsp">
4、method
method屬性是配合url屬性一起使用的,表示使用者應當具有指定url指定method通路的權限,method的預設值為GET,可選值為http請求的7種方法。
限制通路方法是通過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/>
上述權限的鑒定結果是:${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權限的使用者才被允許擷取指定的内容。
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。
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所寫)