Chapter 4: Managing passwords
The introduction connects the previous chapter’s user management to passwords as an essential part of authentication, then previews the chapter’s topics.
After this chapter you will be able to
- Password role in authentication. Describe passwords as an essential part of the authentication flow alongside the user management discussed in chapter 3.
- PasswordEncoder purpose and place. Explain why systems generally transform passwords instead of managing them as plain text, and identify PasswordEncoder as Spring Security’s separate contract for that responsibility in authentication.
- Password encoding and matching. Explain how PasswordEncoder connects password storage to authentication through its encode() and matches() methods.
- Encoding and matching consistency. Explain why a PasswordEncoder's encode() and matches() implementations must correspond: a value returned by encode() must be verifiable by matches() on the same encoder.
- SHA-512 encoder verification. Trace how the SHA-512 example encodes and verifies a password: encode() returns its hash, while matches() hashes the raw input and compares the hashes.
- Provided encoder choices. Distinguish the provided PasswordEncoder implementations and explain why NoOpPasswordEncoder and StandardPasswordEncoder are unsuitable choices for new real-world applications.
- PBKDF2 configuration tradeoff. Explain which PBKDF2 encoding settings the section discusses and why choosing them involves a resource-versus-strength compromise.
- Changing password algorithms. Explain why an application might retain several password encoders when its password algorithm changes.
- Delegated encoder selection. Trace how DelegatingPasswordEncoder chooses a PasswordEncoder for a stored hash, including the configured default.
- Crypto module scope and benefit. Explain that the Spring Security Crypto module provides cryptography-related features, including the password encoders discussed earlier, and can remove the need for a separate library for accessible key-generation and encryption features.
- Key generator types and outputs. Describe what key generators produce and distinguish the string and byte-array generators provided through KeyGenerators.
- Byte key length and reuse. Explain how byte-key length can be chosen and distinguish keys generated on each call from a shared key.
- Encryptor operations and data types. Distinguish TextEncryptor from BytesEncryptor by the data each accepts and returns, and describe their shared encryption and decryption responsibilities.
- Standard and stronger byte encryptors. Explain how Encryptors.standard() and Encryptors.stronger() differ according to the section.
- Text encryptor factory choices. Describe how Encryptors.text(), Encryptors.delux(), and Encryptors.noOpText() differ.
What it builds on
- Implementing authentication in Spring Security (chapter 3) · The discussion of authentication and managing users in Spring Security.
- Overriding default configurations (chapter 2) · Introduces the idea of overriding Spring Security defaults.
Section by section
Introduction
The introduction connects the previous chapter’s user management to passwords as an essential part of authentication, then previews the chapter’s topics.
- Password role in authentication: Describe passwords as an essential part of the authentication flow alongside the user management discussed in chapter 3.
Why it matters: This connects the chapter’s focus on passwords to the authentication work you have already read about.
Key terms: passwords, authentication flow
4.1 Using password encoders
This section introduces why passwords are transformed and where Spring Security’s PasswordEncoder fits in authentication.
- PasswordEncoder purpose and place: Explain why systems generally transform passwords instead of managing them as plain text, and identify PasswordEncoder as Spring Security’s separate contract for that responsibility in authentication.
Why it matters: This gives you the purpose of PasswordEncoder before you examine its contract and implementations.
Key terms: plain text, transformation, PasswordEncoder, authentication process
4.1.1 The PasswordEncoder contract
Defines how Spring Security’s PasswordEncoder encodes passwords and checks them during authentication.
- Password encoding and matching: Explain how PasswordEncoder connects password storage to authentication through its encode() and matches() methods.
Why it matters: A password can be checked correctly only when validation is compatible with the way it was encoded. - Optional encoding upgrade: Describe the default behavior of upgradeEncoding() and what returning true enables.
Why it matters: The contract includes an optional way to request further encoding of an existing encoded password.
Key terms: PasswordEncoder, encode(), matches(), raw password, encoded password, upgradeEncoding()
4.1.2 Implementing your PasswordEncoder
This section explains how to implement PasswordEncoder so encoded passwords can be verified, using cleartext and SHA-512 examples.
- Encoding and matching consistency: Explain why a PasswordEncoder's encode() and matches() implementations must correspond: a value returned by encode() must be verifiable by matches() on the same encoder.
Why it matters: An encoder is useful for authentication only if it can check passwords against the values it produces. - Cleartext encoder behavior: Describe how the cleartext example implements encoding and matching: encode() returns the password unchanged, and matches() compares the strings for equality.
Why it matters: This simple case makes the relationship between encoding and verification concrete. - SHA-512 encoder verification: Trace how the SHA-512 example encodes and verifies a password: encode() returns its hash, while matches() hashes the raw input and compares the hashes.
Why it matters: It shows how matches() can verify an encoded value without comparing the raw password directly with that value.
Key terms: PasswordEncoder, encode(), matches(), plain text, NoOpPasswordEncoder, equals(), SHA-512, hash, raw password
4.1.3 Choosing from the provided PasswordEncoder implementations
This section compares Spring Security’s provided password encoders and explains how to configure the PBKDF2 and bcrypt options.
- Provided encoder choices: Distinguish the provided PasswordEncoder implementations and explain why NoOpPasswordEncoder and StandardPasswordEncoder are unsuitable choices for new real-world applications.
Why it matters: Choosing a provided encoder avoids unnecessary custom code without mistaking an example-only or deprecated option for a suitable new choice. - PBKDF2 configuration tradeoff: Explain which PBKDF2 encoding settings the section discusses and why choosing them involves a resource-versus-strength compromise.
Why it matters: PBKDF2 settings should balance the desired encoding strength against the cost of generating hashes. - Bcrypt strength configuration: Describe how BCryptPasswordEncoder can be instantiated and how its strength setting affects hashing work.
Why it matters: The bcrypt strength setting changes the amount of work performed during password encoding.
Key terms: PasswordEncoder, NoOpPasswordEncoder, StandardPasswordEncoder, Pbkdf2PasswordEncoder, BCryptPasswordEncoder, SCryptPasswordEncoder, PBKDF2, HMAC, iterations, hash width
4.1.4 Multiple encoding strategies with DelegatingPasswordEncoder
Explains why an application may need multiple password encoders, how DelegatingPasswordEncoder selects among them, and how encoding, encryption, and hashing differ.
- Changing password algorithms: Explain why an application might retain several password encoders when its password algorithm changes.
Why it matters: This is the practical reason for selecting an encoder according to the stored hash. - Delegated encoder selection: Trace how DelegatingPasswordEncoder chooses a PasswordEncoder for a stored hash, including the configured default.
Why it matters: The prefix tells the application which implementation should check a particular stored password. - Encoding and encryption terms: Distinguish general encoding from encryption, and describe how encryption keys relate to decryption.
Why it matters: These distinctions keep the book’s security terminology from being treated as interchangeable. - Hashing and password matching: Explain how hashing differs from encryption and why matching and salts matter.
Why it matters: It explains why passwords can be checked against stored hashes without recovering the original passwords.
Key terms: DelegatingPasswordEncoder, hashes, PasswordEncoder, prefix, map of encoders, default encoder, encoding, encryption, decryption, symmetric key
4.2 Taking advantage of the Spring Security Crypto module
The section introduces the Spring Security Crypto module, why it can simplify project dependencies, and the basic roles of its key generators and encryptors.
- Crypto module scope and benefit: Explain that the Spring Security Crypto module provides cryptography-related features, including the password encoders discussed earlier, and can remove the need for a separate library for accessible key-generation and encryption features.
Why it matters: This explains why a Spring Security project might use the module instead of adding another cryptography library. - Key generator and encryptor roles: Distinguish key generators, which produce keys for hashing and encryption algorithms, from encryptors, which encrypt and decrypt data.
Why it matters: The distinction helps you identify which module feature fits a key-generation task and which fits a data-encryption task.
Key terms: Spring Security Crypto module, SSCM, password encoders, Key generators, Encryptors
4.2.1 Using key generators
This section explains Spring Security’s string and byte key generators, including key length and whether repeated calls produce new or shared values.
- Key generator types and outputs: Describe what key generators produce and distinguish the string and byte-array generators provided through KeyGenerators.
Why it matters: The output type determines which generator fits the key value an algorithm needs. - Byte key length and reuse: Explain how byte-key length can be chosen and distinguish keys generated on each call from a shared key.
Why it matters: Choosing between fresh and repeated key values changes what successive calls to the generator produce.
Key terms: KeyGenerators, StringKeyGenerator, BytesKeyGenerator, generateKey(), salt, KeyGenerators.secureRandom(), KeyGenerators.shared(int length)
4.2.2 Encrypting and decrypting secrets using encryptors
This section explains how Spring Security Crypto encryptors handle strings and bytes, and how to choose among the provided implementations.
- Encryptor operations and data types: Distinguish TextEncryptor from BytesEncryptor by the data each accepts and returns, and describe their shared encryption and decryption responsibilities.
Why it matters: The data type you need to protect determines which encryptor interface fits. - Standard and stronger byte encryptors: Explain how Encryptors.standard() and Encryptors.stronger() differ according to the section.
Why it matters: The factory choice changes the encryption mode used behind the scenes. - Text encryptor factory choices: Describe how Encryptors.text(), Encryptors.delux(), and Encryptors.noOpText() differ.
Why it matters: These choices let you select a text encryptor or deliberately skip encryption in a demo or performance test.
Key terms: BytesEncryptor, TextEncryptor, encryption, decryption, Encryptors.standard(), Encryptors.stronger(), Galois/Counter Mode (GCM), cipher block chaining (CBC), Encryptors.text(), Encryptors.delux()
4.3 Summary
Where this is used later
- Implementing basic authentication using JSON web tokens (chapter 14) · Password encoders.
- Implementing custom authentication logic (chapter 6) · The PasswordEncoder contract used for passwords.
Concepts explained in this chapter
- PasswordEncoderPasswordEncoder is a Spring Security strategy for encoding passwords and matching supplied passwords against stored representations.
- BCryptPasswordEncoderBCryptPasswordEncoder is a Spring Security PasswordEncoder implementation that encodes passwords with the bcrypt password-hashing function.
- SCryptPasswordEncoderSCryptPasswordEncoder is a Spring Security PasswordEncoder implementation that encodes passwords with the scrypt password-hashing function.
- encryptionEncryption is the transformation of readable data into ciphertext using a cryptographic key so that only authorized parties can recover the original data.
- cryptographic saltA salt is additional key-like data combined with an input before a hashing or cryptographic operation to make repeated inputs produce distinct results.
- hash functionA hashing algorithm deterministically transforms input data into an output from which the original input is intended to be impractical to recover.
- DelegatingPasswordEncoderDelegatingPasswordEncoder is a Spring Security PasswordEncoder implementation that selects another password encoder according to an identifier in the stored password representation.
- hash prefixA hash prefix is an identifier prepended to a stored password hash to indicate which password encoder produced it.
- NoOpPasswordEncoderNoOpPasswordEncoder is a Spring Security PasswordEncoder implementation that leaves passwords in cleartext instead of applying one-way encoding.
- Pbkdf2PasswordEncoderPbkdf2PasswordEncoder is a Spring Security PasswordEncoder implementation that derives password representations using PBKDF2.
- StandardPasswordEncoderStandardPasswordEncoder is a deprecated Spring Security PasswordEncoder implementation that hashes passwords with SHA-256 and an optional secret.
- pbkdf2PBKDF2 is a password-based key-derivation standard that repeatedly applies a pseudorandom function to derive a cryptographic key from a password and salt.
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.
