Jmix security subsystem provides an easily configurable access control mechanism for your application. It is based on Spring Security and adds the following features:
Integration with your data model.
Permissions to invoke CRUD operations on entities and to view/modify specific entity attributes. For example, a user can view documents, but cannot create, update, or delete them, and can view all document attributes except
Row-level access control restricts access to individual entity instances. For example, users can view documents that have been created in their department only.
Integration with UI.
Permissions to open screens of the user interface and see main menu items.
If a visual component like Text Field is bound to an entity attribute, it automatically becomes read-only or hidden depending on the current user rights to the attribute. Table actions are disabled if the corresponding CRUD operations are denied for the user.
Declarative definition of roles and permissions using annotated Java interfaces.
Ability to define roles and permissions at runtime and store them in the database.
User interface for viewing roles and permissions, assigning roles to users, and for creating runtime roles.
In this guide, we mainly describe the standard implementation of the security subsystem. To use all its features, make sure your
build.gradle file contains the following dependencies:
implementation 'io.jmix.security:jmix-security-starter' implementation 'io.jmix.security:jmix-security-ui-starter' implementation 'io.jmix.security:jmix-security-data-starter'
Below you can find a few diagrams that explain main concepts of the Jmix security subsystem.
A container here is a separately runnable/deployable unit that executes code or stores data.
In a simple case, Jmix provides all necessary security components (authentication, authorization, users and roles management) in a single application. Users are managed and authenticated by the application.
Optionally, you can use an external identity and access management (IAM) service like OIDC or LDAP. In this case, users are authenticated by the external service, which can also provide the list of roles of the authenticated user back to the application for subsequent authorization.
Users and Roles Management
Roles and policies can be defined in the application both at design time using annotated Java classes, and at runtime using configuration stored in the database.
When users are managed in the application, the administrator creates users and assigns roles to them using the application UI. The User entity is generated by default for a new project.
If an external IAM service is used, it manages the list of users and usually the list of roles for each user. The administrator also configures roles and policies in the application, and makes sure the application roles match the IAM roles by name. So when a user logs in to the system, the application gets the list of roles assigned to the user by the IAM service and uses its own roles and policies configuration for authorization.
There can be also mixed scenarios, when users are created both in IAM service and in the application (for example, automatically upon login).
User Authentication and Authorization
The authentication mechanism is based on Spring Security. Jmix provides default configuration for Spring Security, as well as the login screen generated in the project and CurrentAuthentication bean for obtainig information about the current user.
When a user works with the application, the access control component of the framework is requested for authorizing user actions. It, in turn, gets the information about the current user permissions from the roles configuration and makes decisions.
Roles and Policies
Below is a diagram that shows relationship between users, roles and policies.
A user can have multiple roles of two distinct types: resource and row-level.
Resource roles give users permissions to specific objects and operations, that are denied by default. A user without resource roles has no permissions and cannot access the system.
Row-level roles, in contrast, restrict access to particular entity instances. A user without row-level roles has access to all instances of an entity (if it is permitted by resource roles).
Each role can define policies of different types. Policies specify a target object (a resource for resource permissions, an entity instance or group of instances for row-level policies) and a permission or restriction to apply to this object.