Users
User Entity
Users of a Jmix application are defined by the User
class that is automatically generated by Studio in a new project. It is a JPA entity implementing the JmixUserDetails
interface which has a number of methods required by the framework:
-
getUsername()
returns a unique user name. -
getPassword()
returns a hashed password. -
isEnabled()
,isAccountNonExpired()
,isAccountNonLocked()
,isCredentialsNonExpired()
indicate whether the user can log in to the system. -
getAuthorities()
,setAuthorities()
are used by the framework to associate the user with a set of permissions upon login.
Users are stored in the main database of your application. By default, the User
entity and the corresponding database table have the following attributes:
-
id
,version
are the standard primary key and optimistic locking attributes. -
username
,password
,enabled
store values returned by the methods of theJmixUserDetails
interface. -
email
,firstName
,lastName
store additional information about users.
You can define any number of additional attributes required for your application, for example, department
or position
.
User Management
A new project contains the 010-init-user.xml
database migration script that creates a user with the admin
/admin
username/password and grants the user full access to the application by associating the entity with the system-full-access
role.
A new project also contains the UI screens for managing users, see Application → Users. These screens allow you to create, edit and remove users, change and reset their passwords. To assign roles to a user, click the Role assignments button in the user browser.
The framework provides the ui-minimal role that gives permissions to log in to UI and use some common UI elements. Assign this role to new users that will interact with the application through the UI, otherwise they won’t be able to log in.
|
Built-in Users
Any Jmix application with the standard security subsystem has two built-in user objects:
-
Anonymous user object corresponds to not authenticated users. It allows you to grant some permissions to users before they log in.
-
System user object is required for the system authentication mechanism. It is used when there is no real user interacting with the application, for example, when the application is starting up, or when a business method is called by a scheduler.
The built-in user objects are not stored in the database but created on the application startup by the DatabaseUserRepository
class of your project. You can customize both users in the initAnonymousUser()
and initSystemUser()
methods of this class. By default, the system user is associated with the system-full-access
role and hence has all permissions. The anonymous user has no permissions by default.
User Substitution
The system administrator can give a user an ability to substitute another user. The substitution means the user has the security permissions and restrictions of the substituted user. For example, if Alice substitutes Bob, she logs in to the application as Alice but has the Bob’s roles.
To see the feature in action, do the following:
-
Log in as
admin
and create at least one more user with theUI: minimal access
role. -
Select
admin
in the Users table and click Additional → User substitution. You will see a list of users thatadmin
can substitute. -
Add your new user to the list of users substituted by
admin
. -
Now you will see that the current user name in the
userIndicator
component of the main screen has changed to a drop-down list that contains the substituted user. If you select this user, the workspace will change as if you re-login as this user. But all audit features will still registeradmin
- the logged-in user.
The CurrentUserSubstitution
bean can be used to obtain a currently substituted user, an authenticated user, or the effective user (which is substituted user in case of substitution, authenticated one otherwise).
For example:
@Autowired
private CurrentUserSubstitution currentUserSubstitution;
private String getSubstitutedUserName() {
User substitutedUser = (User) currentUserSubstitution.getSubstitutedUser();
return substitutedUser == null ? "" : substitutedUser.getUsername();
}
-
The
CurrentAuthentication.getUser()
method always returns the authenticated user. -
The
CurrentAuthentication.getAuthentication().getAuthorities()
returns authorities of the effective user. That is, in the case of substitution, these authorities differ from the authorities of the authenticated user.