Chapter 3: Managing users
The chapter introduction explains why Spring Security uses interface contracts to manage users and identifies the user-related contracts the chapter will develop.
After this chapter you will be able to
- Interface contracts and implementations. Explain how interface contracts let an application integrate with a framework without tying it to one implementation.
- User-related contract roles. Distinguish the roles assigned here to UserDetails, GrantedAuthority, and UserDetailsManager, including how UserDetailsManager relates to UserDetailsService.
- User management in authentication. Explain that UserDetailsService and PasswordEncoder are the components of the authentication flow concerned with user details and credentials.
- User retrieval and management contracts. Distinguish UserDetailsService’s retrieval of a user by username from UserDetailsManager’s added operations for adding, modifying, or deleting users, and explain why the contracts are separate.
- Users and their authorities. Describe how UserDetails represents a user to Spring Security and how GrantedAuthority represents actions that user is allowed to do.
- UserDetails as the user blueprint. Explain that an application’s user class implements the UserDetails contract so Spring Security can understand the user, whose identity informs decisions about access to functionality.
- Credentials in UserDetails. Distinguish the UserDetails methods that supply authentication details from those used for authorization.
- User authorities and privileges. Explain what an authority represents and what getAuthorities() returns.
- Account restriction status methods. Describe the four UserDetails status methods and explain when they should return true or false.
- Authorities as User Privileges. Explain that authorities represent what a user can do in an application and let it distinguish users with different privileges, such as reading versus modifying data. State that a user must have at least one authority.
- Named GrantedAuthority Instances. Describe how an authority is given a name for later authorization rules and how getAuthority() returns that name as a String. Explain that instances can be made with a lambda expression or with SimpleGrantedAuthority, which creates an immutable instance from a supplied name.
- Minimal DummyUser contract. Describe what the DummyUser implementation returns for the UserDetails methods discussed here: a fixed username and password, one authority, and true for its four remaining methods.
- Reusable user instances. Explain why the fixed-value DummyUser is only a teaching example and how the proposed practical class differs.
- Built-in UserDetails construction. Explain when to use Spring Security’s User builder instead of writing a custom UserDetails implementation, and state the minimum information it requires.
- User builder creation and completion. Describe how to start a UserBuilder and what happens when build() completes the user.
- Mixed user class responsibilities. Explain why making a JPA User entity also implement UserDetails makes the class harder to read and maintain.
- SecurityUser entity adapter. Describe how SecurityUser wraps a User entity to provide the UserDetails contract while leaving persistence concerns in User.
- UserDetailsService in authentication. Explain that UserDetails describes users, while authentication delegates user management to a UserDetailsService instance.
- UserDetailsService lookup contract. Explain that the authentication implementation calls UserDetailsService’s sole method, loadUserByUsername(String username), to retrieve a UserDetails implementation for a unique username, and that a missing username causes a UsernameNotFoundException.
- User retrieval implementation. Explain that an application implements UserDetailsService to retrieve a user by username, regardless of where it stores user details. Describe how the example searches its in-memory list, returning the matching UserDetails or throwing UsernameNotFoundException.
- UserDetailsManager contract and purpose. Explain why an application might use UserDetailsManager instead of only UserDetailsService: authentication needs user lookup, while applications may also need to add or delete users.
- JDBC user storage and configuration. Describe how the example uses JdbcUserDetailsManager with an SQL database: its expected users and authorities data, a DataSource and matching JDBC driver, and database-stored credentials used for HTTP Basic authentication.
What it builds on
- Customizing user details management (chapter 2) · Introduces customization of user details management.
Section by section
Introduction
The chapter introduction explains why Spring Security uses interface contracts to manage users and identifies the user-related contracts the chapter will develop.
- Interface contracts and implementations: Explain how interface contracts let an application integrate with a framework without tying it to one implementation.
Why it matters: This explains why the chapter focuses on interfaces rather than a single way to store or manage users. - User-related contract roles: Distinguish the roles assigned here to UserDetails, GrantedAuthority, and UserDetailsManager, including how UserDetailsManager relates to UserDetailsService.
Why it matters: Keeping these contracts distinct makes it easier to follow how the chapter describes users and manages them.
Key terms: contracts, interfaces, implementations, abstractions, UserDetails, GrantedAuthority, UserDetailsService, UserDetailsManager
3.1 Implementing authentication in Spring Security
This section locates user management in Spring Security’s authentication architecture and introduces the contracts for retrieving, managing, and representing users.
- User management in authentication: Explain that UserDetailsService and PasswordEncoder are the components of the authentication flow concerned with user details and credentials.
Why it matters: It places user and credential handling within the larger authentication architecture. - User retrieval and management contracts: Distinguish UserDetailsService’s retrieval of a user by username from UserDetailsManager’s added operations for adding, modifying, or deleting users, and explain why the contracts are separate.
Why it matters: The distinction helps you choose a contract without implementing unnecessary user-management operations. - Users and their authorities: Describe how UserDetails represents a user to Spring Security and how GrantedAuthority represents actions that user is allowed to do.
Why it matters: It connects the user retrieved during authentication with the privileges later used for authorization.
Key terms: authentication flow, user management part, UserDetailsService, PasswordEncoder, UserDetailsManager, interface segregation principle, UserDetails, GrantedAuthority, authorities, privileges
3.2 Describing the user
The section explains why an application’s user class must implement UserDetails for Spring Security to understand its users.
- UserDetails as the user blueprint: Explain that an application’s user class implements the UserDetails contract so Spring Security can understand the user, whose identity informs decisions about access to functionality.
Why it matters: It connects your application’s user model to the user representation Spring Security expects.
Key terms: UserDetails contract, user
3.2.1 Describing users with the UserDetails contract
This section explains how the UserDetails contract represents a user’s credentials, authorities, and account restrictions.
- Credentials in UserDetails: Distinguish the UserDetails methods that supply authentication details from those used for authorization.
Why it matters: This distinction clarifies what each part of a user description is for. - User authorities and privileges: Explain what an authority represents and what getAuthorities() returns.
Why it matters: Authorities express what actions a user is permitted to perform. - Account restriction status methods: Describe the four UserDetails status methods and explain when they should return true or false.
Why it matters: Their positive-sounding names make it important to interpret each boolean correctly.
Key terms: UserDetails, getUsername(), getPassword(), authentication, authorization, authority, privilege, getAuthorities(), isAccountNonExpired(), isAccountNonLocked()
3.2.2 Detailing on the GrantedAuthority contract
Explains how Spring Security represents a user's privileges as authorities and how to create named GrantedAuthority instances.
- Authorities as User Privileges: Explain that authorities represent what a user can do in an application and let it distinguish users with different privileges, such as reading versus modifying data. State that a user must have at least one authority.
Why it matters: Authorities give authorization rules a way to distinguish users by their permitted actions. - Named GrantedAuthority Instances: Describe how an authority is given a name for later authorization rules and how getAuthority() returns that name as a String. Explain that instances can be made with a lambda expression or with SimpleGrantedAuthority, which creates an immutable instance from a supplied name.
Why it matters: Naming privileges makes it possible to refer to them in authorization rules.
Key terms: authorities, GrantedAuthority, getAuthority(), SimpleGrantedAuthority, lambda expression
3.2.3 Writing a minimal implementation of UserDetails
This section uses a fixed-value DummyUser to show what a UserDetails implementation supplies, then explains why a practical implementation needs to represent different users.
- Minimal DummyUser contract: Describe what the DummyUser implementation returns for the UserDetails methods discussed here: a fixed username and password, one authority, and true for its four remaining methods.
Why it matters: The fixed-value example makes the UserDetails methods concrete before introducing users that vary by instance. - Reusable user instances: Explain why the fixed-value DummyUser is only a teaching example and how the proposed practical class differs.
Why it matters: Per-instance user data lets one class describe more than the single hard-coded example user.
Key terms: DummyUser, UserDetails, getUsername(), getPassword(), getAuthorities(), GrantedAuthority, instances, username, password, attributes
3.2.4 Using a builder to create instances of the UserDetails type
This section shows how Spring Security’s User builder creates simple, immutable UserDetails instances without a custom implementation.
- Built-in UserDetails construction: Explain when to use Spring Security’s User builder instead of writing a custom UserDetails implementation, and state the minimum information it requires.
Why it matters: It gives you a concise option when a custom user class would add unnecessary code. - User builder creation and completion: Describe how to start a UserBuilder and what happens when build() completes the user.
Why it matters: It clarifies both ways to begin building a user and what the final build step does.
Key terms: User, UserDetails, User builder class, immutable, User.withUsername(String username), UserBuilder, build(), Function<String, String>, PasswordEncoder
3.2.5 Combining multiple responsibilities related to the user
The section shows how to keep database persistence and Spring Security user details separate by wrapping a JPA User entity in a SecurityUser adapter.
- Mixed user class responsibilities: Explain why making a JPA User entity also implement UserDetails makes the class harder to read and maintain.
Why it matters: Separating these concerns makes the code easier to read and maintain. - SecurityUser entity adapter: Describe how SecurityUser wraps a User entity to provide the UserDetails contract while leaving persistence concerns in User.
Why it matters: The adapter lets Spring Security use the persisted user without combining the two classes’ responsibilities.
Key terms: JPA entity, UserDetails, responsibilities, SecurityUser, User
3.3 Instructing Spring Security on how to manage users
This introduction distinguishes describing a user from the component Spring Security delegates to for user management during authentication.
- UserDetailsService in authentication: Explain that UserDetails describes users, while authentication delegates user management to a UserDetailsService instance.
Why it matters: The distinction separates what represents a user from the component involved in finding users during authentication.
Key terms: UserDetails, UserDetailsService, authentication process, user management
3.3.1 Understanding the UserDetailsService contract
This subsection defines how UserDetailsService supplies user details during authentication and what happens when a username is not found.
- UserDetailsService lookup contract: Explain that the authentication implementation calls UserDetailsService’s sole method, loadUserByUsername(String username), to retrieve a UserDetails implementation for a unique username, and that a missing username causes a UsernameNotFoundException.
Why it matters: This contract tells you what user information authentication expects a UserDetailsService to provide. - Missing user exception hierarchy: Describe why the throws clause for UsernameNotFoundException is documentation rather than a requirement to handle a checked exception.
Why it matters: It clarifies how to read the exception declaration in the interface.
Key terms: UserDetailsService, loadUserByUsername(String username), UserDetails, UsernameNotFoundException, AuthenticationException, RuntimeException, throws clause
3.3.2 Implementing the UserDetailsService contract
This section implements an in-memory UserDetailsService, registers it with Spring Security, and checks it through an endpoint.
- User retrieval implementation: Explain that an application implements UserDetailsService to retrieve a user by username, regardless of where it stores user details. Describe how the example searches its in-memory list, returning the matching UserDetails or throwing UsernameNotFoundException.
Why it matters: This is the part of user management that connects an application's user records to Spring Security. - Service registration and endpoint check: Describe how the example makes its UserDetailsService available as a bean with one registered user, then checks the setup through an endpoint. State the observed responses for the given credentials and for other credentials.
Why it matters: Registering the service and trying the endpoint show that the implementation is being used in the application.
Key terms: UserDetailsService, loadUserByUsername(String username), UserDetails, UsernameNotFoundException, bean, configuration class, cURL, HTTP 200 OK, 401 Unauthorized
3.3.3 Implementing the UserDetailsManager contract
This section explains how UserDetailsManager extends user lookup with user-management operations and shows how to use JDBC or LDAP implementations for authentication.
- UserDetailsManager contract and purpose: Explain why an application might use UserDetailsManager instead of only UserDetailsService: authentication needs user lookup, while applications may also need to add or delete users.
Why it matters: It distinguishes finding a user for authentication from managing that user's account. - JDBC user storage and configuration: Describe how the example uses JdbcUserDetailsManager with an SQL database: its expected users and authorities data, a DataSource and matching JDBC driver, and database-stored credentials used for HTTP Basic authentication.
Why it matters: These are the pieces that let the example authenticate against users stored in a database rather than in memory. - Custom JDBC lookup queries: Explain why and how the JdbcUserDetailsManager's queries can be overridden when an application's table or column names differ from the defaults.
Why it matters: An existing database need not adopt the manager's default naming scheme. - LDAP user management example: Describe the alternative LdapUserDetailsManager example: an embedded LDAP server populated from an LDIF file is configured, then the manager is used to authenticate its user.
Why it matters: It shows that the user-management contract can be backed by LDAP as well as SQL.
Key terms: UserDetailsManager, UserDetailsService, InMemoryUserDetailsManager, JdbcUserDetailsManager, JDBC, DataSource, users, authorities, enabled, queries
3.4 Summary
Where this is used later
- The PasswordEncoder contract (chapter 4) · Examines the PasswordEncoder contract introduced here.
- (chapter intro) (chapter 4) · The discussion of authentication and managing users in Spring Security.
- Restricting access based on authorities and roles (chapter 7) · Uses authorities when restricting access.
- Using mock users for tests (chapter 18) · Users have details such as authorities.
- Implementing custom authentication logic (chapter 6) · Custom authentication logic uses the distinction between credentials and other user details.
- Restricting access for all endpoints based on user authorities (chapter 7) · Endpoint restrictions based on user authorities rely on the privileges associated with a user.
- Representing the request during authentication (chapter 6) · The concept of granted authorities.
- Adding a filter at the location of another in the chain (chapter 5) · The role of the UserDetailsService contract in managing user details.
Concepts explained in this chapter
- UserDetailsManagerUserDetailsManager is a Spring Security interface that extends UserDetailsService with operations for creating users and modifying or deleting user passwords.
- UserDetailsUserDetails is a Spring Security representation of a user's identity, password, and granted authorities.
- JdbcUserDetailsManagerJdbcUserDetailsManager is a Spring Security UserDetailsService and UserDetailsManager implementation that stores and manages user details through JDBC and a relational database.
- LdapUserDetailsManagerLdapUserDetailsManager is a Spring Security UserDetailsManager implementation that retrieves and manages user details in an LDAP directory.
- UserDetailsServiceUserDetailsService is a Spring Security interface for retrieving user-specific data needed to authenticate a user.
- GrantedAuthorityGrantedAuthority is a Spring Security interface representing an authority granted to an authenticated principal.
- user managementUser management is the administration of user identities, credentials, and related account information in an application.
- getAuthorities()getAuthorities() is a UserDetails method that returns the authorities granted to the user.
- authorizationAuthorization is the process of determining whether an authenticated entity has permission to perform an action or access a resource.
These guides are generated from the text of Manning books by Manning's knowledge graph and link to the sections they draw on. The full books are available on liveBook and at manning.com.
