Add Security in the View Layer"
Robertwenzel (talk | contribs) |
|||
(9 intermediate revisions by 2 users not shown) | |||
Line 1: | Line 1: | ||
{{ZKSpringEssentialsPageHeader}} | {{ZKSpringEssentialsPageHeader}} | ||
− | = | + | =Overview= |
− | + | ZK Spring Security provides features to check a user's role and permissions so that you can determine whether to render certain parts of the UI based on the user's roles. | |
− | + | ZK Spring Security provides 2 ways to access user roles and permissions in a ZK application. | |
− | + | * '''SecurityUtil''' a java class providing static methods to be used in component, controller, and view model code | |
− | * '''SecurityUtil''' a java class providing static methods to be used in component, controller and view model code | + | * '''Taglib functions''' and an implicit '''authentication''' object to perform permission checks conveniently in ZUL files (with EL-Expressions) |
− | * '''Taglib functions''' and an implicit 'authentication' object to perform permission checks conveniently in ZUL files (with EL-Expressions) | ||
− | + | =Using the Taglib in ZUL= | |
In zul files the special attributes [[ZUML_Reference/ZUML/Attributes/if|if]] and [[ZUML_Reference/ZUML/Attributes/unless|unless]] are ideal candidates to render or omit certain parts of a zul file. | In zul files the special attributes [[ZUML_Reference/ZUML/Attributes/if|if]] and [[ZUML_Reference/ZUML/Attributes/unless|unless]] are ideal candidates to render or omit certain parts of a zul file. | ||
Line 16: | Line 15: | ||
After declaring the taglib the functions are available with the specified prefix. | After declaring the taglib the functions are available with the specified prefix. | ||
− | <source lang="xml" | + | <source lang="xml" highlight="1,4,9,12"> |
<?taglib uri="http://www.zkoss.org/zkspring/security" prefix="sec"?> | <?taglib uri="http://www.zkoss.org/zkspring/security" prefix="sec"?> | ||
<zk> | <zk> | ||
Line 34: | Line 33: | ||
</source> | </source> | ||
− | As in all zul pages | + | As in all zul pages, the taglib function can also be used in a component's attributes. For example, to disable a button according to a role: |
<source lang="xml"> | <source lang="xml"> | ||
Line 40: | Line 39: | ||
</source> | </source> | ||
− | Available functions as implemented in (org.zkoss.spring.security.SecurityUtil): | + | Available functions as implemented in ([https://www.zkoss.org/javadoc/latest/zkspring-security/org/zkoss/spring/security/SecurityUtil.html org.zkoss.spring.security.SecurityUtil]): |
− | * | + | * <code>boolean isNoneGranted(String authorities)</code>: Return true if the authenticated principal is granted NONE of the roles in the specified authorities. |
− | * | + | * <code>boolean isAllGranted(String authorities)</code>: Return true if the authenticated principal is granted ALL of the roles in the specified authorities. |
− | * | + | * <code>boolean isAnyGranted(String authorities)</code>: Return true if the authenticated principal is granted ANY of the roles in the specified authorities. |
− | * | + | * <code>boolean isAccessible(String hasPermission, Object domainObject)</code>: Return true if the current Authentication has one of the specified permissions to the presented domain object instance. |
− | * | + | * <code>Authentication getAuthentication()</code>: Return current login Authentication (similar to implicit "authentication" object). |
− | = | + | =Using <code>SecurityUtil</code>= |
− | + | You can call the methods of ([https://www.zkoss.org/javadoc/latest/zkspring-security/org/zkoss/spring/security/SecurityUtil.html org.zkoss.spring.security.SecurityUtil]) in java code directly, to build the UI conditionally: | |
<source lang="java"> | <source lang="java"> | ||
Line 60: | Line 59: | ||
</source> | </source> | ||
− | + | =The Implicit "authentication" Object= | |
− | |||
− | ' | + | The <code>DelegatingVariableResolver</code> adds an implicit object "authentication" which exposes Spring's current authentication object [https://docs.spring.io/spring-security/site/docs/4.0.x/apidocs/org/springframework/security/core/Authentication.html Authentication] to EL expressions. Depending on the type of the principal object you can access also nested properties. |
− | <source lang="xml" | + | |
− | + | <source lang="xml" highlight="1,3,6,9,12"> | |
− | |||
<?variable-resolver class="org.zkoss.zkplus.spring.DelegatingVariableResolver"?> | <?variable-resolver class="org.zkoss.zkplus.spring.DelegatingVariableResolver"?> | ||
− | < | + | <div> |
+ | <label value="authentication.name"/> = ${authentication.name} | ||
+ | </div> | ||
+ | <div> | ||
+ | <label value="authentication.principal.username"/> = ${authentication.principal.username} | ||
+ | </div> | ||
+ | <div> | ||
+ | <label value="authentication.principal.enabled"/> = ${authentication.principal.enabled} | ||
+ | </div> | ||
+ | <div> | ||
+ | <label value="authentication.principal.accountNonLocked"/> = ${authentication.principal.accountNonLocked} | ||
+ | </div> | ||
+ | </source> | ||
− | + | =Websocket / Server Push support= | |
− | + | As WebSocket and asynchronous UI updates (via server push) don't always go through Spring Security's Filter chain (as no HTTP Request is sent/filtered), the SecurityContextHolder is not initialized in such cases. The result is, that Spring won't be able to perform authentication or authorization (role) checks. | |
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | ... | + | To achieve better integration the [https://github.com/zkoss/zkspring/blob/master/zkspring-security/src/main/java/org/zkoss/spring/init/SecurityContextAwareExecutionListener.java SecurityContextAwareExecutionListener] (an ExecutionInit/Cleanup-Listener) is added by default to fill the SecurityContextHolder from the current Session during UI updates. |
− | + | This listener is enabled by default and can be disabled by setting the library property '''org.zkoss.spring.init.SecurityContextAwareExecutionListener.enabled''' to '''false'''. | |
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
{{ZKSpringEssentialsPageFooter}} | {{ZKSpringEssentialsPageFooter}} |
Latest revision as of 09:20, 13 December 2022
Overview
ZK Spring Security provides features to check a user's role and permissions so that you can determine whether to render certain parts of the UI based on the user's roles.
ZK Spring Security provides 2 ways to access user roles and permissions in a ZK application.
- SecurityUtil a java class providing static methods to be used in component, controller, and view model code
- Taglib functions and an implicit authentication object to perform permission checks conveniently in ZUL files (with EL-Expressions)
Using the Taglib in ZUL
In zul files the special attributes if and unless are ideal candidates to render or omit certain parts of a zul file.
After declaring the taglib the functions are available with the specified prefix.
<?taglib uri="http://www.zkoss.org/zkspring/security" prefix="sec"?>
<zk>
<div if="${sec:isAllGranted('ROLE_SUPERVISOR')}">
This div and all child components are only displayed for user with the SUPERVISOR ROLE
<listbox .../>
</div>
<button if="${sec:isAnyGranted('ROLE_TELLER,ROLE_ACCOUNTANT')}"
label="For TELLERs and ACCOUNTANTs only" >
<zk if="${sec:isNoneGranted('ROLE_TRAINEE,ROLE_ROOKIE')}">
TRAINEES and ROOKIES won't see this.
</zk>
</zk>
As in all zul pages, the taglib function can also be used in a component's attributes. For example, to disable a button according to a role:
<button label="Transfer Money" disabled="${sec:isNoneGranted('ROLE_SUPERVISOR')}" .../>
Available functions as implemented in (org.zkoss.spring.security.SecurityUtil):
boolean isNoneGranted(String authorities)
: Return true if the authenticated principal is granted NONE of the roles in the specified authorities.boolean isAllGranted(String authorities)
: Return true if the authenticated principal is granted ALL of the roles in the specified authorities.boolean isAnyGranted(String authorities)
: Return true if the authenticated principal is granted ANY of the roles in the specified authorities.boolean isAccessible(String hasPermission, Object domainObject)
: Return true if the current Authentication has one of the specified permissions to the presented domain object instance.Authentication getAuthentication()
: Return current login Authentication (similar to implicit "authentication" object).
Using SecurityUtil
You can call the methods of (org.zkoss.spring.security.SecurityUtil) in java code directly, to build the UI conditionally:
if (SecurityUtil.isAllGranted("ROLE_SUPERVISOR")) {
Button btn = new Button();
...
btn.setParent(win);
}
The Implicit "authentication" Object
The DelegatingVariableResolver
adds an implicit object "authentication" which exposes Spring's current authentication object Authentication to EL expressions. Depending on the type of the principal object you can access also nested properties.
<?variable-resolver class="org.zkoss.zkplus.spring.DelegatingVariableResolver"?>
<div>
<label value="authentication.name"/> = ${authentication.name}
</div>
<div>
<label value="authentication.principal.username"/> = ${authentication.principal.username}
</div>
<div>
<label value="authentication.principal.enabled"/> = ${authentication.principal.enabled}
</div>
<div>
<label value="authentication.principal.accountNonLocked"/> = ${authentication.principal.accountNonLocked}
</div>
Websocket / Server Push support
As WebSocket and asynchronous UI updates (via server push) don't always go through Spring Security's Filter chain (as no HTTP Request is sent/filtered), the SecurityContextHolder is not initialized in such cases. The result is, that Spring won't be able to perform authentication or authorization (role) checks.
To achieve better integration the SecurityContextAwareExecutionListener (an ExecutionInit/Cleanup-Listener) is added by default to fill the SecurityContextHolder from the current Session during UI updates.
This listener is enabled by default and can be disabled by setting the library property org.zkoss.spring.init.SecurityContextAwareExecutionListener.enabled to false.