{"id":772,"date":"2012-02-26T23:53:49","date_gmt":"2012-02-26T22:53:49","guid":{"rendered":"http:\/\/doanduyhai.wordpress.com\/?p=772"},"modified":"2012-02-26T23:53:49","modified_gmt":"2012-02-26T22:53:49","slug":"spring-security-part-v-security-tags","status":"publish","type":"post","link":"https:\/\/www.doanduyhai.com\/blog\/?p=772","title":{"rendered":"Spring Security part V : Security tags"},"content":{"rendered":"<p>Today we discuss about the security tags provided with Spring Security package. These tags allow you to customize your web pages to include\/exclude elements based on user roles and credentials<\/p>\n<p><!--more--><\/p>\n<blockquote><p>The below description of Spring Security Tag is based on official <strong>Spring Security 3.1.0 RELEASE<\/strong>. It may not apply to older versions\n<\/p><\/blockquote>\n<h1>I Configuration<\/h1>\n<p>To enable JSP page-level security, we need to import the Spring Security tag library as follow:<\/p>\n<pre class=\"brush: xml; title: ; wrap-lines: false; notranslate\" title=\"\">\n&amp;lt;%@ taglib prefix=&amp;quot;sec&amp;quot; uri=&amp;quot;http:\/\/www.springframework.org\/security\/tags&amp;quot; %&amp;gt;\n<\/pre>\n<p>We also need to add the spring security taglib Maven dependency into our project pom.xml<\/p>\n<pre class=\"brush: xml; title: ; wrap-lines: false; notranslate\" title=\"\">\n  \t&amp;lt;dependency&amp;gt;\n  \t\t&amp;lt;groupId&amp;gt;org.springframework.security&amp;lt;\/groupId&amp;gt;\n  \t\t&amp;lt;artifactId&amp;gt;spring-security-taglibs&amp;lt;\/artifactId&amp;gt;\n  \t\t&amp;lt;version&amp;gt;3.1.0.RELEASE&amp;lt;\/version&amp;gt;\n  \t\t&amp;lt;type&amp;gt;jar&amp;lt;\/type&amp;gt;\n  \t\t&amp;lt;scope&amp;gt;compile&amp;lt;\/scope&amp;gt;\n  \t&amp;lt;\/dependency&amp;gt;\n<\/pre>\n<h1>II Security tags<\/h1>\n<p>&nbsp;<\/p>\n<h3>A  The <em>Authorization<\/em> tag<\/h3>\n<p>To enable the rendering of some portion based on user credentials, we can rely on the <strong>&lt;sec:authorize&gt;<\/strong> tag:<\/p>\n<pre class=\"brush: xml; title: ; wrap-lines: false; notranslate\" title=\"\">\n&amp;lt;sec:authorize access=&amp;quot;hasRole('admin')&amp;quot;&amp;gt;\n\t&amp;lt;table&amp;gt;\n  \t\t&amp;lt;tr&amp;gt;\n  \t  \t  \t&amp;lt;td&amp;gt;xxx&amp;lt;\/td&amp;gt;\n  \t  \t  \t&amp;lt;!-- Some administrator data here --&amp;gt;\n  \t  \t&amp;lt;\/tr&amp;gt;\n  \t&amp;lt;\/table&amp;gt;\n&amp;lt;\/sec:authorize&amp;gt;\n\n&amp;lt;sec:authorize access=&amp;quot;hasRole('guest')&amp;quot;&amp;gt;\n\tRestricted data, you are not allowed to access this resource  \t\n&amp;lt;\/sec:authorize&amp;gt;\n<\/pre>\n<p> The &#8220;<strong>access<\/strong>&#8221; attribute allows us to define the access rules. In the above example we simply check for user role (<em>admin<\/em> or <em>guest<\/em>). The hasRole is a <strong>SpEL<\/strong> (<strong>Spring Expression Language<\/strong>) syntax. Complete list of spEL expressions for security is given below:<\/p>\n<ul>\n<li><strong>hasRole([role])<\/strong>: Returns true if the current principal has the specified role.<\/li>\n<li><strong>hasAnyRole([role1,role2])<\/strong>: Returns true if the current principal has any of the supplied roles (given as a comma-separated list of strings)<\/li>\n<li><strong>principal<\/strong>: Allows direct access to the principal object representing the current user<\/li>\n<li>\n<strong>authentication<\/strong>: Allows direct access to the current Authentication object obtained from the SecurityContext<\/li>\n<li><strong>permitAll<\/strong>: Always evaluates to <strong>true<\/strong><\/li>\n<li><strong>denyAll<\/strong>: Always evaluates to <strong>false<\/strong><\/li>\n<li><strong>isAnonymous()<\/strong>: Returns true if the current principal is an anonymous user<\/li>\n<li><strong>isRememberMe()<\/strong>: Returns true if the current principal is a remember-me user<\/li>\n<li><strong>isAuthenticated()<\/strong>: Returns true if the user is not anonymous<\/li>\n<li><strong>isFullyAuthenticated()<\/strong>: Returns true if the user is not an anonymous or a remember-me user<\/li>\n<\/ul>\n<p>Among this list, only some expressions are usefull for the access attribute, mainly <strong>hasRole([role])<\/strong>, <strong>hasAnyRole([role1,role2])<\/strong>, <strong>isAnonymous()<\/strong>, <strong>isRememberMe()<\/strong>, <strong>isAuthenticated()<\/strong> and <strong>isFullyAuthenticated()<\/strong>. The other expressions are more informative and serve in different contexts (we&#8217;ll see them soon)<\/p>\n<p>Apart from the &#8220;<strong>access<\/strong>&#8221; attribute, the <strong>&lt;sec:authorize&gt;<\/strong> tag offers other interesting attributes:<\/p>\n<ul>\n<li><strong>url<\/strong>: an URL within the application. The tag <strong>&lt;sec:authorize&gt;<\/strong> is renderd if the user is grated access to this URL (based on rules defined by the <strong>FilterSecurityInterceptor<\/strong>)<\/li>\n<li><strong>method<\/strong>: GET or POST. Specify the HTTP method user to access the <strong>url<\/strong>. This attribute can only be used along with the previous <strong>url<\/strong> attribute.<\/li>\n<li><strong>var<\/strong>: a page scope variable to store the evaluation of this tag (<strong>tru<\/strong>e or <strong>false<\/strong>) so it can be re-used later in the page for different purpose.<\/li>\n<\/ul>\n<p>Please note that for the &#8220;url&#8221; attribute to work, you need to declare an additional <strong>DefaultWebInvocationPrivilegeEvaluator<\/strong> bean in the Spring context with the <strong>filterSecurityInterceptor<\/strong> injected as constructor argument:<\/p>\n<pre class=\"brush: xml; highlight: [21]; title: ; wrap-lines: false; notranslate\" title=\"\">\n&amp;lt;!-- Filter for role checking --&amp;gt;\n&amp;lt;bean id=&amp;quot;filterSecurityInterceptor&amp;quot; class=&amp;quot;org.springframework.security.web.access.intercept.FilterSecurityInterceptor&amp;quot;&amp;gt;\n\t&amp;lt;property name=&amp;quot;authenticationManager&amp;quot; ref=&amp;quot;authenticationManager&amp;quot;\/&amp;gt;\n\t&amp;lt;property name=&amp;quot;accessDecisionManager&amp;quot; ref=&amp;quot;httpRequestAccessDecisionManager&amp;quot;\/&amp;gt;\n\t&amp;lt;property name=&amp;quot;securityMetadataSource&amp;quot;&amp;gt;\n\t\t&amp;lt;sec:filter-security-metadata-source lowercase-comparisons=&amp;quot;true&amp;quot; request-matcher=&amp;quot;ant&amp;quot; use-expressions=&amp;quot;true&amp;quot;&amp;gt;\n\t\t\t&amp;lt;sec:intercept-url pattern=&amp;quot;\/pages\/Security\/**&amp;quot; access=&amp;quot;permitAll&amp;quot;\/&amp;gt;\n\t\t\t&amp;lt;sec:intercept-url pattern=&amp;quot;\/resources\/**&amp;quot; access=&amp;quot;permitAll&amp;quot;\/&amp;gt;\n\t\t\t&amp;lt;sec:intercept-url pattern=&amp;quot;\/pages\/Settings\/**&amp;quot; access=&amp;quot;hasRole('SETTINGS')&amp;quot;\/&amp;gt;\n\t\t\t&amp;lt;sec:intercept-url pattern=&amp;quot;\/pages\/Home\/*&amp;quot; access=&amp;quot;hasRole('HOME')&amp;quot;\/&amp;gt;              \n\t\t\t&amp;lt;sec:intercept-url pattern=&amp;quot;\/pages\/Admin\/**&amp;quot; access=&amp;quot;hasRole('ADMINISTRATOR')&amp;quot;\/&amp;gt;\n\t\t\t&amp;lt;sec:intercept-url pattern=&amp;quot;\/servlet\/Download&amp;quot; access=&amp;quot;hasAnyRole('DOWNLOAD','PREMIUM_ACCOUNT')&amp;quot;\/&amp;gt;\n                \n\t\t\t&amp;lt;sec:intercept-url pattern=&amp;quot;\/**&amp;quot; access=&amp;quot;isAuthenticated()&amp;quot;\/&amp;gt;\n\t\t&amp;lt;\/sec:filter-security-metadata-source&amp;gt;\n\t&amp;lt;\/property&amp;gt;\n&amp;lt;\/bean&amp;gt;\n\n&amp;lt;!-- webInvocationPrivilegeEvaluator necessary to use &amp;lt;sec:authorized url=&amp;quot;xx&amp;quot;&amp;gt; --&amp;gt;\n&amp;lt;bean id=&amp;quot;webInvocationPrivilegeEvaluator&amp;quot; class=&amp;quot;org.springframework.security.web.access.DefaultWebInvocationPrivilegeEvaluator&amp;quot;&amp;gt;\n\t&amp;lt;constructor-arg ref=&amp;quot;filterSecurityInterceptor&amp;quot;&amp;gt;\n&amp;lt;\/bean&amp;gt;\n<\/pre>\n<p>Below is an example of the var attribute usage:<\/p>\n<pre class=\"brush: xml; highlight: [1,10]; title: ; wrap-lines: false; notranslate\" title=\"\">\n&amp;lt;sec:authorize access=&amp;quot;hasRole('admin')&amp;quot; var=&amp;quot;isAdmin&amp;quot;&amp;gt;\n\t&amp;lt;table&amp;gt;\n  \t\t&amp;lt;tr&amp;gt;\n  \t  \t  \t&amp;lt;td&amp;gt;xxx&amp;lt;\/td&amp;gt;\n  \t  \t  \t&amp;lt;!-- Some administrator data here --&amp;gt;\n  \t  \t&amp;lt;\/tr&amp;gt;\n  \t&amp;lt;\/table&amp;gt;\n&amp;lt;\/sec:authorize&amp;gt;\n...\n&amp;lt;c:if test=&amp;quot;${isAdmin}&amp;quot;&amp;gt;\n  \/\/ Some block here if the user is Admin\n&amp;lt;\/c:if&amp;gt;\n<\/pre>\n<p>&nbsp;<\/p>\n<h3>B  The <em>Authentication<\/em> tag<\/h3>\n<p>The <strong>&amp;ltsec:authentication&gt;<\/strong> tag gives access to the <strong>Authentication<\/strong> object of the security context. The attribute &#8220;<strong>property<\/strong>&#8221; allows us to access some property of the <strong>Authentication<\/strong> object itself and display it directly to the page. <\/p>\n<p>The <strong>Authentication<\/strong> interface exposes the following methods:<\/p>\n<ul>\n<li><strong>authorities<\/strong>: collection of GrantedAuthority instances. Corresponds in most case to user roles<\/li>\n<li><strong>credentials<\/strong>: user&#8217; credentials (usually password)<\/li>\n<li><strong>details<\/strong>: object containing the details of the authentication process itself. The content of this object depends on the implementation of the <strong>Authentication<\/strong> interface. The default implementation returns <strong>null<\/strong><\/li>\n<li><strong>principal<\/strong>: the principal object, which is most of the time an instance of the <strong>UserDetails<\/strong> interface<\/li>\n<li><strong>isAuthenticated<\/strong>: return <strong>true<\/strong> or <strong>false<\/strong> whether the use is authenticated or not<\/li>\n<\/ul>\n<p>As with the previous tag, the <strong>&amp;ltsec:authentication&gt;<\/strong> tag offers some interesting other attributes:<\/p>\n<ul>\n<li><strong>var<\/strong>: a page variable to store the result of the <strong>property<\/strong> attribute so it can be re-used later in the page for different purposes<\/li>\n<li><strong>scope<\/strong>: scope of the above &#8220;<strong>var<\/strong>&#8221; attribute. Can be &#8220;<em>page<\/em>&#8220;, &#8220;<em>request<\/em>&#8220;,&#8221;<em>session<\/em>&#8221; or &#8220;<em>application<\/em>&#8220;<\/li>\n<li><strong>htmlEscape<\/strong>: if <strong>true<\/strong>, enable HTML escape for the &#8220;property&#8221; attribute display<\/li>\n<\/ul>\n<p>Usage examples:<\/p>\n<pre class=\"brush: xml; highlight: [2,6,15]; title: ; wrap-lines: false; notranslate\" title=\"\">\n&amp;lt;!-- Credentials display --&amp;gt;\nYour password is &amp;lt;sec:authentication property=&amp;quot;credentials&amp;quot;\/&amp;gt;\n...\n\n&amp;lt;!-- Roles display --&amp;gt;\n&amp;lt;sec:authentication property=&amp;quot;authorities&amp;quot; var=&amp;quot;roles&amp;quot; scope=&amp;quot;page&amp;quot; \/&amp;gt;\nYour roles are:\n&amp;lt;ul&amp;gt;\n\t&amp;lt;c:forEach var=&amp;quot;role&amp;quot; items=&amp;quot;${roles}&amp;quot;&amp;gt;\n \t&amp;lt;li&amp;gt;${role}&amp;lt;\/li&amp;gt;\n\t&amp;lt;\/c:forEach&amp;gt;\n&amp;lt;\/ul&amp;gt;\n\n&amp;lt;!-- Username display --&amp;gt;\nYour username is &amp;lt;sec:authentication property=&amp;quot;principal.username&amp;quot;\/&amp;gt;\n<\/pre>\n<p>&nbsp;<\/p>\n<h3>C  The <em>Accesscontrollist<\/em> tag<\/h3>\n<p>This <strong>&lt;sec:accesscontrollist&gt;<\/strong> tag is rarely used and can only be evaluated if <strong>Spring Security&#8217;s ACL<\/strong> module is activated.<\/p>\n<p>The available attributes are:<\/p>\n<ul>\n<li><strong>hasPermission<\/strong>: a list of permission (coma as separator) to be checked against domain object. The permission strings will be converted first into <strong>Permission<\/strong> instance by the <strong>PermissionFactory<\/strong> before performing evaluation. <em>The evaluation is true if at least one of the listed permission is found in the domain object<\/em><\/li>\n<li><strong>domainObject<\/strong>: domain object for which the above permissions are evaluated<\/li>\n<li><strong>var<\/strong>: a page scope variable to store the evaluation of this tag (<strong>true<\/strong> or <strong>false<\/strong>) so it can be re-used later in the page for different purpose<\/li>\n<\/ul>\n<p>Usage example:<\/p>\n<pre class=\"brush: xml; highlight: [1]; title: ; wrap-lines: false; notranslate\" title=\"\">\n\n&amp;lt;sec:accesscontrollist hasPermission=&amp;quot;admin,designer&amp;quot; domainObject=&amp;quot;${someObject}&amp;quot;&amp;gt;\n\t\/\/Displayed only if the domainObject has &amp;quot;admin&amp;quot; OR &amp;quot;designer&amp;quot; permission  \n&amp;lt;\/sec:accesscontrollist&amp;gt; \n\n<\/pre>\n<h1>III Security tags for Facelet<\/h1>\n<p>The above security tags are only available for JSP pages. If you are a JSF-user with Facelet as templating solution, no chance.<\/p>\n<p><del datetime=\"2012-04-24T21:27:21+00:00\">Luckily, some brillant people had a good idea to adapt these tags for Facelet. You can download the binaries here <a href=\"http:\/\/www.dominikdorn.com\/facelets\/\" title=\"http:\/\/www.dominikdorn.com\/facelets\/\" target=\"_blank\">http:\/\/www.dominikdorn.com\/facelets\/<\/a><\/del><\/p>\n<p> By looking around, I found out that there is a tag library out there for JSF shipped with Spring Web Flow: <a href=\"http:\/\/static.springsource.org\/spring-webflow\/docs\/2.2.x\/reference\/html\/ch13s09.html\" title=\"http:\/\/static.springsource.org\/spring-webflow\/docs\/2.2.x\/reference\/html\/ch13s09.html\" target=\"_blank\">http:\/\/static.springsource.org\/spring-webflow\/docs\/2.2.x\/reference\/html\/ch13s09.html<\/a><\/p>\n<p>You need to add the following dependency to your pom.xml<\/p>\n<pre class=\"brush: xml; title: ; wrap-lines: false; notranslate\" title=\"\">\n&amp;lt;dependency&amp;gt;\n\t&amp;lt;groupId&amp;gt;org.springframework.webflow&amp;lt;\/groupId&amp;gt;\n\t&amp;lt;artifactId&amp;gt;spring-faces&amp;lt;\/artifactId&amp;gt;\n\t&amp;lt;version&amp;gt;2.2.0.RELEASE&amp;lt;\/version&amp;gt;\n&amp;lt;\/dependency&amp;gt;\n<\/pre>\n<p> This jar contains many packages, among others the <strong>org.springframework.faces.security<\/strong> which is of interest. Alternatively if you do not want to get all the packages not related to security you can just copy the <strong>org.springframework.faces.security<\/strong> package into your source code.<\/p>\n<p>Adding the above dependency is not enough. You need also to declare this new taglib in a <strong>springsecurity.taglib.xml<\/strong> file for example:<\/p>\n<pre class=\"brush: xml; title: ; notranslate\" title=\"\">\n&amp;lt;?xml version=&amp;quot;1.0&amp;quot;?&amp;gt;\n&amp;lt;!DOCTYPE facelet-taglib PUBLIC\n  &amp;quot;-\/\/Sun Microsystems, Inc.\/\/DTD Facelet Taglib 1.0\/\/EN&amp;quot;\n  &amp;quot;http:\/\/java.sun.com\/dtd\/facelet-taglib_1_0.dtd&amp;quot;&amp;gt;\n&amp;lt;facelet-taglib&amp;gt;\n\t&amp;lt;namespace&amp;gt;http:\/\/www.springframework.org\/security\/tags&amp;lt;\/namespace&amp;gt;\n\t&amp;lt;tag&amp;gt;\n\t\t&amp;lt;tag-name&amp;gt;authorize&amp;lt;\/tag-name&amp;gt;\n\t\t&amp;lt;handler-class&amp;gt;org.springframework.faces.security.FaceletsAuthorizeTagHandler&amp;lt;\/handler-class&amp;gt;\n\t&amp;lt;\/tag&amp;gt;\n\t&amp;lt;function&amp;gt;\n\t\t&amp;lt;function-name&amp;gt;areAllGranted&amp;lt;\/function-name&amp;gt;\n\t\t&amp;lt;function-class&amp;gt;org.springframework.faces.security.FaceletsAuthorizeTagUtils&amp;lt;\/function-class&amp;gt;\n\t\t&amp;lt;function-signature&amp;gt;boolean areAllGranted(java.lang.String)&amp;lt;\/function-signature&amp;gt;\n\t&amp;lt;\/function&amp;gt;\n\t&amp;lt;function&amp;gt;\n\t\t&amp;lt;function-name&amp;gt;areAnyGranted&amp;lt;\/function-name&amp;gt;\n\t\t&amp;lt;function-class&amp;gt;org.springframework.faces.security.FaceletsAuthorizeTagUtils&amp;lt;\/function-class&amp;gt;\n\t\t&amp;lt;function-signature&amp;gt;boolean areAnyGranted(java.lang.String)&amp;lt;\/function-signature&amp;gt;\n\t&amp;lt;\/function&amp;gt;\n\t&amp;lt;function&amp;gt;\n\t\t&amp;lt;function-name&amp;gt;areNotGranted&amp;lt;\/function-name&amp;gt;\n\t\t&amp;lt;function-class&amp;gt;org.springframework.faces.security.FaceletsAuthorizeTagUtils&amp;lt;\/function-class&amp;gt;\n\t\t&amp;lt;function-signature&amp;gt;boolean areNotGranted(java.lang.String)&amp;lt;\/function-signature&amp;gt;\n\t&amp;lt;\/function&amp;gt;\n\t&amp;lt;function&amp;gt;\n\t\t&amp;lt;function-name&amp;gt;isAllowed&amp;lt;\/function-name&amp;gt;\n\t\t&amp;lt;function-class&amp;gt;org.springframework.faces.security.FaceletsAuthorizeTagUtils&amp;lt;\/function-class&amp;gt;\n\t\t&amp;lt;function-signature&amp;gt;boolean isAllowed(java.lang.String, java.lang.String)&amp;lt;\/function-signature&amp;gt;\n\t&amp;lt;\/function&amp;gt;\n\t&amp;lt;function&amp;gt;\n\t\t&amp;lt;function-name&amp;gt;access&amp;lt;\/function-name&amp;gt;\n\t\t&amp;lt;function-class&amp;gt;org.springframework.faces.security.FaceletsAuthorizeTagUtils&amp;lt;\/function-class&amp;gt;\n\t\t&amp;lt;function-signature&amp;gt;boolean access(java.lang.String)&amp;lt;\/function-signature&amp;gt;\n\t&amp;lt;\/function&amp;gt;\t\n&amp;lt;\/facelet-taglib&amp;gt;\n<\/pre>\n<p>The above declaration sheds some light on the available infrastructure:<\/p>\n<ul>\n<li><strong>authorize<\/strong>: new tag<\/li>\n<li><strong>areAllGranted(roles)<\/strong>: new EL function. Returns true if <strong>all<\/strong> listed roles are granted to the current user<\/li>\n<li><strong>areAnyGranted(roles)<\/strong>: new EL function. Returns true if <strong>at least one<\/strong> listed role is granted to the current user<\/li>\n<li><strong>areNotGranted(roles)<\/strong>: new EL function. Returns true if <strong>all<\/strong> listed roles are not  granted to the current user<\/li>\n<li><strong>isAllowed(url,method)<\/strong>: new EL function. Returns true if the given url with corresponding HTTP method can be accessed by the current user<\/li>\n<li><strong>access(webExpression)<\/strong>: new EL function. Returns true if the given web expression holds for the current user<\/li>\n<\/ul>\n<p>The  tag exposes the following attributes:<\/p>\n<ul>\n<li><strong>access<\/strong>: see above<\/li>\n<li><strong>url<\/strong>: see above<\/li>\n<li><strong>method<\/strong>: see above<\/li>\n<li><strong>areAllGranted<\/strong>: see above<\/li>\n<li><strong>areAnyGranted<\/strong>: see above<\/li>\n<li><strong>areNotGranted<\/strong>: see above<\/li>\n<li><strong>var<\/strong>: set the result of the access evaluation (true or false) into the Faces context<\/li>\n<\/ul>\n<p>We need to declare this taglib in the <strong>web.xml<\/strong> file:<\/p>\n<pre class=\"brush: xml; highlight: [3]; title: ; notranslate\" title=\"\">\n&amp;lt;context-param&amp;gt;\n\t&amp;lt;param-name&amp;gt;javax.faces.FACELETS_LIBRARIES&amp;lt;\/param-name&amp;gt;\n\t&amp;lt;param-value&amp;gt;\/WEB-INF\/springsecurity.taglib.xml&amp;lt;\/param-value&amp;gt;\n&amp;lt;\/context-param&amp;gt;\n<\/pre>\n<p>Usage example:<\/p>\n<pre class=\"brush: xml; highlight: [3]; title: ; notranslate\" title=\"\">\n&amp;lt;html xmlns=&amp;quot;http:\/\/www.w3.org\/1999\/xhtml&amp;quot;\n      xmlns:ui=&amp;quot;http:\/\/java.sun.com\/jsf\/facelets&amp;quot; \n      xmlns:h=&amp;quot;http:\/\/java.sun.com\/jsf\/html&amp;quot;\n      xmlns:f=&amp;quot;http:\/\/java.sun.com\/jsf\/core&amp;quot;\n      xmlns:sec=&amp;quot;http:\/\/www.springframework.org\/security\/tags&amp;quot;&amp;gt;\n&amp;lt;ui:composition template=&amp;quot;\/pages\/Templates\/techWebTemplate.xhtml&amp;quot;&amp;gt;\n\t...\n\t...\n\t&amp;lt;h:panelGroup  id=&amp;quot;secureBlock&amp;quot; layout=&amp;quot;block&amp;quot;\n\t\trendered=&amp;quot;#{sec:areAnyGranted('DESIGNER, ADMINISTRATOR')}&amp;quot;&amp;gt;\n\t\t\/\/ Section rendered only for DESIGNER or ADMINISTRATOR roles\n\t&amp;lt;\/h:panelGroup&amp;gt;\t\t\t\t\t\t\n\t...\n\t...\n\t&amp;lt;sec:authorize access=&amp;quot;hasAnyRole('ADMINISTRATOR',&amp;quot;DESIGNER')&amp;quot;&amp;gt;\n\t\t&amp;lt;h:panelGroup id=&amp;quot;administrationBlock&amp;quot; layout=&amp;quot;block&amp;quot;&amp;gt;\n\t\t...\n\t\t&amp;lt;\/h:panelGroup&amp;gt;\n\t&amp;lt;\/sec:authorize&amp;gt;    \n&amp;lt;\/ui:composition&amp;gt;\n&amp;lt;\/html&amp;gt;\n<\/pre>\n<p>Please pay attention to the special typo for the tag version and the EL function version.<\/p>\n<p><strong>&lt;sec:areAnyGranted(&#8216;DESIGNER, ADMINISTRATOR&#8217;)&gt;<\/strong>: the roles are separated by a coma and <strong>the whole chain is enclosed in simple quotes<\/strong><\/p>\n<p><strong>hasAnyRole(&#8216;ADMINISTRATOR&#8217;,&#8217;DESIGNER&#8217;)<\/strong>: the roles are <strong>enclosed first in simple quotes<\/strong> then separated by a coma<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Today we discuss about the security tags provided with Spring Security package. These tags allow you to customize your web pages to include\/exclude elements based on user roles and credentials<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":[],"categories":[30,14],"tags":[],"_links":{"self":[{"href":"https:\/\/www.doanduyhai.com\/blog\/index.php?rest_route=\/wp\/v2\/posts\/772"}],"collection":[{"href":"https:\/\/www.doanduyhai.com\/blog\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.doanduyhai.com\/blog\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.doanduyhai.com\/blog\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.doanduyhai.com\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=772"}],"version-history":[{"count":0,"href":"https:\/\/www.doanduyhai.com\/blog\/index.php?rest_route=\/wp\/v2\/posts\/772\/revisions"}],"wp:attachment":[{"href":"https:\/\/www.doanduyhai.com\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=772"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.doanduyhai.com\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=772"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.doanduyhai.com\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=772"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}