Careeroza
Authorizing Requests
The Rule Methods
| Method | Meaning |
|---|---|
permitAll() | anyone, logged in or not |
authenticated() | any logged-in user |
denyAll() | nobody (block an endpoint completely) |
anonymous() | only users who are NOT logged in (e.g. a register page) |
hasRole("ADMIN") | logged-in users with that role (roles in depth: medium level) |
.authorizeHttpRequests(auth -> auth
.requestMatchers(HttpMethod.GET, "/api/products/**", "/api/categories/**").permitAll()
.requestMatchers("/api/auth/register").anonymous()
.requestMatchers("/api/internal/**").denyAll()
.requestMatchers(PathRequest.toStaticResources().atCommonLocations()).permitAll() // /css, /js, /images, favicon
.anyRequest().authenticated())First Match Wins
Example
Rules are checked top to bottom and the first matching rule decides. Put specific rules first and anyRequest() last:
import java.util.*;
import java.util.function.Predicate;
public class Main {
record Rule(String pattern, String decision) {}
static boolean matches(String pattern, String path) {
if (pattern.equals("anyRequest")) return true;
if (pattern.endsWith("/**")) return path.startsWith(pattern.substring(0, pattern.length() - 3));
return pattern.equals(path);
}
static String decide(List<Rule> rules, String path) {
for (Rule r : rules) if (matches(r.pattern(), path)) return r.decision() + " (rule " + r.pattern() + ")";
return "no rule";
}
public static void main(String[] args) {
List<Rule> good = List.of(new Rule("/api/products/**", "permitAll"), new Rule("anyRequest", "authenticated"));
List<Rule> bad = List.of(new Rule("anyRequest", "authenticated"), new Rule("/api/products/**", "permitAll"));
for (String path : List.of("/api/products/7", "/api/orders")) {
System.out.println("GOOD order " + path + " -> " + decide(good, path));
System.out.println("WRONG order " + path + " -> " + decide(bad, path));
}
}
}Output
GOOD order /api/products/7 -> permitAll (rule /api/products/**) WRONG order /api/products/7 -> authenticated (rule anyRequest) GOOD order /api/orders -> authenticated (rule anyRequest) WRONG order /api/orders -> authenticated (rule anyRequest)
Note: Spring Security 6 refuses to start if anyRequest() is not the last rule: "Can't configure requestMatchers after anyRequest". Order mistakes between two specific rules (for example /api/** before /api/admin/**) are not detected, so be careful.
Matching by HTTP Method
ShopEase lets everyone read products, but changing them needs a login. Pass an HttpMethod as the first argument:
.authorizeHttpRequests(auth -> auth
.requestMatchers(HttpMethod.GET, "/api/products/**").permitAll()
.requestMatchers(HttpMethod.POST, "/api/products").authenticated()
.anyRequest().authenticated())Result
curl -s -o /dev/null -w "GET %{http_code}\n" localhost:8080/api/products/1
curl -s -o /dev/null -w "POST %{http_code}\n" -X POST localhost:8080/api/products
curl -s -o /dev/null -w "DELETE %{http_code}\n" -X DELETE localhost:8080/api/products/1Example output
GET 200 POST 401 DELETE 401
Tip: Default to secure: end with .anyRequest().authenticated() (or denyAll()), so a new endpoint someone forgets to list is protected, not public.