This article describes how administrator users can manage the application's users, groups and permissions using an intuitive and friendly user interface in order to configure who can access the different resources and features available. The security management capabilities presented exceed by far the ones provided by the old Dashbuilder.
Basic concepts
In order to understand the new security management module, a few core concepts need to be introduced first.Roles vs Groups
Permissions
- View a perspective
- Save a project
- View a repository
- Delete a dashboard
A permission can be granted or denied and it can be global or resource specific. For instance:
- Global: “Create new perspectives”
- Specific: “View the home perspective”
As you can see, a permission is a "resource + action" pair. In the concrete case of a perspective we have: read, update, delete and create as the available actions. That means that there are four possible permissions that could be granted for perspectives.
Permissions do not necessarily need to be tied to a resource. Sometimes it is also necessary to protect access to specific features, like for instance "generate a sales report". That means, permissions can be used not only to protect access to resources but also to custom features within the application.
Authorization policy
The set of permissions assigned to every role and/or group is called the authorization (or security) policy. Every application contains a single security policy which is used every time the system checks a permission.
The authorization policy file is stored in a file called WEB-INF/classes/security-policy.properties under the application's WAR structure.
NOTE: If no policy is defined then the authorization management features are disabled and the application behaves as if all the resources & features were granted by default.
Here is an example of a security policy file:
# Role "admin"
role.admin.permission.perspective.read=true
role.admin.permission.perspective.read.Dashboard=false
# Role "user"
role.user.permission.perspective.read=false
role.user.permission.perspective.read.Home=true
role.user.permission.perspective.read.Dashboard=true
Every entry defines a single permission which is assigned to a role/group. On application start up, the policy file is loaded and stored into memory.
Security provider
In most typical scenarios the application's security is delegated to the container's security mechanism, which consumes a given realm at same time. It's important to consider that there exist several realm implementations, for example Wildfly provides a realm based on the application-users.properties/application-roles.properties files, Tomcat provides a realm based on the tomcat-users.xml file, etc.
So there is no single security realm to rely on, it can be different in each installation.
Due to the potential different security environments that have to be supported, the security module provides a well defined API with some default built-in security providers.
A security provider is the formal name given to a concrete user and group management service implementation for a given realm.
The user & group management features available will depend on the security provider configured.
If the built-in providers do not fit with the application's security realm, it is easy to build and register your own provider.
Installation and setup
At the time of this writing, the application provides two pre-installed security providers:
- Wildfly 10 / EAP 7 - Both distributions use the Wildfly security provider configured for the use of the default realm files application-users.properties and application-roles.properties
- Tomcat - It uses the Tomcat security provider configured for the use of the default realm file tomcat-users.xml
Please, read each provider's documentation in order to apply the concrete settings for the target deployment environment.
On the other hand, when either using a custom security provider or using one of the availables, consider the following installation options:
- Enable the security management feature on an existing WAR distribution
- Setup and installation in an existing or new project
NOTE: If no security provider is installed, there will be no available user interface for managing the security realm.
Once a security provider is installed and setup, the user and group management features are automatically enabled in the security management UI (see the "Usage" section below).
Enabling user & group management
Given an existing WAR distribution, follow these steps in order to install and enable the user & group management features:
- Ensure the following libraries are present on WEB-INF/lib:
- WEB-INF/lib/uberfire-security-management-api-?.jar
- WEB-INF/lib/uberfire-security-management-backend-?.jar
- Copy the the security provider library to WEB-INF/lib:
- e.g: WEB-INF/lib/uberfire-security-management-wildfly-?.jar
- If the provider requires additional libraries, copy them as well
- Replace the whole content of the WEB-INF/classes/security-management.properties file, or if not present, create it. The settings present on this file depend on the concrete implementation used.
- If deploying on Wildfly or EAP, check if the WEB-INF/jboss-deployment-structure.xml requires any update.
Please, read each provider's documentation for more information.
Disabling user & group management
The user & groups management features can be disabled, and thus no services or user interface will be available, by means of either:
- Uninstalling the security provider from the application. When no concrete security provider is installed, the user and group management features will be disabled and no services or user interface will be displayed to the user.
- Removing or commenting the security management configuration file. Removing or commenting all the lines in the configuration file located at WEB-INF/classes/security-management.properties is another way to disable the user and group management features.
Usage
The Security Management perspective is available under the Administration section in the top menu bar.
The next screenshot shows how this new perspective looks:
This perspective supports:
- List all the roles, groups and users available
- Create & delete users and groups
- Edit users, assign roles or groups, and change user properties
- Edit both roles & groups security settings, which include:
- The home perspective a user will be directed to after login
- The permissions granted or denied to the different workbench resources and features available
All of the above together provides a complete users and groups management subsystem as well as a permission configuration UI for protecting access to specific resources or features.
The next sections provide a deep insight into all these features.
NOTE: The user and group management related features can be entirely disabled. See the previous section
"Disabling user & group management". If that's the case then both the Groups and Users tabs will remain hidden from the user.
User management
By selecting the Users tab in the left sidebar, the application shows all the users present by default on the application's security realm:
- Searching for users
In addition to listing all the users, search is also allowed. When specifying the search pattern in the search box the users listed will be reduced to only those that matches the search pattern.
Search patterns depend on the concrete security provider being used by the application.
Please, read each provider's documentation for more information.
- Creating new users
By clicking on the "New user +" anchor, a form is displayed on the right.
This is a wizard like interface where the application asks for the new user name, a password as well as what roles/groups to assign.
- Editing a user
After clicking on a user in the left sidebar, the user editor is opened on the screen's right.
For instance, the details screen for the admin user when using the Wildfly security provider looks like the following screenshot:
Same screen but when using the Keycloak security provider looks as:
Note that when using the Keycloak provider, a new user attributes section is displayed, but it's not present when using the Wildfly provider. This is due to the fact that the information and actions available always depend on each provider's capabilities as explained in the "Security provider capabilities" section below.
Next is the type of information handled in the user's details screen:
Next is the type of information handled in the user's details screen:
- The user name
- The user's attributes
- The assigned groups
- The assigned roles
- The permissions granted or denied
In order to update or delete an existing user, click on the Edit button present near to the username in the user editor screen:
them):
For instance, to modify the set of roles and groups assigned to the user or to change the user's password as well.
The Permissions tab shows a summary of all the permissions assigned to this particular user. This is a very helpful view as it allows administrator users to verify if a target user has the right permission levels according to the security settings of its roles and groups.
User attributes can added or deleted using the actions available in the attributes table:
From the Groups tab, a group selection popup is presented when clicking on the "Add to groups" button:
From the Roles tab, a role selection popup is presented when clicking on "Add to roles" button:
A change password popup screen is presented when clicking on the "Change password" button:
The user currently being edited can be deleted from the realm by clicking on the "Delete" button.
Each security realm can provide support for different operations. For example, consider the use of a Wildfly's realm based on properties files. The contents for the applications-users.properties is like:
admin=207b6e0cc556d7084b5e2db7d822555c
katy=fd37b5d0b82ce027bfad677a54fbccee
john=afda4373c6021f3f5841cd6c0a027244
guest=b5d048a237bfd2874b6928e1f37ee15e
Notice that it's based on key-value pairs where the key is the user name, and the value is the hashed value for the user's password. So a user is just represented by a key and its user name, it does not have a name nor an address or any other meta information.
On the other hand, consider the use of a realm provided by a Keycloak server. The user information is composed by more meta-data, such as the surname, address, etc, as in the following image:
For instance, to modify the set of roles and groups assigned to the user or to change the user's password as well.
- Permissions summary
The Permissions tab shows a summary of all the permissions assigned to this particular user. This is a very helpful view as it allows administrator users to verify if a target user has the right permission levels according to the security settings of its roles and groups.
Further details about how to assign permissions to roles and groups are in the "Security Settings Editor" section below.
- Updating the user's attributes
User attributes can added or deleted using the actions available in the attributes table:
- Updating assigned groups
From the Groups tab, a group selection popup is presented when clicking on the "Add to groups" button:
This popup screen allows the user to search and select or deselect the groups assigned to the user.
- Updating assigned roles
From the Roles tab, a role selection popup is presented when clicking on "Add to roles" button:
This popup screen allows the user to search and select or deselect the roles assigned to the user.
- Changing the user's password
A change password popup screen is presented when clicking on the "Change password" button:
- Deleting users
The user currently being edited can be deleted from the realm by clicking on the "Delete" button.
Security provider capabilities
Each security realm can provide support for different operations. For example, consider the use of a Wildfly's realm based on properties files. The contents for the applications-users.properties is like:
admin=207b6e0cc556d7084b5e2db7d822555c
katy=fd37b5d0b82ce027bfad677a54fbccee
john=afda4373c6021f3f5841cd6c0a027244
guest=b5d048a237bfd2874b6928e1f37ee15e
Notice that it's based on key-value pairs where the key is the user name, and the value is the hashed value for the user's password. So a user is just represented by a key and its user name, it does not have a name nor an address or any other meta information.
On the other hand, consider the use of a realm provided by a Keycloak server. The user information is composed by more meta-data, such as the surname, address, etc, as in the following image:
So the different services and client side components from the User and Group Management API are based on capabilities which are used to expose or restrict the available functionality provided by the different services and client side components. Examples of capabilities are:
Each security provider must specify a set of capabilities supported. From the previous examples, it is noted that the Wildfly security provider does not support the attributes management capability - the user is only composed by the user name. On the other hand the Keycloak provider does support this capability.
The different views and user interface components rely on the capabilities supported by each provider, so if a capability is not supported by the provider in use, the UI does not provide the views for the management of that capability. As an example, consider that a concrete provider does not support deleting users - the delete user button on the user interface will be not available.
Please take a look at the concrete service provider documentation to check all the supported capabilities for each one, the default ones can be found here.
By selecting the Groups tab in the left sidebar, the application shows all the groups present by default on the application's security realm:
In addition to listing all the groups, search is also allowed. When specifying the search pattern in the search box the groups listed will be reduced to only those that matches the search pattern.
- Create a user
- Update a user
- Delete a user
- Update user's attributes
- Create a group
- Update a group
- Assign groups to a user
- Assign roles to a user
Each security provider must specify a set of capabilities supported. From the previous examples, it is noted that the Wildfly security provider does not support the attributes management capability - the user is only composed by the user name. On the other hand the Keycloak provider does support this capability.
The different views and user interface components rely on the capabilities supported by each provider, so if a capability is not supported by the provider in use, the UI does not provide the views for the management of that capability. As an example, consider that a concrete provider does not support deleting users - the delete user button on the user interface will be not available.
Please take a look at the concrete service provider documentation to check all the supported capabilities for each one, the default ones can be found here.
Group management
By selecting the Groups tab in the left sidebar, the application shows all the groups present by default on the application's security realm:
- Searching for groups
In addition to listing all the groups, search is also allowed. When specifying the search pattern in the search box the groups listed will be reduced to only those that matches the search pattern.
Search patterns depend on the concrete security provider being used by the application.
Please, read each provider's documentation for more information.
By clicking on the "New group +" anchor, a new screen will be presented on the center panel to perform a new group creation.
Clicking on the "Add selected users" button finishes the group creation.
- Creating new groups
By clicking on the "New group +" anchor, a new screen will be presented on the center panel to perform a new group creation.
After typing a name and clicking Save, the next step is to assign users to it:
Clicking on the "Add selected users" button finishes the group creation.
- Modifying a group
- Deleting groups
Role management
By selecting the Roles tab in the left sidebar, the application shows all the application roles:
That means both role and group based permissions can be defined. The main difference between roles and group are:
- Roles are an application defined resource. They are defined as <security-role> entries in the application's web.xml descriptor.
- Groups are dynamic and can be defined at runtime. The installed security provider determines where groups instances are stored.
They can be used together without any trouble. Groups are recommended though as they are a more flexible than roles.
- Searching for roles
In addition to listing all the roles, search is also allowed. When specifying the search pattern in the search box the roles listed will be reduced to only those that matches the search pattern.
Search patterns depend on the concrete security provider being used by the application.
Please, read each provider's documentation for more information.
This editor is used to set several security settings for both roles and groups.
This is the perspective where the user is directed after login. This makes it possible to have different home pages for different users, since users can be assigned to
different roles or groups.
It is used to determine what settings (home perspective, permissions, ...) have precedence for those users with more that one role or group assigned.
Without this setting, it won't be possible to determine what role/group should take precedence. For instance, an administrative role has higher priority than a non-administrative one. For users with both administrative and non-administrative roles granted, administrative privileges will always win, provided the administrative role's priority is greater than the other.
Currently, only perspective permissions are supported in the UI. If access to a perspective is denied then it will not be shown in any of application menus. Update, Delete and Create permissions change the behaviour of the perspective management plugin editor.
Security Settings Editor
This editor is used to set several security settings for both roles and groups.
Home perspective
This is the perspective where the user is directed after login. This makes it possible to have different home pages for different users, since users can be assigned to
different roles or groups.
Priority
It is used to determine what settings (home perspective, permissions, ...) have precedence for those users with more that one role or group assigned.
Without this setting, it won't be possible to determine what role/group should take precedence. For instance, an administrative role has higher priority than a non-administrative one. For users with both administrative and non-administrative roles granted, administrative privileges will always win, provided the administrative role's priority is greater than the other.
Permissions
Currently, only perspective permissions are supported in the UI. If access to a perspective is denied then it will not be shown in any of application menus. Update, Delete and Create permissions change the behaviour of the perspective management plugin editor.
For perspectives, it is possible to define global permissions and add single instance exceptions afterwards. For instance, Read access can be granted to all the perspectives and deny access just to an individual perspective. This is called the grant all deny a few strategy.
The opposite, deny all grant a few strategy is also supported:
NOTE: In the example above, the Update and Delete permissions are disabled as it does not makes sense to define such permissions if the user is not even able to read perspectives.
The security policy is stored under the workbench’s VFS. Most concrete, in a GIT repo called “security”.
The ACL table is stored in a file called “security-policy.properties” under the “authz” directory. Next is an example of the entries this file contains:
role.admin.home=HomePerspective
role.admin.priority=0
role.admin.permission.perspective.read=true
role.admin.permission.perspective.create=true
role.admin.permission.perspective.delete=true
role.admin.permission.perspective.update=true
Every time the ACL is modified from the security settings UI the changes are stored into the GIT repo.
Initially, when the application is deployed for the first time there is no security policy stored in GIT. However, the application might need to set-up a default policy with the different access profiles for each of the application roles.
In order to support default policies the system allows for declaring a security policy as part of the webapp’s content. This can be done just by placing a security-policy.properties file under the webapp’s resource classpath (the WEB-INF/classes directory inside the WAR archive is a valid one). On app start-up the following steps are executed:
The above is an auto-deploy mechanism which is used in the workbench to set-up its default security policy.
One slight variation of the deployment process is the ability to split the “security-policy.properties” file into small pieces so that it is possible, for example, to define one file per role. The split files must start by the “security-module-” prefix, for instance: “security-module-admin.properties”. The deployment mechanism will read and deploy both the "security-policy.properties" and all the optional “security-module-?.properties” found on the classpath.
Notice, despite using the split approach, the “security-policy.properties” must always be present as it is used as a marker file by the security subsystem in order to locate the other policy files. This split mechanism allows for a better organization of the whole security policy.
Security Policy Storage
The security policy is stored under the workbench’s VFS. Most concrete, in a GIT repo called “security”.
The ACL table is stored in a file called “security-policy.properties” under the “authz” directory. Next is an example of the entries this file contains:
role.admin.home=HomePerspective
role.admin.priority=0
role.admin.permission.perspective.read=true
role.admin.permission.perspective.create=true
role.admin.permission.perspective.delete=true
role.admin.permission.perspective.update=true
Every time the ACL is modified from the security settings UI the changes are stored into the GIT repo.
Initially, when the application is deployed for the first time there is no security policy stored in GIT. However, the application might need to set-up a default policy with the different access profiles for each of the application roles.
In order to support default policies the system allows for declaring a security policy as part of the webapp’s content. This can be done just by placing a security-policy.properties file under the webapp’s resource classpath (the WEB-INF/classes directory inside the WAR archive is a valid one). On app start-up the following steps are executed:
- Check if an active policy is already stored in GIT
- If not, then check if a policy has been defined under the webapp’s classpath
- If found, such policy is stored under GIT
The above is an auto-deploy mechanism which is used in the workbench to set-up its default security policy.
One slight variation of the deployment process is the ability to split the “security-policy.properties” file into small pieces so that it is possible, for example, to define one file per role. The split files must start by the “security-module-” prefix, for instance: “security-module-admin.properties”. The deployment mechanism will read and deploy both the "security-policy.properties" and all the optional “security-module-?.properties” found on the classpath.
Notice, despite using the split approach, the “security-policy.properties” must always be present as it is used as a marker file by the security subsystem in order to locate the other policy files. This split mechanism allows for a better organization of the whole security policy.
Authorization API
Uberfire provides a complete API around permissions. The AuthorizationManager is the main interface for checking if permissions are granted to users.
@Inject AuthorizationManager authzManager; Perspective perpsective1; User user; ... boolean result = authzManager.authorize(perspective1, user);
authorizationManager.check(perspective1, user)
.granted(() -> ...)
.denied(() -> ...);
The security check calls always use the permissions defined in the security policy.
For those interested in those APIs, an entire chapter can be found in the Uberfire's documentation.
Summary
The features described above bring even more flexibility to Dashbuilder. Users and groups can be created right from the UI, new assets like perspectives can be authored (the new Perspective editor is about to be released :-) ) and, finally, permissions on perspectives can be granted or denied.
In the future, along with the improvement of the authoring capabilities, more permission types will be added. The ultimate goal is to deliver a zero/low code, very flexible and customizable tooling which allows to develop, build and deploy business dashboards in the cloud.
UF Dasbuilder is close to its 1.0 release. Only a few major features like the filter controls or the perspective builder are still in progress. The next article will introduce the perspective builder which is the main component used for dashboard design. Stay tuned!