15 · Security / LESSON 73 OF 102
Password hashes and resource ownership
Protect each user’s data rather than merely requiring a login.
Before this lesson: Authentication and filter chains
Understand the topic
Store password hashes, never plaintext or reversible encrypted passwords. PasswordEncoder handles hashing and verification. The bean below supplies an encoder; it is not a registration or user-storage implementation.
Add an owner identity to Task. Obtain the owner from the authenticated principal, not a client field. Scope every list, read, update, and delete by owner. A role check alone cannot prevent one user accessing another user’s guessed task ID.
EXAMPLE · JAVA
src/main/java/com/example/tasks/PasswordConfig.java
package com.example.tasks;
import org.springframework.context.annotation.*;
import org.springframework.security.crypto.factory.PasswordEncoderFactories;
import org.springframework.security.crypto.password.PasswordEncoder;
@Configuration
public class PasswordConfig {
@Bean
PasswordEncoder passwordEncoder() {
return PasswordEncoderFactories.createDelegatingPasswordEncoder();
}
}
// Store encoder.encode(rawPassword).
// Verify encoder.matches(candidate, storedHash).What to expect
Hashes can differ for the same password; matches verifies a candidate. Never return a stored hash in a DTO.
YOUR TURN
Put it into practice
- 01Create two test users and deny cross-user task access.
- 02Implement findByIdAndOwnerId and owner-scoped lists.
- 03Keep passwords and hashes out of logs.
Pass a quiz or complete a lab to check today’s streak. Each lesson counts once per day, including when you review it later.
UNDER THE HOOD
Build the mental model
A valid identity is not permission to act on every record. Enforce ownership at every resource boundary.
- 01Use the authenticated principal to determine owner identity. Ignore or reject a client-supplied owner field for ordinary creation.
- 02Read, list, update, and delete all require ownership scope. Testing only GET-one misses list and mutation leaks.
- 03Password hashes are verification material. Do not compare newly generated hashes as strings because salted encodings differ. Use PasswordEncoder.matches.
A mistake worth avoiding
Do not log tokens or hashes while diagnosing login failures.
DEBUGGING ROOM
Something broke. Where do you look?
Changing a task ID in the URL allows reading another user’s task.
Before revealing the diagnosis, write down your first investigation step.
CHECK YOUR UNDERSTANDING
Where should a new task’s owner come from?
BUILD IT YOURSELF
Create a two-user isolation suite
- 1.Create Alice and Bob with separate tasks.
- 2.Try each user’s IDs across read, update, and delete.
- 3.Check list pagination never contains the other user’s rows.
Acceptance checklist
Lab completion is your self-report. Knowledge checks do not certify project quality.
RETRIEVE IT FROM MEMORY
Why is a role check insufficient for a personal task API?
Revisit this lesson in three days after a successful check or lab.
Ready for the next step?
Explain password verification and object-level authorization.
Reading is separate from passing a knowledge check or completing a lab.