Every level follows the same five steps: name the threat, configure the gate, recognise the pattern, trace the user flow, then prove it with a test.
GET /hello→session ledu→AuthorizationFilter deny→ExceptionTranslationFilter→302 /login→POST /login→UsernamePasswordAuthenticationFilter→session lo SecurityContext→302 /hello→200authorizeHttpRequests + InMemoryUserDetailsManager (USER, ADMIN)AuthorizationManager)GET /admin→AuthorizationFilter→AccessDeniedException→403|ADMIN→200|anonymous→401/302@WithMockUser)UserDetailsService, BCryptPasswordEncoder, failure event listenerUserDetails), Observer (auth events)POST /register→BCrypt hash→DB|login→DaoAuthenticationProvider→loadUserByUsername→matches()→success event|wrong password ×5→listener→account locked→next login 401OncePerRequestFilter, tarvata oauth2ResourceServer().jwt() tho replace; session STATELESS; CSRF off (cookies levu kabatti)JwtDecoder)POST /api/login→JWT|GET /api/orders + Bearer→BearerTokenAuthenticationFilter→signature + expiry check→SecurityContext→200|tampered/expired→401 + WWW-Authenticate@EnableMethodSecurity, @PreAuthorize leda service lo owner checkGET /api/orders/42 (B di)→filter chain pass (authenticated)→method proxy→owner ≠ A→403/404@PreAuthorize skip avtundani prove chese test@Order(1) apiChain securityMatcher("/api/**") + @Order(2) webChain (form login + CSRF); custom AuthenticationEntryPoint / AccessDeniedHandler (clean JSON); login rate limit/api/**→JWT chain|Browser→/web/**→session chain→form POST CSRF token tho→200|token lekunda→403|API ki session cookie matrame→401oauth2Login(), custom OAuth2UserService (Google user → local user + roles)OidcUser)/login→Google ki redirect→consent→/login/oauth2/code/google?code&state→OAuth2LoginAuthenticationFilter state check + code exchange→OidcUser→local user map→session→200oauth2Login() test post-processor tho role mapping test