Methoden-Sicherheit, CORS & CSRF
@PreAuthorize für feingranulare Regeln sowie was CORS und CSRF sind und wie Spring damit umgeht.
Deutsche Übersetzung in Arbeit
Diese Lektion ist noch nicht ins Deutsche übersetzt und wird daher auf Englisch angezeigt. Der Rest der Seite ist vollständig lokalisiert.
Auf dieser Seite
URL-based rules cover most access control, but sometimes a rule belongs on the method, close to the logic it protects. And two acronyms - CORS and CSRF - trip up nearly every web developer. This lesson finishes the Security module by tidying up all three.
Method security with @PreAuthorize
Enable it once, then annotate methods with an authorization expression that's checked before the method runs:
@Configuration
@EnableMethodSecurity // turns on @PreAuthorize/@PostAuthorize
class MethodSecurityConfig {}@Service
class BookService {
@PreAuthorize("hasRole('LIBRARIAN')")
public void delete(String isbn) { ... } // 403 unless the caller is a LIBRARIAN
@PreAuthorize("#memberId == authentication.principal.id or hasRole('LIBRARIAN')")
public List<Loan> loansOf(Long memberId) { ... } // your own loans, or a librarian's view
}The second example shows method security's real strength: expressions can reference method arguments and the current user, so you can enforce "a member may see only their own data" - a rule that URL matchers can't express.
URL rules for coarse, method rules for fine
Use authorizeHttpRequests for broad, endpoint-level rules (this path needs LIBRARIAN),
and @PreAuthorize for fine-grained, data-aware rules (you may act only on your own
records). They complement each other; you don't have to choose one.
CORS: who may call your API from a browser
CORS (Cross-Origin Resource Sharing) is a browser security feature. By default a
web page at app.bookvault.dev cannot call an API at api.bookvault.dev (a different
origin) unless the API explicitly allows it. You opt in per allowed origin:
http.cors(cors -> cors.configurationSource(request -> {
var config = new CorsConfiguration();
config.setAllowedOrigins(List.of("https://app.bookvault.dev"));
config.setAllowedMethods(List.of("GET", "POST", "PUT", "DELETE"));
return config;
}));CORS isn't a lock on your API - it's the browser asking your API "may this website talk to you?" and honoring the answer. Non-browser clients ignore it entirely.
CSRF: and why you disabled it
CSRF (Cross-Site Request Forgery) tricks a logged-in user's browser into sending an unwanted request using their session cookie. Spring Security's CSRF protection defends session-cookie apps. But BookVault authenticates with a Bearer token, not a cookie the browser attaches automatically - so there's nothing for CSRF to exploit, which is exactly why you disabled CSRF for the stateless API earlier.
Keep CSRF on for cookie/session apps
Disabling CSRF is correct only for stateless, token-authenticated APIs. If you build a traditional server-rendered app that authenticates with a session cookie, leave CSRF protection enabled - it's a genuine defense there.
BookVault must let a member view their own active loans but not anyone else's, while
a LIBRARIAN may view any member's. A URL rule like hasRole('MEMBER') can't express
"only your own." Which mechanism do you use, and roughly what expression enforces it?
What can @PreAuthorize express that URL-based (authorizeHttpRequests) rules cannot?
Key takeaways
- @EnableMethodSecurity + @PreAuthorize put authorization on methods, checked before they run.
- Method expressions can reference arguments and the current user, enabling fine-grained rules like 'only your own data' that URL matchers can't express.
- Use URL rules for coarse endpoint access and method security for fine-grained, data-aware checks - they complement each other.
- CORS is a browser feature: your API opts in to which cross-origin sites may call it; non-browser clients ignore it.
- CSRF protection defends cookie/session apps; it's safe to disable only for stateless, Bearer-token APIs like BookVault.