Authorization — What May You Do?
Asha has logged in to library-service. She may borrow books, but should she be able to delete one from the catalogue? Knowing who someone is does not answer what they may do. That second question is authorization, and Spring Security lets you answer it at the URL, at the method, or both.
The rule
Authorization asks what a known user may do — by URL first, by method for detail.
Every authenticated user carries a list of authorities, simple strings such as ROLE_MEMBER, ROLE_LIBRARIAN or SCOPE_books.write. A role is just an authority whose name starts with ROLE_. That is why hasRole("LIBRARIAN") checks for the authority ROLE_LIBRARIAN: the prefix is added for you.
URL rules go in the filter chain configuration. They are checked top to bottom, and the first match wins:
http.authorizeHttpRequests(auth -> auth
.requestMatchers(HttpMethod.GET, "/books/**").permitAll()
.requestMatchers(HttpMethod.DELETE, "/books/**").hasRole("LIBRARIAN")
.requestMatchers("/books/*/borrow").hasAnyRole("MEMBER", "LIBRARIAN")
.anyRequest().authenticated());Method rules go on the service itself, after turning them on with @EnableMethodSecurity on a configuration class:
@PreAuthorize("hasRole('LIBRARIAN') or #memberId == authentication.principal.id")
public List<Loan> loansFor(long memberId) { ... }The expression can use the method's parameters, so it can say "librarians, or the member asking about their own loans", which a URL rule cannot. (principal.id assumes your own UserDetails class has an id field.) Method security runs through a proxy, so the self-call trap from the AOP lesson applies here too.
The shortcut
Write URL rules like a funnel: most specific first, anyRequest() last. When you read someone else's rules, walk down the list with the request in hand and stop at the first line that matches.
Line 1
GET /books/**— the method is DELETE, so no match. Keep going.
The ordering trap: if .anyRequest().authenticated() were written first, it would match everything, and the librarian rule below it would never be reached. Spring Security actually refuses to start when anyRequest() is not last, which is a helpful guard.
Drills
Answer fast — trust the rule.
A logged-in member tries an action only librarians may do. Which status is typical?
hasRole("LIBRARIAN") checks for which authority string?
How are the rules inside authorizeHttpRequests evaluated?
Which rule can say "librarians, or the member whose id is the memberId argument"?
Remember
- Authorization asks what a known user may do — by URL first, by method for detail.
- URL rules: most specific first,
anyRequest()last; first match wins. - Trap:
hasRole("X")means the authorityROLE_X.
