Skip to content

Understanding User Management interfaces and Classes#

UserDetails Hierarchy#

  • So UserDetails is an interface which provide core user information. This interface will provide some abstract methods like getAuthorities, getPassword, getUsername and so on, they are core user information that an simple application have to provide. In spring security we have an sample implementation of this UserDetails interface called User. For example, we don't have a very big application which need to be create our own user schema, so we can go with the sample User implementation of spring security.

 #zoom

  • So, the User class implement UserDetails and if you look into the User class you can see there are some attributes as below:
User.java
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
    private String password;

    private final String username;

    private final Set<GrantedAuthority> authorities;

    private final boolean accountNonExpired;

    private final boolean accountNonLocked;

    private final boolean credentialsNonExpired;

    private final boolean enabled;
  • So if you have to create your custom user implementation from UserDetails please make sure that put the same naming conventions and name variables as above, because these are things that understand by spring security framework.
  • Next, we have another interface and extend the UserDetails called MutableUserDetails. This interface provide one more method setPassword and the class MutableUseris the implementation of it.
  • So with the User class don't have any method to set the password (the password is only created in the constructor of User), this is inconvenient when the user forgot the password, or want to change it. So the MutableUser will help you to solve it by provide the method setPassword. As you can see in some websites when you click into a link forgot password and put the email into it, then you will received an email with a link to set the new password and retype it. So this an feature of MutableUser.

UserDetailsService Hierarchy#

  • Let's take a look into the UserDetailsService hierarchy then you will understand how end users will be managed by spring security.
  • Below are interfaces and classes revolving around user management inside spring security.

 #zoom

  • UserDetailsService is an interface, which have a single abstract method called loadUserByusername. Ideally, most of the applications they just wanted to validate whether the given user is present inside a database or LDAP application or inside memory of my spring security container. So in all that scenarios, we just pass username to this abstract method that we are receiving from the UI and this method we have in logic of fetching the Userdetails from the database or LDAP server or from the memory of the spring container.
  • So UserDetailsService is an interface which have a logic of fetching the user from the database or any other places and the return type of loadUserByusername is Userdetails, because whenever we are dealing with users, we decided to use Userdetails schema adhering to the spring security.
  • Then we have UserDetailsManager which will extend the UserDetailsService with abstract methods for user management like createUser, updateUser, deleteUser, changePassword and userExists.
UserDetailsManager.java
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
public interface UserDetailsManager extends UserDetailsService {

    /**
     * Create a new user with the supplied details.
     */
    void createUser(UserDetails user);

    /**
     * Update the specified user.
     */
    void updateUser(UserDetails user);

    /**
     * Remove the user with the given login name from the system.
     */
    void deleteUser(String username);

    /**
     * Modify the current user's password. This should change the user's password in the
     * persistent user repository (datbase, LDAP etc).
     * @param oldPassword current password (for re-authentication if required)
     * @param newPassword the password to change to
     */
    void changePassword(String oldPassword, String newPassword);

    /**
     * Check if a user with the supplied login name exists in the system.
     */
    boolean userExists(String username);
  • By default, spring security provides 2 implementations of UserDetailsManager. They are InMemoryUserDetailsManager and JdbcUserDetailsManager .
    • InMemoryUserDetailsManager: so if you want to some proof of concept or building some sample applications to demo someone, you can use InMemoryUserDetailsManager. That means you can maintain the users, you can load the user details, authentication details, authorities, everything from the memory itself, which will store and set the spring container. See Example: Configure Users With inMemoryAuthentication, Configure Users With inMemoryUserDetailsManager.
    • JdbcUserDetailsManager: this is the most famous implementation of spring security and this is a production grade of implementation That means if you provide data source details of MySQL or Oracle or any database, this JdbcUserDetailsManager contain all the code related to loading the UserDetails, maintaining them, creating them, deleting them, changing passwords.

InMemoryUserDetailsManager#

  • If you check InMemoryUserDetailsManager you will see there is a property users which is a HashMap of username and MutableUserDetails. So basically, when you create an user using InMemoryUserDetailsManager, your user will be type of MutableUserDetails and it will saved into a HashMap.
InMemoryUserDetailsManager.java
1
2
3
4
5
6
7
public class InMemoryUserDetailsManager implements UserDetailsManager, UserDetailsPasswordService {

    protected final Log logger = LogFactory.getLog(getClass());

    private final Map<String, MutableUserDetails> users = new HashMap<>();

    .....
  • So if you look into the InMemoryUserDetailsManager class, you will see it implement 2 interfaces, one is the UserDetailsManager which is the main interface for managing UserDetails and the second one is the UserDetailsPasswordService that provide the method updatePassword for the UserDetails.

JdbcUserDetailsManager#

  • If you check the JdbcUserDetailsManager you will see it implements UserDetailsManager and another interface called GroupManager. Because in production mode, many user can be added into a group (Ex: admin group). Then in the GroupManager you will see it contains some methods for group management.
JdbcUserDetailsManager.java
1
2
3
public class JdbcUserDetailsManager extends JdbcDaoImpl implements UserDetailsManager, GroupManager {

    .....
GroupManager.java
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
public interface GroupManager {

    /**
     * Returns the names of all groups that this group manager controls.
     */
    List<String> findAllGroups();

    /**
     * Locates the users who are members of a group
     * @param groupName the group whose members are required
     * @return the usernames of the group members
     */
    List<String> findUsersInGroup(String groupName);

    /**
     * Creates a new group with the specified list of authorities.
     * @param groupName the name for the new group
     * @param authorities the authorities which are to be allocated to this group.
     */
    void createGroup(String groupName, List<GrantedAuthority> authorities);

    /**
     * Removes a group, including all members and authorities.
     * @param groupName the group to remove.
     */
    void deleteGroup(String groupName);

    /**
     * Changes the name of a group without altering the assigned authorities or members.
     */
    void renameGroup(String oldName, String newName);

    /**
     * Makes a user a member of a particular group.
     * @param username the user to be given membership.
     * @param group the name of the group to which the user will be added.
     */
    void addUserToGroup(String username, String group);

    /**
     * Deletes a user's membership of a group.
     * @param username the user
     * @param groupName the group to remove them from
     */
    void removeUserFromGroup(String username, String groupName);

    /**
     * Obtains the list of authorities which are assigned to a group.
     */
    List<GrantedAuthority> findGroupAuthorities(String groupName);

    /**
     * Assigns a new authority to a group.
     */
    void addGroupAuthority(String groupName, GrantedAuthority authority);

    /**
     * Deletes an authority from those assigned to a group
     */
    void removeGroupAuthority(String groupName, GrantedAuthority authority);
  • Finally, the JdbcUserDetailsManager will be the one that implement all methods provided for managing user in UserDetails and group in GroupManager.

See Also#

References#