Browse Source

Revisit Request and Method Security Docs

Issue gh-13088
Josh Cummings 2 years ago
parent
commit
e5fcf1ebcf

BIN
docs/modules/ROOT/assets/images/servlet/authorization/methodsecurity.odg


BIN
docs/modules/ROOT/assets/images/servlet/authorization/methodsecurity.png


+ 0 - 2
docs/modules/ROOT/nav.adoc

@@ -59,9 +59,7 @@
 ** xref:servlet/authorization/index.adoc[Authorization]
 ** xref:servlet/authorization/index.adoc[Authorization]
 *** xref:servlet/authorization/architecture.adoc[Authorization Architecture]
 *** xref:servlet/authorization/architecture.adoc[Authorization Architecture]
 *** xref:servlet/authorization/authorize-http-requests.adoc[Authorize HTTP Requests]
 *** xref:servlet/authorization/authorize-http-requests.adoc[Authorize HTTP Requests]
-*** xref:servlet/authorization/authorize-requests.adoc[Authorize HTTP Requests with FilterSecurityInterceptor]
 *** xref:servlet/authorization/expression-based.adoc[Expression-Based Access Control]
 *** xref:servlet/authorization/expression-based.adoc[Expression-Based Access Control]
-*** xref:servlet/authorization/secure-objects.adoc[Secure Object Implementations]
 *** xref:servlet/authorization/method-security.adoc[Method Security]
 *** xref:servlet/authorization/method-security.adoc[Method Security]
 *** xref:servlet/authorization/acls.adoc[Domain Object Security ACLs]
 *** xref:servlet/authorization/acls.adoc[Domain Object Security ACLs]
 *** xref:servlet/authorization/events.adoc[Authorization Events]
 *** xref:servlet/authorization/events.adoc[Authorization Events]

+ 1 - 1
docs/modules/ROOT/pages/migration/servlet/authorization.adoc

@@ -36,7 +36,7 @@ There are no further migrations steps for Java or Kotlin for this feature.
 == Use `AuthorizationManager` for Request Security
 == Use `AuthorizationManager` for Request Security
 
 
 In 6.0, `<http>` defaults `once-per-request` to `false`, `filter-all-dispatcher-types` to `true`, and `use-authorization-manager` to `true`.
 In 6.0, `<http>` defaults `once-per-request` to `false`, `filter-all-dispatcher-types` to `true`, and `use-authorization-manager` to `true`.
-Also, xref:servlet/authorization/authorize-requests.adoc#filtersecurityinterceptor-every-request[`authorizeRequests#filterSecurityInterceptorOncePerRequest`] defaults to `false` and xref:servlet/authorization/authorize-http-requests.adoc[`authorizeHttpRequests#filterAllDispatcherTypes`] defaults to `true`.
+Also, {security-api-url}org/springframework/security/config/annotation/web/configurers/AbstractInterceptUrlConfigurer.AbstractInterceptUrlRegistry.html#filterSecurityInterceptorOncePerRequest(boolean)[`authorizeRequests#filterSecurityInterceptorOncePerRequest`] defaults to `false` and xref:servlet/authorization/authorize-http-requests.adoc[`authorizeHttpRequests#filterAllDispatcherTypes`] defaults to `true`.
 So, to complete migration, any defaults values can be removed.
 So, to complete migration, any defaults values can be removed.
 
 
 For example, if you opted in to the 6.0 default for `filter-all-dispatcher-types` or `authorizeHttpRequests#filterAllDispatcherTypes` like so:
 For example, if you opted in to the 6.0 default for `filter-all-dispatcher-types` or `authorizeHttpRequests#filterAllDispatcherTypes` like so:

+ 1 - 1
docs/modules/ROOT/pages/servlet/architecture.adoc

@@ -194,7 +194,7 @@ The following is a comprehensive list of Spring Security Filter ordering:
 * `OAuth2AuthorizationCodeGrantFilter`
 * `OAuth2AuthorizationCodeGrantFilter`
 * `SessionManagementFilter`
 * `SessionManagementFilter`
 * <<servlet-exceptiontranslationfilter,`ExceptionTranslationFilter`>>
 * <<servlet-exceptiontranslationfilter,`ExceptionTranslationFilter`>>
-* xref:servlet/authorization/authorize-requests.adoc#servlet-authorization-filtersecurityinterceptor[`FilterSecurityInterceptor`]
+* xref:servlet/authorization/authorize-http-requests.adoc[`AuthorizationFilter`]
 * `SwitchUserFilter`
 * `SwitchUserFilter`
 
 
 [[servlet-exceptiontranslationfilter]]
 [[servlet-exceptiontranslationfilter]]

+ 1 - 1
docs/modules/ROOT/pages/servlet/authentication/passwords/basic.adoc

@@ -15,7 +15,7 @@ The preceding figure builds off our xref:servlet/architecture.adoc#servlet-secur
 
 
 image:{icondir}/number_1.png[] First, a user makes an unauthenticated request to the resource `/private` for which it is not authorized.
 image:{icondir}/number_1.png[] First, a user makes an unauthenticated request to the resource `/private` for which it is not authorized.
 
 
-image:{icondir}/number_2.png[] Spring Security's xref:servlet/authorization/authorize-requests.adoc#servlet-authorization-filtersecurityinterceptor[`FilterSecurityInterceptor`] indicates that the unauthenticated request is __Denied__ by throwing an `AccessDeniedException`.
+image:{icondir}/number_2.png[] Spring Security's xref:servlet/authorization/authorize-http-requests.adoc[`AuthorizationFilter`] indicates that the unauthenticated request is __Denied__ by throwing an `AccessDeniedException`.
 
 
 image:{icondir}/number_3.png[] Since the user is not authenticated, xref:servlet/architecture.adoc#servlet-exceptiontranslationfilter[`ExceptionTranslationFilter`] initiates __Start Authentication__.
 image:{icondir}/number_3.png[] Since the user is not authenticated, xref:servlet/architecture.adoc#servlet-exceptiontranslationfilter[`ExceptionTranslationFilter`] initiates __Start Authentication__.
 The configured xref:servlet/authentication/architecture.adoc#servlet-authentication-authenticationentrypoint[`AuthenticationEntryPoint`] is an instance of {security-api-url}org/springframework/security/web/authentication/www/BasicAuthenticationEntryPoint.html[`BasicAuthenticationEntryPoint`], which sends a WWW-Authenticate header.
 The configured xref:servlet/authentication/architecture.adoc#servlet-authentication-authenticationentrypoint[`AuthenticationEntryPoint`] is an instance of {security-api-url}org/springframework/security/web/authentication/www/BasicAuthenticationEntryPoint.html[`BasicAuthenticationEntryPoint`], which sends a WWW-Authenticate header.

+ 1 - 1
docs/modules/ROOT/pages/servlet/authentication/passwords/form.adoc

@@ -16,7 +16,7 @@ The preceding figure builds off our xref:servlet/architecture.adoc#servlet-secur
 
 
 image:{icondir}/number_1.png[] First, a user makes an unauthenticated request to the resource (`/private`) for which it is not authorized.
 image:{icondir}/number_1.png[] First, a user makes an unauthenticated request to the resource (`/private`) for which it is not authorized.
 
 
-image:{icondir}/number_2.png[] Spring Security's xref:servlet/authorization/authorize-requests.adoc#servlet-authorization-filtersecurityinterceptor[`FilterSecurityInterceptor`] indicates that the unauthenticated request is __Denied__ by throwing an `AccessDeniedException`.
+image:{icondir}/number_2.png[] Spring Security's xref:servlet/authorization/authorize-http-requests.adoc[`AuthorizationFilter`] indicates that the unauthenticated request is __Denied__ by throwing an `AccessDeniedException`.
 
 
 image:{icondir}/number_3.png[] Since the user is not authenticated, xref:servlet/architecture.adoc#servlet-exceptiontranslationfilter[`ExceptionTranslationFilter`] initiates __Start Authentication__ and sends a redirect to the login page with the configured xref:servlet/authentication/architecture.adoc#servlet-authentication-authenticationentrypoint[`AuthenticationEntryPoint`].
 image:{icondir}/number_3.png[] Since the user is not authenticated, xref:servlet/architecture.adoc#servlet-exceptiontranslationfilter[`ExceptionTranslationFilter`] initiates __Start Authentication__ and sends a redirect to the login page with the configured xref:servlet/authentication/architecture.adoc#servlet-authentication-authenticationentrypoint[`AuthenticationEntryPoint`].
 In most cases, the `AuthenticationEntryPoint` is an instance of {security-api-url}org/springframework/security/web/authentication/LoginUrlAuthenticationEntryPoint.html[`LoginUrlAuthenticationEntryPoint`].
 In most cases, the `AuthenticationEntryPoint` is an instance of {security-api-url}org/springframework/security/web/authentication/LoginUrlAuthenticationEntryPoint.html[`LoginUrlAuthenticationEntryPoint`].

+ 59 - 9
docs/modules/ROOT/pages/servlet/authorization/architecture.adoc

@@ -23,30 +23,76 @@ String getAuthority();
 ----
 ----
 ====
 ====
 
 
-This method lets an
-`AccessDecisionManager` instance to obtain a precise `String` representation of the `GrantedAuthority`.
-By returning a representation as a `String`, a `GrantedAuthority` can be easily "`read`" by most `AccessDecisionManager` implementations.
-If a `GrantedAuthority` cannot be precisely represented as a `String`, the `GrantedAuthority` is considered "`complex`" and `getAuthority()` must return `null`.
+This method is used by an
+`AuthorizationManager` instance to obtain a precise `String` representation of the `GrantedAuthority`.
+By returning a representation as a `String`, a `GrantedAuthority` can be easily "read" by most `AuthorizationManager` implementations.
+If a `GrantedAuthority` cannot be precisely represented as a `String`, the `GrantedAuthority` is considered "complex" and `getAuthority()` must return `null`.
 
 
-An example of a "`complex`" `GrantedAuthority` would be an implementation that stores a list of operations and authority thresholds that apply to different customer account numbers.
+An example of a complex `GrantedAuthority` would be an implementation that stores a list of operations and authority thresholds that apply to different customer account numbers.
 Representing this complex `GrantedAuthority` as a `String` would be quite difficult. As a result, the `getAuthority()` method should return `null`.
 Representing this complex `GrantedAuthority` as a `String` would be quite difficult. As a result, the `getAuthority()` method should return `null`.
-This indicates to any `AccessDecisionManager` that it needs to support the specific `GrantedAuthority` implementation to understand its contents.
+This indicates to any `AuthorizationManager` that it needs to support the specific `GrantedAuthority` implementation to understand its contents.
 
 
 Spring Security includes one concrete `GrantedAuthority` implementation: `SimpleGrantedAuthority`.
 Spring Security includes one concrete `GrantedAuthority` implementation: `SimpleGrantedAuthority`.
 This implementation lets any user-specified `String` be converted into a `GrantedAuthority`.
 This implementation lets any user-specified `String` be converted into a `GrantedAuthority`.
 All `AuthenticationProvider` instances included with the security architecture use `SimpleGrantedAuthority` to populate the `Authentication` object.
 All `AuthenticationProvider` instances included with the security architecture use `SimpleGrantedAuthority` to populate the `Authentication` object.
 
 
+[[jc-method-security-custom-granted-authority-defaults]]
+By default, role-based authorization rules include `ROLE_` as a prefix.
+This means that if there is an authorization rule that requires a security context to have a role of "USER", Spring Security will by default look for a `GrantedAuthority#getAuthority` that returns "ROLE_USER".
+
+You can customize this with `GrantedAuthorityDefaults`.
+`GrantedAuthorityDefaults` exists to allow customizing the prefix to use for role-based authorization rules.
+
+You can configure the authorization rules to use a different prefix by exposing a `GrantedAuthorityDefaults` bean, like so:
+
+.Custom MethodSecurityExpressionHandler
+====
+.Java
+[source,java,role="primary"]
+----
+@Bean
+static GrantedAuthorityDefaults grantedAuthorityDefaults() {
+	return new GrantedAuthorityDefaults("MYPREFIX_");
+}
+----
+
+.Kotlin
+[source,kotlin,role="secondary"]
+----
+companion object {
+	@Bean
+	fun grantedAuthorityDefaults() : GrantedAuthorityDefaults {
+		return GrantedAuthorityDefaults("MYPREFIX_");
+	}
+}
+----
+
+.Xml
+[source,xml,role="secondary"]
+----
+<bean id="grantedAuthorityDefaults" class="org.springframework.security.config.core.GrantedAuthorityDefaults">
+	<constructor-arg value="MYPREFIX_"/>
+</bean>
+----
+====
+
+[TIP]
+====
+You expose `GrantedAuthorityDefaults` using a `static` method to ensure that Spring publishes it before it initializes Spring Security's method security `@Configuration` classes
+====
+
 [[authz-pre-invocation]]
 [[authz-pre-invocation]]
-== Pre-Invocation Handling
+== Invocation Handling
 Spring Security provides interceptors that control access to secure objects, such as method invocations or web requests.
 Spring Security provides interceptors that control access to secure objects, such as method invocations or web requests.
-A pre-invocation decision on whether the invocation is allowed to proceed is made by the `AccessDecisionManager`.
+A pre-invocation decision on whether the invocation is allowed to proceed is made by `AuthorizationManager` instances.
+Also post-invocation decisions on whether a given value may be returned is made by `AuthorizationManager` instances.
 
 
 === The AuthorizationManager
 === The AuthorizationManager
 `AuthorizationManager` supersedes both <<authz-legacy-note,`AccessDecisionManager` and `AccessDecisionVoter`>>.
 `AuthorizationManager` supersedes both <<authz-legacy-note,`AccessDecisionManager` and `AccessDecisionVoter`>>.
 
 
 Applications that customize an `AccessDecisionManager` or `AccessDecisionVoter` are encouraged to <<authz-voter-adaptation,change to using `AuthorizationManager`>>.
 Applications that customize an `AccessDecisionManager` or `AccessDecisionVoter` are encouraged to <<authz-voter-adaptation,change to using `AuthorizationManager`>>.
 
 
-``AuthorizationManager``s are called by the xref:servlet/authorization/authorize-http-requests.adoc[`AuthorizationFilter`] and are responsible for making final access control decisions.
+``AuthorizationManager``s are called by Spring Security's xref:servlet/authorization/authorize-http-requests.adoc[request-based], xref:servlet/authorization/method-security.adoc[method-based], and xref:servlet/integrations/websocket.adoc[message-based] authorization components and are responsible for making final access control decisions.
 The `AuthorizationManager` interface contains two methods:
 The `AuthorizationManager` interface contains two methods:
 
 
 ====
 ====
@@ -97,6 +143,10 @@ Another manager is the `AuthenticatedAuthorizationManager`.
 It can be used to differentiate between anonymous, fully-authenticated and remember-me authenticated users.
 It can be used to differentiate between anonymous, fully-authenticated and remember-me authenticated users.
 Many sites allow certain limited access under remember-me authentication, but require a user to confirm their identity by logging in for full access.
 Many sites allow certain limited access under remember-me authentication, but require a user to confirm their identity by logging in for full access.
 
 
+[[authz-authorization-managers]]
+==== AuthorizationManagers
+There are also helpful static factories in `AuthenticationManagers` for composing individual ``AuthenticationManager``s into more sophisticated expressions.
+
 [[authz-custom-authorization-manager]]
 [[authz-custom-authorization-manager]]
 ==== Custom Authorization Managers
 ==== Custom Authorization Managers
 Obviously, you can also implement a custom `AuthorizationManager` and you can put just about any access-control logic you want in it.
 Obviously, you can also implement a custom `AuthorizationManager` and you can put just about any access-control logic you want in it.

+ 696 - 199
docs/modules/ROOT/pages/servlet/authorization/authorize-http-requests.adoc

@@ -1,61 +1,172 @@
 [[servlet-authorization-authorizationfilter]]
 [[servlet-authorization-authorizationfilter]]
-= Authorize HttpServletRequests with AuthorizationFilter
+= Authorize HttpServletRequests
 :figures: servlet/authorization
 :figures: servlet/authorization
 
 
-This section builds on xref:servlet/architecture.adoc#servlet-architecture[Servlet Architecture and Implementation] by digging deeper into how xref:servlet/authorization/index.adoc#servlet-authorization[authorization] works within Servlet-based applications.
+Spring Security allows you to xref:servlet/authorization/index.adoc[model your authorization] at the request level.
+For example, with Spring Security you can say that all pages under `/admin` require one authority while all other pages simply require authentication.
 
 
-[NOTE]
-`AuthorizationFilter` supersedes xref:servlet/authorization/authorize-requests.adoc#servlet-authorization-filtersecurityinterceptor[`FilterSecurityInterceptor`].
-To remain backward compatible, `FilterSecurityInterceptor` remains the default.
-This section discusses how `AuthorizationFilter` works and how to override the default configuration.
+By default, Spring Security requires that every request be authenticated.
+That said, any time you use xref:servlet/configuration/java.adoc#jc-httpsecurity[an `HttpSecurity` instance], it's necessary to declare your authorization rules.
 
 
-The {security-api-url}org/springframework/security/web/access/intercept/AuthorizationFilter.html[`AuthorizationFilter`] provides xref:servlet/authorization/index.adoc#servlet-authorization[authorization] for ``HttpServletRequest``s.
-It is inserted into the xref:servlet/architecture.adoc#servlet-filterchainproxy[FilterChainProxy] as one of the xref:servlet/architecture.adoc#servlet-security-filters[Security Filters].
-
-You can override the default when you declare a `SecurityFilterChain`.
-Instead of using xref:servlet/authorization/authorize-http-requests.adoc#servlet-authorize-requests-defaults[`authorizeRequests`], use `authorizeHttpRequests`, like so:
+[[activate-request-security]]
+Whenever you have an `HttpSecurity` instance, you should at least do:
 
 
 .Use authorizeHttpRequests
 .Use authorizeHttpRequests
 ====
 ====
 .Java
 .Java
 [source,java,role="primary"]
 [source,java,role="primary"]
 ----
 ----
-@Bean
-SecurityFilterChain web(HttpSecurity http) throws AuthenticationException {
-    http
-        .authorizeHttpRequests((authorize) -> authorize
-            .anyRequest().authenticated();
-        )
-        // ...
+http
+    .authorizeHttpRequests((authorize) -> authorize
+        .anyRequest().authenticated()
+    )
+----
 
 
-    return http.build();
+.Kotlin
+[source,kotlin,role="secondary"]
+----
+http {
+    authorizeHttpRequests {
+        authorize(anyRequest, authenticated)
+    }
 }
 }
 ----
 ----
+
+.Xml
+[source,xml,role="secondary"]
+----
+<http>
+    <intercept-url pattern="/**" access="authenticated"/>
+</http>
+----
 ====
 ====
 
 
-This improves on `authorizeRequests` in a number of ways:
+This tells Spring Security that any endpoint in your application requires that the security context at a minimum be authenticated in order to allow it.
 
 
-1. Uses the simplified `AuthorizationManager` API instead of metadata sources, config attributes, decision managers, and voters.
-This simplifies reuse and customization.
-2. Delays `Authentication` lookup.
-Instead of the authentication needing to be looked up for every request, it will only look it up in requests where an authorization decision requires authentication.
-3. Bean-based configuration support.
+In many cases, your authorization rules will be more sophisticated than that, so please consider the following use cases:
+
+* I have an app that uses `authorizeRequests` and I want to <<migrate-authorize-requests,migrate it to `authorizeHttpRequests`>>
+* I want to <<request-authorization-architecture,understand how the `AuthorizationFilter` components work>>
+* I want to <<match-requests, match requests>> based on a pattern; specifically <<match-by-regex,regex>>
+* I want to <<authorize-requests, authorize requests>>
+* I want to <<match-by-custom, match a request programmatically>>
+* I want to <<authorize-requests, authorize a request programmatically>>
+* I want to <<remote-authorization-manager, delegate request authorization>> to a policy agent
 
 
-When `authorizeHttpRequests` is used instead of `authorizeRequests`, then {security-api-url}org/springframework/security/web/access/intercept/AuthorizationFilter.html[`AuthorizationFilter`] is used instead of xref:servlet/authorization/authorize-requests.adoc#servlet-authorization-filtersecurityinterceptor[`FilterSecurityInterceptor`].
+[[request-authorization-architecture]]
+== Understanding How Request Authorization Components Work
+
+[NOTE]
+This section builds on xref:servlet/architecture.adoc#servlet-architecture[Servlet Architecture and Implementation] by digging deeper into how xref:servlet/authorization/index.adoc#servlet-authorization[authorization] works at the request level in Servlet-based applications.
 
 
 .Authorize HttpServletRequest
 .Authorize HttpServletRequest
 image::{figures}/authorizationfilter.png[]
 image::{figures}/authorizationfilter.png[]
 
 
-* image:{icondir}/number_1.png[] First, the `AuthorizationFilter` obtains an  xref:servlet/authentication/architecture.adoc#servlet-authentication-authentication[Authentication] from the xref:servlet/authentication/architecture.adoc#servlet-authentication-securitycontextholder[SecurityContextHolder].
-It wraps this in an `Supplier` in order to delay lookup.
+* image:{icondir}/number_1.png[] First, the `AuthorizationFilter` constructs a `Supplier` that retrieves an  xref:servlet/authentication/architecture.adoc#servlet-authentication-authentication[Authentication] from the xref:servlet/authentication/architecture.adoc#servlet-authentication-securitycontextholder[SecurityContextHolder].
 * image:{icondir}/number_2.png[] Second, it passes the `Supplier<Authentication>` and the `HttpServletRequest` to the xref:servlet/architecture.adoc#authz-authorization-manager[`AuthorizationManager`].
 * image:{icondir}/number_2.png[] Second, it passes the `Supplier<Authentication>` and the `HttpServletRequest` to the xref:servlet/architecture.adoc#authz-authorization-manager[`AuthorizationManager`].
-** image:{icondir}/number_3.png[] If authorization is denied, an `AccessDeniedException` is thrown.
+The `AuthorizationManager` matches the request to the patterns in `authorizeHttpRequests`, and runs the corresponding rule.
+** image:{icondir}/number_3.png[] If authorization is denied, xref:servlet/authorization/events.adoc[an `AuthorizationDeniedEvent` is published], and an `AccessDeniedException` is thrown.
 In this case the xref:servlet/architecture.adoc#servlet-exceptiontranslationfilter[`ExceptionTranslationFilter`] handles the `AccessDeniedException`.
 In this case the xref:servlet/architecture.adoc#servlet-exceptiontranslationfilter[`ExceptionTranslationFilter`] handles the `AccessDeniedException`.
-** image:{icondir}/number_4.png[] If access is granted, `AuthorizationFilter` continues with the xref:servlet/architecture.adoc#servlet-filters-review[FilterChain] which allows the application to process normally.
+** image:{icondir}/number_4.png[] If access is granted, xref:servlet/authorization/events.adoc[an `AuthorizationGrantedEvent` is published] and `AuthorizationFilter` continues with the xref:servlet/architecture.adoc#servlet-filters-review[FilterChain] which allows the application to process normally.
 
 
-We can configure Spring Security to have different rules by adding more rules in order of precedence.
+=== `AuthorizationFilter` Is Last By Default
 
 
-.Authorize Requests
+The `AuthorizationFilter` is last in xref:servlet/architecture.adoc#servlet-filterchain-figure[the Spring Security filter chain] by default.
+This means that Spring Security's xref:servlet/authentication/index.adoc[authentication filters], xref:servlet/exploits/index.adoc[exploit protections], and other filter integrations do not require authorization.
+If you add filters of your own before the `AuthorizationFilter`, they will also not require authorization; otherwise, they will.
+
+A place where this typically becomes important is when you are adding {spring-framework-reference-url}web.html#spring-web[Spring MVC] endpoints.
+Because they are executed by the {spring-framework-reference-url}web.html#mvc-servlet[`DispatcherServlet`] and this comes after the `AuthorizationFilter`, you're endpoints need to be <<authorizing-endpoints,included in `authorizeHttpRequests` to be permitted>>.
+
+=== All Dispatches Are Authorized
+
+The `AuthorizationFilter` runs not just on every request, but on every dispatch.
+This means that the `REQUEST` dispatch needs authorization, but also ``FORWARD``s, ``ERROR``s, and ``INCLUDE``s.
+
+For example, {spring-framework-reference-url}web.html#spring-web[Spring MVC] can `FORWARD` the request to a view resolver that renders a Thymeleaf template, like so:
+
+.Sample Forwarding Spring MVC Controller
+====
+.Java
+[source,java,role="primary"]
+----
+@Controller
+public class MyController {
+    @GetMapping("/endpoint")
+    public String endpoint() {
+        return "endpoint";
+    }
+}
+----
+
+.Kotlin
+[source,kotlin,role="secondary"]
+----
+@Controller
+class MyController {
+    @GetMapping("/endpoint")
+    fun endpoint(): String {
+        return "endpoint"
+    }
+}
+----
+====
+
+In this case, authorization happens twice; once for authorizing `/endpoint` and once for forwarding to Thymeleaf to render the "endpoint" template.
+
+For that reason, you may want to <<match-by-dispatcher-type, permit all `FORWARD` dispatches>>.
+
+Another example of this principle is {spring-boot-reference-url}web.html#web.servlet.spring-mvc.error-handling[how Spring Boot handles errors].
+If the container catches an exception, say like the following:
+
+.Sample Erroring Spring MVC Controller
+====
+.Java
+[source,java,role="primary"]
+----
+@Controller
+public class MyController {
+    @GetMapping("/endpoint")
+    public String endpoint() {
+        throw new UnsupportedOperationException("unsupported");
+    }
+}
+----
+
+.Kotlin
+[source,kotlin,role="secondary"]
+----
+@Controller
+class MyController {
+    @GetMapping("/endpoint")
+    fun endpoint(): String {
+        throw UnsupportedOperationException("unsupported")
+    }
+}
+----
+====
+
+then Boot will dispatch it to the `ERROR` dispatch.
+
+In that case, authorization also happens twice; once for authorizing `/endpoint` and once for dispatching the error.
+
+For that reason, you may want to <<match-by-dispatcher-type, permit all `ERROR` dispatches>>.
+
+=== `Authentication` Lookup is Deferred
+
+Remember that xref:servlet/authorization/architecture.adoc#_the_authorizationmanager[the `AuthorizationManager` API uses a `Supplier<Authentication>`].
+
+This matters with `authorizeHttpRequests` when requests are <<authorize-requests,always permitted or always denied>>.
+In those cases, xref:servlet/authentication/architecture.adoc#servlet-authentication-authentication[the `Authentication`] is not queried, making for a faster request.
+
+[[authorizing-endpoints]]
+== Authorizing an Endpoint
+
+You can configure Spring Security to have different rules by adding more rules in order of precedence.
+
+If you want to require that `/endpoint` only be accessible by end users with the `USER` authority, then you can do:
+
+.Authorize an Endpoint
 ====
 ====
 .Java
 .Java
 [source,java,role="primary"]
 [source,java,role="primary"]
@@ -63,225 +174,649 @@ We can configure Spring Security to have different rules by adding more rules in
 @Bean
 @Bean
 SecurityFilterChain web(HttpSecurity http) throws Exception {
 SecurityFilterChain web(HttpSecurity http) throws Exception {
 	http
 	http
-		// ...
-		.authorizeHttpRequests(authorize -> authorize                                  // <1>
-			.requestMatchers("/resources/**", "/signup", "/about").permitAll()         // <2>
-			.requestMatchers("/admin/**").hasRole("ADMIN")                             // <3>
-			.requestMatchers("/db/**").access(new WebExpressionAuthorizationManager("hasRole('ADMIN') and hasRole('DBA')"))   // <4>
-			// .requestMatchers("/db/**").access(AuthorizationManagers.allOf(AuthorityAuthorizationManager.hasRole("ADMIN"), AuthorityAuthorizationManager.hasRole("DBA")))   // <5>
-			.anyRequest().denyAll()                                                // <6>
-		);
+		.authorizeHttpRequests((authorize) -> authorize
+			.requestMatchers("/endpoint").hasAuthority('USER')
+			.anyRequest().authenticated()
+		)
+        // ...
 
 
 	return http.build();
 	return http.build();
 }
 }
 ----
 ----
+
+.Kotlin
+[source,kotlin,role="secondary"]
+----
+@Bean
+SecurityFilterChain web(HttpSecurity http) throws Exception {
+	http {
+        authorizeHttpRequests {
+            authorize("/endpoint", hasAuthority('USER'))
+            authorize(anyRequest, authenticated)
+        }
+	}
+	return http.build();
+}
+----
+
+.Xml
+[source,xml,role="secondary"]
+----
+<http>
+    <intercept-url pattern="/endpoint" access="hasAuthority('USER')"/>
+    <intercept-url pattern="/**" access="authenticated"/>
+</http>
+----
 ====
 ====
-<1> There are multiple authorization rules specified.
-Each rule is considered in the order they were declared.
-<2> We specified multiple URL patterns that any user can access.
-Specifically, any user can access a request if the URL starts with "/resources/", equals "/signup", or equals "/about".
-<3> Any URL that starts with "/admin/" will be restricted to users who have the role "ROLE_ADMIN".
-You will notice that since we are invoking the `hasRole` method we do not need to specify the "ROLE_" prefix.
-<4> Any URL that starts with "/db/" requires the user to have both "ROLE_ADMIN" and "ROLE_DBA".
-You will notice that since we are using the `hasRole` expression we do not need to specify the "ROLE_" prefix.
-<5> The same rule from 4, could be written by combining multiple `AuthorizationManager`.
-<6> Any URL that has not already been matched on is denied access.
-This is a good strategy if you do not want to accidentally forget to update your authorization rules.
 
 
-You can take a bean-based approach by constructing your own xref:servlet/authorization/architecture.adoc#authz-delegate-authorization-manager[`RequestMatcherDelegatingAuthorizationManager`] like so:
+As you can see, the declaration can be broken up in to pattern/rule pairs.
+
+`AuthorizationFilter` processes these pairs in the order listed, applying only the first match to the request.
+This means that even though `/**` would also match for `/endpoint` the above rules are not a problem.
+The way to read the above rules is "if the request is `/endpoint`, then require the `USER` authority; else, only require authentication".
+
+Spring Security supports several patterns and several rules; you can also programmatically create your own of each.
+
+Once authorized, you can test it using xref:servlet/test/method.adoc#test-method-withmockuser[Security's test support] in the following way:
 
 
-.Configure RequestMatcherDelegatingAuthorizationManager
+.Test Endpoint Authorization
 ====
 ====
 .Java
 .Java
 [source,java,role="primary"]
 [source,java,role="primary"]
 ----
 ----
-@Bean
-SecurityFilterChain web(HttpSecurity http, AuthorizationManager<RequestAuthorizationContext> access)
-        throws AuthenticationException {
-    http
-        .authorizeHttpRequests((authorize) -> authorize
-            .anyRequest().access(access)
-        )
-        // ...
+@WithMockUser(authorities="USER")
+@Test
+void endpointWhenUserAuthorityThenAuthorized() {
+    this.mvc.perform(get("/endpoint"))
+        .andExpect(status().isOk());
+}
 
 
-    return http.build();
+@WithMockUser
+@Test
+void endpointWhenNotUserAuthorityThenForbidden() {
+    this.mvc.perform(get("/endpoint"))
+        .andExpect(status().isForbidden());
 }
 }
 
 
-@Bean
-AuthorizationManager<RequestAuthorizationContext> requestMatcherAuthorizationManager(HandlerMappingIntrospector introspector) {
-    MvcRequestMatcher.Builder mvcMatcherBuilder = new MvcRequestMatcher.Builder(introspector);
-    RequestMatcher permitAll =
-            new AndRequestMatcher(
-                    mvcMatcherBuilder.pattern("/resources/**"),
-                    mvcMatcherBuilder.pattern("/signup"),
-                    mvcMatcherBuilder.pattern("/about"));
-    RequestMatcher admin = mvcMatcherBuilder.pattern("/admin/**");
-    RequestMatcher db = mvcMatcherBuilder.pattern("/db/**");
-    RequestMatcher any = AnyRequestMatcher.INSTANCE;
-    AuthorizationManager<HttpServletRequest> manager = RequestMatcherDelegatingAuthorizationManager.builder()
-            .add(permitAll, (context) -> new AuthorizationDecision(true))
-            .add(admin, AuthorityAuthorizationManager.hasRole("ADMIN"))
-            .add(db, AuthorityAuthorizationManager.hasRole("DBA"))
-            .add(any, new AuthenticatedAuthorizationManager())
-            .build();
-    return (context) -> manager.check(context.getRequest());
+@Test
+void anyWhenUnauthenticatedThenUnauthorized() {
+    this.mvc.perform(get("/any"))
+        .andExpect(status().isUnauthorized())
 }
 }
 ----
 ----
 ====
 ====
 
 
-You can also wire xref:servlet/authorization/architecture.adoc#authz-custom-authorization-manager[your own custom authorization managers] for any request matcher.
+[[match-requests]]
+== Matching Requests
+
+Above you've already seen <<authorizing-endpoints, two ways to match requests>>.
+
+The first you saw was the simplest, which is to match any request.
 
 
-Here is an example of mapping a custom authorization manager to the `my/authorized/endpoint`:
+The second is to match by a URI pattern.
+Spring Security supports two languages for URI pattern-matching: <<match-by-ant,Ant>> (as seen above) and <<match-by-regex,Regular Expressions>>.
 
 
-.Custom Authorization Manager
+[[match-by-ant]]
+=== Matching Using Ant
+Ant is the default language that Spring Security uses to match requests.
+
+You can use it to match a single endpoint or a directory, and you can even capture placeholders for later use.
+You can also refine it to match a specific set of HTTP methods.
+
+Let's say that you instead of wanting to match the `/endpoint` endpoint, you want to match all endpoints under the `/resource` directory.
+In that case, you can do something like the following:
+
+.Match with Ant
 ====
 ====
 .Java
 .Java
 [source,java,role="primary"]
 [source,java,role="primary"]
 ----
 ----
-@Bean
-SecurityFilterChain web(HttpSecurity http) throws Exception {
-    http
-        .authorizeHttpRequests((authorize) -> authorize
-            .requestMatchers("/my/authorized/endpoint").access(new CustomAuthorizationManager());
-        )
-        // ...
+http
+    .authorizeHttpRequests((authorize) -> authorize
+        .requestMatchers("/resource/**").hasAuthority("USER")
+        .anyRequest().authenticated()
+    )
+----
 
 
-    return http.build();
+.Kotlin
+[source,kotlin,role="secondary"]
+----
+http {
+    authorizeHttpRequests {
+        authorize("/resource/**", hasAuthority("USER"))
+        authorize(anyRequest, authenticated)
+    }
 }
 }
 ----
 ----
+
+.Xml
+[source,xml,role="secondary"]
+----
+<http>
+    <intercept-url pattern="/resource/**" access="hasAuthority('USER')"/>
+    <intercept-url pattern="/**" access="authenticated"/>
+</http>
+----
 ====
 ====
 
 
-Or you can provide it for all requests as seen below:
+The way to read this is "if the request is `/resource` or some subdirectory, require the `USER` authority; otherwise, only require authentication"
 
 
-.Custom Authorization Manager for All Requests
+You can also extract path values from the request, as seen below:
+
+.Authorize and Extract
 ====
 ====
 .Java
 .Java
 [source,java,role="primary"]
 [source,java,role="primary"]
 ----
 ----
-@Bean
-SecurityFilterChain web(HttpSecurity http) throws Exception {
-    http
-        .authorizeHttpRequests((authorize) -> authorize
-            .anyRequest().access(new CustomAuthorizationManager());
-        )
-        // ...
+http
+    .authorizeHttpRequests((authorize) -> authorize
+        .requestMatchers("/resource/{name}").access(new WebExpressionAuthorizationManager("#name == authentication.name"))
+        .anyRequest().authenticated()
+    )
+----
 
 
-    return http.build();
+.Kotlin
+[source,kotlin,role="secondary"]
+----
+http {
+    authorizeHttpRequests {
+        authorize("/resource/{name}", WebExpressionAuthorizationManager("#name == authentication.name"))
+        authorize(anyRequest, authenticated)
+    }
 }
 }
 ----
 ----
+
+.Xml
+[source,xml,role="secondary"]
+----
+<http>
+    <intercept-url pattern="/resource/{name}" access="#name == authentication.name"/>
+    <intercept-url pattern="/**" access="authenticated"/>
+</http>
+----
 ====
 ====
 
 
-By default, the `AuthorizationFilter` applies to all dispatcher types.
-We can configure Spring Security to not apply the authorization rules to all dispatcher types by using the `shouldFilterAllDispatcherTypes` method:
+Once authorized, you can test it using xref:servlet/test/method.adoc#test-method-withmockuser[Security's test support] in the following way:
 
 
-.Set shouldFilterAllDispatcherTypes to false
+.Test Directory Authorization
 ====
 ====
 .Java
 .Java
 [source,java,role="primary"]
 [source,java,role="primary"]
 ----
 ----
-@Bean
-SecurityFilterChain web(HttpSecurity http) throws Exception {
-    http
-        .authorizeHttpRequests((authorize) -> authorize
-            .shouldFilterAllDispatcherTypes(false)
-            .anyRequest().authenticated()
-        )
-        // ...
+@WithMockUser(authorities="USER")
+@Test
+void endpointWhenUserAuthorityThenAuthorized() {
+    this.mvc.perform(get("/endpoint/jon"))
+        .andExpect(status().isOk());
+}
 
 
-    return http.build();
+@WithMockUser
+@Test
+void endpointWhenNotUserAuthorityThenForbidden() {
+    this.mvc.perform(get("/endpoint/jon"))
+        .andExpect(status().isForbidden());
+}
+
+@Test
+void anyWhenUnauthenticatedThenUnauthorized() {
+    this.mvc.perform(get("/any"))
+        .andExpect(status().isUnauthorized())
 }
 }
 ----
 ----
+====
+
+[NOTE]
+Spring Security only matches paths.
+If you want to match query parameters, you will need a custom request matcher.
+
+[[match-by-regex]]
+=== Matching Using Regular Expressions
+Spring Security supports matching requests against a regular expression.
+This can come in handy if you want to apply more strict matching criteria than `**` on a subdirectory.
+
+For example, consider a path that contains the username and the rule that all usernames must be alphanumeric.
+You can use {security-api-url}org/springframework/security/web/util/matcher/RegexRequestMatcher.html[`RegexRequestMatcher`] to respect this rule, like so:
+
+.Match with Regex
+====
+.Java
+[source,java,role="primary"]
+----
+http
+    .authorizeHttpRequests((authorize) -> authorize
+        .requestMatchers(RegexRequestMatcher.regexMatcher("/resource/[A-Za-z0-9]+")).hasAuthority("USER")
+        .anyRequest().denyAll()
+    )
+----
+
 .Kotlin
 .Kotlin
 [source,kotlin,role="secondary"]
 [source,kotlin,role="secondary"]
 ----
 ----
-@Bean
-open fun web(http: HttpSecurity): SecurityFilterChain {
-    http {
-        authorizeHttpRequests {
-            shouldFilterAllDispatcherTypes = false
-            authorize(anyRequest, authenticated)
-        }
+http {
+    authorizeHttpRequests {
+        authorize(RegexRequestMatcher.regexMatcher("/resource/[A-Za-z0-9]+"), hasAuthority("USER"))
+        authorize(anyRequest, denyAll)
+    }
+}
+----
+
+.Xml
+[source,xml,role="secondary"]
+----
+<http>
+    <intercept-url request-matcher="regex" pattern="/resource/[A-Za-z0-9]+" access="hasAuthority('USER')"/>
+    <intercept-url pattern="/**" access="denyAll"/>
+</http>
+----
+====
+
+[[match-by-httpmethod]]
+=== Matching By Http Method
+
+You can also match rules by HTTP method.
+One place where this is handy is when authorizing by permissions granted, like being granted a `read` or `write` privilege.
+
+To require all ``GET``s to have the `read` permission and all ``POST``s to have the `write` permission, you can do something like this:
+
+.Match by HTTP Method
+====
+.Java
+[source,java,role="primary"]
+----
+http
+    .authorizeHttpRequests((authorize) -> authorize
+        .requestMatchers(HttpMethod.GET).hasAuthority("read")
+        .requestMatchers(HttpMethod.POST).hasAuthority("write")
+        .anyRequest().denyAll()
+    )
+----
+
+.Kotlin
+[source,kotlin,role="secondary"]
+----
+http {
+    authorizeHttpRequests {
+        authorize(HttpMethod.GET, hasAuthority("read"))
+        authorize(HttpMethod.POST, hasAuthority("write"))
+        authorize(anyRequest, denyAll)
+    }
+}
+----
+
+.Xml
+[source,xml,role="secondary"]
+----
+<http>
+    <intercept-url http-method="GET" pattern="/**" access="hasAuthority('read')"/>
+    <intercept-url http-method="POST" pattern="/**" access="hasAuthority('write')"/>
+    <intercept-url pattern="/**" access="denyAll"/>
+</http>
+----
+====
+
+These authorization rules should read as: "if the request is a GET, then require `read` permission; else, if the request is a POST, then require `write` permission; else, deny the request"
+
+[TIP]
+Denying the request by default is a healthy security practice since it turns the set of rules into an allow list.
+
+Once authorized, you can test it using xref:servlet/test/method.adoc#test-method-withmockuser[Security's test support] in the following way:
+
+.Test Http Method Authorization
+====
+.Java
+[source,java,role="primary"]
+----
+@WithMockUser(authorities="read")
+@Test
+void getWhenReadAuthorityThenAuthorized() {
+    this.mvc.perform(get("/any"))
+        .andExpect(status().isOk());
+}
+
+@WithMockUser
+@Test
+void getWhenNoReadAuthorityThenForbidden() {
+    this.mvc.perform(get("/any"))
+        .andExpect(status().isForbidden());
+}
+
+@WithMockUser(authorities="write")
+@Test
+void postWhenWriteAuthorityThenAuthorized() {
+    this.mvc.perform(post("/any").with(csrf()))
+        .andExpect(status().isOk())
+}
+
+@WithMockUser(authorities="read")
+@Test
+void postWhenNoWriteAuthorityThenForbidden() {
+    this.mvc.perform(get("/any").with(csrf()))
+        .andExpect(status().isForbidden());
+}
+----
+====
+
+[[match-by-dispatcher-type]]
+=== Matching By Dispatcher Type
+
+[NOTE]
+This feature is not currently supported in XML
+
+As stated earlier, Spring Security <<_all_dispatches_are_authorized, authorizes all dispatcher types by default>>.
+And even though xref:servlet/authentication/architecture.adoc#servlet-authentication-securitycontext[the security context] established on the `REQUEST` dispatch carries over to subsequent dispatches, subtle mismatches can sometimes cause an unexpected `AccessDeniedException`.
+
+To address that, you can configure Spring Security Java configuration to allow dispatcher types like `FORWARD` and `ERROR`, like so:
+
+.Match by Dispatcher Type
+====
+.Java
+[source,java,role="secondary"]
+----
+http
+    .authorizeHttpRequests((authorize) -> authorize
+        .dispatcherTypeMatchers(DispatcherType.FORWARD, DispatcherType.ERROR).permitAll()
+        .requestMatchers("/endpoint").permitAll()
+        .anyRequest().denyAll()
+    )
+----
+
+.Kotlin
+[source,kotlin,role="secondary"]
+----
+http {
+    authorizeHttpRequests {
+        authorize(DispatcherType.FORWARD, permitAll)
+        authorize(DispatcherType.ERROR, permitAll)
+        authorize("/endpoint", permitAll)
+        authorize(anyRequest, denyAll)
     }
     }
-    return http.build()
 }
 }
 ----
 ----
 ====
 ====
 
 
-Instead of setting `shouldFilterAllDispatcherTypes` to `false`, the recommended approach is to customize authorization on the dispatcher types.
-For example, you may want to grant all access on requests with dispatcher type `ASYNC` or `FORWARD`.
+[[match-by-custom]]
+=== Using a Custom Matcher
+
+[NOTE]
+This feature is not currently supported in XML
 
 
-.Permit ASYNC and FORWARD dispatcher type
+In Java configuration, you can create your own {security-api-url}org/springframework/security/web/util/matcher/RequestMatcher.html[`RequestMatcher`] and supply it to the DSL like so:
+
+.Authorize by Dispatcher Type
+====
+.Java
+[source,java,role="secondary"]
+----
+RequestMatcher printview = (request) -> request.getParameter("print") != null;
+http
+    .authorizeHttpRequests((authorize) -> authorize
+        .requestMatchers(printview).hasAuthority("print")
+        .anyRequest().authenticated()
+    )
+----
+
+.Kotlin
+[source,kotlin,role="secondary"]
+----
+val printview: RequestMatcher = { (request) -> request.getParameter("print") != null }
+http {
+    authorizeHttpRequests {
+        authorize(printview, hasAuthority("print"))
+        authorize(anyRequest, authenticated)
+    }
+}
+----
+====
+
+[TIP]
+Because {security-api-url}org/springframework/security/web/util/matcher/RequestMatcher.html[`RequestMatcher`] is a functional interface, you can supply it as a lambda in the DSL.
+However, if you want to extract values from the request, you will need to have a concrete class since that requires overriding a `default` method.
+
+Once authorized, you can test it using xref:servlet/test/method.adoc#test-method-withmockuser[Security's test support] in the following way:
+
+.Test Custom Authorization
 ====
 ====
 .Java
 .Java
 [source,java,role="primary"]
 [source,java,role="primary"]
 ----
 ----
+@WithMockUser(authorities="print")
+@Test
+void printWhenPrintAuthorityThenAuthorized() {
+    this.mvc.perform(get("/any?print"))
+        .andExpect(status().isOk());
+}
+
+@WithMockUser
+@Test
+void printWhenNoPrintAuthorityThenForbidden() {
+    this.mvc.perform(get("/any?print"))
+        .andExpect(status().isForbidden());
+}
+----
+====
+
+[[authorize-requests]]
+== Authorizing Requests
+
+Once a request is matched, you can authorize it in several ways <<match-requests, already seen>> like `permitAll`, `denyAll`, and `hasAuthority`.
+
+As a quick summary, here are the authorization rules built into the DSL:
+
+* `permitAll` - The request requires no authorization and is a public endpoint; note that in this case, xref:servlet/authentication/architecture.adoc#servlet-authentication-authentication[the `Authentication`] is never retrieved from the session
+* `denyAll` - The request is not allowed under any circumstances; note that in this case, the `Authentication` is never retrieved from the session
+* `hasAuthority` - The request requires that the `Authentication` have xref:servlet/authorization/architecture.adoc#authz-authorities[a `GrantedAuthority`] that matches the given value
+* `hasRole` - A shortcut for `hasAuthority` that prefixes `ROLE_` or whatever is configured as the default prefix
+* `hasAnyAuthority` - The request requires that the `Authentication` have a `GrantedAuthority` that matches any of the given values
+* `hasAnyRole` - A shortcut for `hasAnyAuthority` that prefixes `ROLE_` or whatever is configured as the default prefix
+* `access` - The request uses this custom `AuthorizationManager` to determine access
+
+Having now learned the patterns, rules, and how they can be paired together, you should be able to understand what is going on in this more complex example:
+
+.Authorize Requests
+====
+.Java
+[source,java,role="primary"]
+----
+import static jakarta.servlet.DispatcherType.*;
+
+import static org.springframework.security.authorization.AuthorizationManagers.allOf;
+import static org.springframework.security.authorization.AuthorityAuthorizationManager.hasAuthority;
+import static org.springframework.security.authorization.AuthorityAuthorizationManager.hasRole;
+
 @Bean
 @Bean
 SecurityFilterChain web(HttpSecurity http) throws Exception {
 SecurityFilterChain web(HttpSecurity http) throws Exception {
-    http
-        .authorizeHttpRequests((authorize) -> authorize
-            .dispatcherTypeMatchers(DispatcherType.ASYNC, DispatcherType.FORWARD).permitAll()
-            .anyRequest().authenticated()
-        )
-        // ...
+	http
+		// ...
+		.authorizeHttpRequests(authorize -> authorize                                  // <1>
+            .dispatcherTypeMatchers(FORWARD, ERROR).permitAll() // <2>
+			.requestMatchers("/static/**", "/signup", "/about").permitAll()         // <3>
+			.requestMatchers("/admin/**").hasRole("ADMIN")                             // <4>
+			.requestMatchers("/db/**").access(allOf(hasAuthority('db'), hasRole('ADMIN')))   // <5>
+			.anyRequest().denyAll()                                                // <6>
+		);
 
 
-    return http.build();
+	return http.build();
+}
+----
+====
+<1> There are multiple authorization rules specified.
+Each rule is considered in the order they were declared.
+<2> Dispatches `FORWARD` and `ERROR` are permitted to allow {spring-framework-reference-url}web.html#spring-web[Spring MVC] to render views and Spring Boot to render errors
+<3> We specified multiple URL patterns that any user can access.
+Specifically, any user can access a request if the URL starts with "/resources/", equals "/signup", or equals "/about".
+<4> Any URL that starts with "/admin/" will be restricted to users who have the role "ROLE_ADMIN".
+You will notice that since we are invoking the `hasRole` method we do not need to specify the "ROLE_" prefix.
+<5> Any URL that starts with "/db/" requires the user to have both been granted the "db" permission as well as be a "ROLE_ADMIN".
+You will notice that since we are using the `hasRole` expression we do not need to specify the "ROLE_" prefix.
+<6> Any URL that has not already been matched on is denied access.
+This is a good strategy if you do not want to accidentally forget to update your authorization rules.
+
+[[remote-authorization-manager]]
+=== Use an Authorization Database, Policy Agent, or Other Service
+If you want to configure Spring Security to use a separate service for authorization, you can create your own `AuthorizationManager` and match it to `anyRequest`.
+
+First, your `AuthorizationManager` may look something like this:
+
+.Open Policy Agent Authorization Manager
+====
+.Java
+[source,java,role="primary"]
+----
+@Component
+public final class OpenPolicyAgentAuthorizationManager implements AuthorizationManager<RequestAuthorizationContext> {
+    @Override
+    public AuthorizationDecision check(Supplier<Authentication> authentication, RequestAuthorizationContext context) {
+        // make request to Open Policy Agent
+    }
 }
 }
 ----
 ----
+====
+
+Then, you can wire it into Spring Security in the following way:
+
+.Any Request Goes to Remote Service
+====
+.Java
+[source,java,role="primary"]
+----
+@Bean
+SecurityFilterChain web(HttpSecurity http, AuthorizationManager<RequestAuthorizationContext> authz) throws Exception {
+	http
+		// ...
+		.authorizeHttpRequests((authorize) -> authorize
+            .anyRequest().access(authz)
+		);
+
+	return http.build();
+}
+----
+====
+
+[[favor-permitall]]
+=== Favor `permitAll` over `ignoring`
+When you have static resources it can be tempting to configure the filter chain to ignore these values.
+A more secure approach is to permit them using `permitAll` like so:
+
+.Permit Static Resources
+====
+.Java
+[source,java,role="secondary"]
+----
+http
+    .authorizeHttpRequests((authorize) -> authorize
+        .requestMatchers("/css/**").permitAll()
+        .anyRequest().authenticated()
+    )
+----
+
 .Kotlin
 .Kotlin
 [source,kotlin,role="secondary"]
 [source,kotlin,role="secondary"]
 ----
 ----
-@Bean
-open fun web(http: HttpSecurity): SecurityFilterChain {
-    http {
-        authorizeHttpRequests {
-            authorize(DispatcherTypeRequestMatcher(DispatcherType.ASYNC, DispatcherType.FORWARD), permitAll)
-            authorize(anyRequest, authenticated)
-        }
+http {
+    authorizeHttpRequests {
+        authorize("/css/**", permitAll)
+        authorize(anyRequest, authenticated)
     }
     }
-    return http.build()
 }
 }
 ----
 ----
 ====
 ====
 
 
-You can also customize it to require a specific role for a dispatcher type:
+It's more secure because even with static resources it's important to write secure headers, which Spring Security cannot do if the request is ignored.
+
+In this past, this came with a performance tradeoff since the session was consulted by Spring Security on every request.
+As of Spring Security 6, however, the session is no longer pinged unless required by the authorization rule.
+Because the performance impact is now addressed, Spring Security recommends using at least `permitAll` for all requests.
+
+[[migrate-authorize-requests]]
+== Migrating from `authorizeRequests`
+
+[NOTE]
+`AuthorizationFilter` supersedes {security-api-url}org/springframework/security/web/access/intercept/FilterSecurityInterceptor.html[`FilterSecurityInterceptor`].
+To remain backward compatible, `FilterSecurityInterceptor` remains the default.
+This section discusses how `AuthorizationFilter` works and how to override the default configuration.
+
+The {security-api-url}org/springframework/security/web/access/intercept/AuthorizationFilter.html[`AuthorizationFilter`] provides xref:servlet/authorization/index.adoc#servlet-authorization[authorization] for ``HttpServletRequest``s.
+It is inserted into the xref:servlet/architecture.adoc#servlet-filterchainproxy[FilterChainProxy] as one of the xref:servlet/architecture.adoc#servlet-security-filters[Security Filters].
+
+You can override the default when you declare a `SecurityFilterChain`.
+Instead of using {security-api-url}org/springframework/security/config/annotation/web/builders/HttpSecurity.html#authorizeRequests()[`authorizeRequests`], use `authorizeHttpRequests`, like so:
 
 
-.Require ADMIN for Dispatcher Type ERROR
+.Use authorizeHttpRequests
 ====
 ====
 .Java
 .Java
 [source,java,role="primary"]
 [source,java,role="primary"]
 ----
 ----
 @Bean
 @Bean
-SecurityFilterChain web(HttpSecurity http) throws Exception {
+SecurityFilterChain web(HttpSecurity http) throws AuthenticationException {
     http
     http
         .authorizeHttpRequests((authorize) -> authorize
         .authorizeHttpRequests((authorize) -> authorize
-            .dispatcherTypeMatchers(DispatcherType.ERROR).hasRole("ADMIN")
-            .anyRequest().authenticated()
+            .anyRequest().authenticated();
         )
         )
         // ...
         // ...
 
 
     return http.build();
     return http.build();
 }
 }
 ----
 ----
+====
+
+This improves on `authorizeRequests` in a number of ways:
+
+1. Uses the simplified `AuthorizationManager` API instead of metadata sources, config attributes, decision managers, and voters.
+This simplifies reuse and customization.
+2. Delays `Authentication` lookup.
+Instead of the authentication needing to be looked up for every request, it will only look it up in requests where an authorization decision requires authentication.
+3. Bean-based configuration support.
+
+When `authorizeHttpRequests` is used instead of `authorizeRequests`, then {security-api-url}org/springframework/security/web/access/intercept/AuthorizationFilter.html[`AuthorizationFilter`] is used instead of {security-api-url}org/springframework/security/web/access/intercept/FilterSecurityInterceptor.html[`FilterSecurityInterceptor`].
+
+=== Migrating Expressions
+
+Where possible, it is recommended that you use type-safe authorization managers instead of SpEL.
+For Java configuration, {security-api-url}org/springframework/security/web/access/expression/WebExpressionAuthorizationManager.html[`WebExpressionAuthorizationManager`] is available to help migrate legacy SpEL.
+
+To use `WebExpressionAuthorizationManager`, you can construct one with the expression you are trying to migrate, like so:
+
+====
+.Java
+[source,java,role="primary"]
+----
+.requestMatchers("/test/**").access(new WebExpressionAuthorizationManager("hasRole('ADMIN') && hasRole('USER')"))
+----
+
 .Kotlin
 .Kotlin
 [source,kotlin,role="secondary"]
 [source,kotlin,role="secondary"]
 ----
 ----
-@Bean
-open fun web(http: HttpSecurity): SecurityFilterChain {
-    http {
-        authorizeHttpRequests {
-            authorize(DispatcherTypeRequestMatcher(DispatcherType.ERROR), hasRole("ADMIN"))
-            authorize(anyRequest, authenticated)
-        }
-    }
-    return http.build()
-}
+.requestMatchers("/test/**").access(WebExpressionAuthorizationManager("hasRole('ADMIN') && hasRole('USER')"))
 ----
 ----
 ====
 ====
 
 
-== Request Matchers
+If you are referring to a bean in your expression like so: `@webSecurity.check(authentication, request)`, it's recommended that you instead call the bean directly, which will look something like the following:
 
 
-The `RequestMatcher` interface is used to determine if a request matches a given rule.
-We use `securityMatchers` to determine if a given `HttpSecurity` should be applied to a given request.
+====
+.Java
+[source,java,role="primary"]
+----
+.requestMatchers("/test/**").access((authentication, context) ->
+    new AuthorizationDecision(webSecurity.check(authentication.get(), context.getRequest())))
+----
+
+.Kotlin
+[source,kotlin,role="secondary"]
+----
+.requestMatchers("/test/**").access((authentication, context): AuthorizationManager<RequestAuthorizationContext> ->
+    AuthorizationDecision(webSecurity.check(authentication.get(), context.getRequest())))
+----
+====
+
+For complex instructions that include bean references as well as other expressions, it is recommended that you change those to implement `AuthorizationManager` and refer to them by calling `.access(AuthorizationManager)`.
+
+If you are not able to do that, you can configure a {security-api-url}org/springframework/security/web/access/expression/DefaultHttpSecurityExpressionHandler.html[`DefaultHttpSecurityExpressionHandler`] with a bean resolver and supply that to `WebExpressionAuthorizationManager#setExpressionhandler`.
+
+[[security-matchers]]
+== Security Matchers
+
+The {security-api-url}org/springframework/security/web/util/matcher/RequestMatcher.html[`RequestMatcher`] interface is used to determine if a request matches a given rule.
+We use `securityMatchers` to determine if xref:servlet/configuration/java.adoc#jc-httpsecurity[a given `HttpSecurity`] should be applied to a given request.
 The same way, we can use `requestMatchers` to determine the authorization rules that we should apply to a given request.
 The same way, we can use `requestMatchers` to determine the authorization rules that we should apply to a given request.
 Look at the following example:
 Look at the following example:
 
 
@@ -336,7 +871,7 @@ open class SecurityConfig {
 <3> Allow access to URLs that start with `/admin/` to users with the `ADMIN` role
 <3> Allow access to URLs that start with `/admin/` to users with the `ADMIN` role
 <4> Any other request that doesn't match the rules above, will require authentication
 <4> Any other request that doesn't match the rules above, will require authentication
 
 
-The `securityMatcher(s)` and `requestMatcher(s)` methods will decide which `RequestMatcher` implementation fits best for your application: If Spring MVC is in the classpath, then `MvcRequestMatcher` will be used, otherwise, `AntPathRequestMatcher` will be used.
+The `securityMatcher(s)` and `requestMatcher(s)` methods will decide which `RequestMatcher` implementation fits best for your application: If {spring-framework-reference-url}web.html#spring-web[Spring MVC] is in the classpath, then {security-api-url}org/springframework/security/web/servlet/util/matcher/MvcRequestMatcher.html[`MvcRequestMatcher`] will be used, otherwise, {security-api-url}org/springframework/security/web/servlet/util/matcher/AntPathRequestMatcher.html[`AntPathRequestMatcher`] will be used.
 You can read more about the Spring MVC integration xref:servlet/integrations/mvc.adoc[here].
 You can read more about the Spring MVC integration xref:servlet/integrations/mvc.adoc[here].
 
 
 If you want to use a specific `RequestMatcher`, just pass an implementation to the `securityMatcher` and/or `requestMatcher` methods:
 If you want to use a specific `RequestMatcher`, just pass an implementation to the `securityMatcher` and/or `requestMatcher` methods:
@@ -409,45 +944,7 @@ open class SecurityConfig {
 <4> Allow access to URLs that start with `/admin/` to users with the `ADMIN` role, using `RegexRequestMatcher`
 <4> Allow access to URLs that start with `/admin/` to users with the `ADMIN` role, using `RegexRequestMatcher`
 <5> Allow access to URLs that match the `MyCustomRequestMatcher` to users with the `SUPERVISOR` role, using a custom `RequestMatcher`
 <5> Allow access to URLs that match the `MyCustomRequestMatcher` to users with the `SUPERVISOR` role, using a custom `RequestMatcher`
 
 
-== Expressions
-
-It is recommended that you use type-safe authorization managers instead of SpEL.
-However, `WebExpressionAuthorizationManager` is available to help migrate legacy SpEL.
-
-To use `WebExpressionAuthorizationManager`, you can construct one with the expression you are trying to migrate, like so:
-
-====
-.Java
-[source,java,role="primary"]
-----
-.requestMatchers("/test/**").access(new WebExpressionAuthorizationManager("hasRole('ADMIN') && hasRole('USER')"))
-----
-
-.Kotlin
-[source,kotlin,role="secondary"]
-----
-.requestMatchers("/test/**").access(WebExpressionAuthorizationManager("hasRole('ADMIN') && hasRole('USER')"))
-----
-====
-
-If you are referring to a bean in your expression like so: `@webSecurity.check(authentication, request)`, it's recommended that you instead call the bean directly, which will look something like the following:
-
-====
-.Java
-[source,java,role="primary"]
-----
-.requestMatchers("/test/**").access((authentication, context) ->
-    new AuthorizationDecision(webSecurity.check(authentication.get(), context.getRequest())))
-----
-
-.Kotlin
-[source,kotlin,role="secondary"]
-----
-.requestMatchers("/test/**").access((authentication, context): AuthorizationManager<RequestAuthorizationContext> ->
-    AuthorizationDecision(webSecurity.check(authentication.get(), context.getRequest())))
-----
-====
-
-For complex instructions that include bean references as well as other expressions, it is recommended that you change those to implement `AuthorizationManager` and refer to them by calling `.access(AuthorizationManager)`.
+== Further Reading
 
 
-If you are not able to do that, you can configure a `DefaultHttpSecurityExpressionHandler` with a bean resolver and supply that to `WebExpressionAuthorizationManager#setExpressionhandler`.
+Now that you have secured your application's requests, consider xref:servlet/authorization/method-security.adoc[securing its methods].
+You can also read further on xref:servlet/test/index.adoc[testing your application] or on integrating Spring Security with other aspects of you application like xref:servlet/integrations/data.adoc[the data layer] or xref:servlet/integrations/observability.adoc[tracing and metrics].

+ 0 - 183
docs/modules/ROOT/pages/servlet/authorization/authorize-requests.adoc

@@ -1,183 +0,0 @@
-[[servlet-authorization-filtersecurityinterceptor]]
-= Authorize HttpServletRequest with FilterSecurityInterceptor
-:figures: servlet/authorization
-
-[NOTE]
-====
-`FilterSecurityInterceptor` is in the process of being replaced by xref:servlet/authorization/authorize-http-requests.adoc[`AuthorizationFilter`].
-Consider using that instead.
-====
-
-This section builds on xref:servlet/architecture.adoc#servlet-architecture[Servlet Architecture and Implementation] by digging deeper into how xref:servlet/authorization/index.adoc#servlet-authorization[authorization] works within Servlet-based applications.
-
-The {security-api-url}org/springframework/security/web/access/intercept/FilterSecurityInterceptor.html[`FilterSecurityInterceptor`] provides xref:servlet/authorization/index.adoc#servlet-authorization[authorization] for `HttpServletRequest` instances.
-It is inserted into the xref:servlet/architecture.adoc#servlet-filterchainproxy[FilterChainProxy] as one of the xref:servlet/architecture.adoc#servlet-security-filters[Security Filters].
-
-The following image shows the role of `FilterSecurityInterceptor`:
-
-.Authorize HttpServletRequest
-image::{figures}/filtersecurityinterceptor.png[]
-
-image:{icondir}/number_1.png[] The `FilterSecurityInterceptor` obtains an xref:servlet/authentication/architecture.adoc#servlet-authentication-authentication[Authentication] from the xref:servlet/authentication/architecture.adoc#servlet-authentication-securitycontextholder[SecurityContextHolder].
-image:{icondir}/number_2.png[] `FilterSecurityInterceptor` creates a {security-api-url}org/springframework/security/web/FilterInvocation.html[`FilterInvocation`] from the `HttpServletRequest`, `HttpServletResponse`, and `FilterChain` that are passed into the `FilterSecurityInterceptor`.
-image:{icondir}/number_3.png[] It passes the `FilterInvocation` to `SecurityMetadataSource` to get the ``ConfigAttribute``s.
-image:{icondir}/number_4.png[] It passes the `Authentication`, `FilterInvocation`, and ``ConfigAttribute``s to the `AccessDecisionManager`.
-image:{icondir}/number_5.png[] If authorization is denied, an `AccessDeniedException` is thrown.
-In this case, the xref:servlet/architecture.adoc#servlet-exceptiontranslationfilter[`ExceptionTranslationFilter`] handles the `AccessDeniedException`.
-image:{icondir}/number_6.png[] If access is granted, `FilterSecurityInterceptor` continues with the xref:servlet/architecture.adoc#servlet-filters-review[`FilterChain`], which lets the application process normally.
-
-// configuration (xml/java)
-
-By default, Spring Security's authorization requires all requests to be authenticated.
-The following listing shows the explicit configuration:
-
-[[servlet-authorize-requests-defaults]]
-.Every Request Must be Authenticated
-====
-.Java
-[source,java,role="primary"]
-----
-@Bean
-public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
-	http
-		// ...
-		.authorizeRequests(authorize -> authorize
-			.anyRequest().authenticated()
-		);
-	return http.build();
-}
-----
-
-.XML
-[source,xml,role="secondary"]
-----
-<http>
-	<!-- ... -->
-	<intercept-url pattern="/**" access="authenticated"/>
-</http>
-----
-
-.Kotlin
-[source,kotlin,role="secondary"]
-----
-@Bean
-open fun filterChain(http: HttpSecurity): SecurityFilterChain {
-    http {
-        // ...
-        authorizeRequests {
-            authorize(anyRequest, authenticated)
-        }
-    }
-    return http.build()
-}
-----
-====
-
-We can configure Spring Security to have different rules by adding more rules in order of precedence:
-
-.Authorize Requests
-====
-.Java
-[source,java,role="primary"]
-----
-@Bean
-public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
-	http
-		// ...
-		.authorizeRequests(authorize -> authorize                                  // <1>
-			.requestMatchers("/resources/**", "/signup", "/about").permitAll()         // <2>
-			.requestMatchers("/admin/**").hasRole("ADMIN")                             // <3>
-			.requestMatchers("/db/**").access("hasRole('ADMIN') and hasRole('DBA')")   // <4>
-			.anyRequest().denyAll()                                                // <5>
-		);
-	return http.build();
-}
-----
-
-.XML
-[source,xml,role="secondary"]
-----
-<http> <!--1-->
-	<!-- ... -->
-	<!--2-->
-	<intercept-url pattern="/resources/**" access="permitAll"/>
-	<intercept-url pattern="/signup" access="permitAll"/>
-	<intercept-url pattern="/about" access="permitAll"/>
-
-	<intercept-url pattern="/admin/**" access="hasRole('ADMIN')"/> <!--3-->
-	<intercept-url pattern="/db/**" access="hasRole('ADMIN') and hasRole('DBA')"/> <!--4-->
-	<intercept-url pattern="/**" access="denyAll"/> <!--5-->
-</http>
-----
-
-.Kotlin
-[source,kotlin,role="secondary"]
-----
-@Bean
-open fun filterChain(http: HttpSecurity): SecurityFilterChain {
-   http {
-        authorizeRequests { // <1>
-            authorize("/resources/**", permitAll) // <2>
-            authorize("/signup", permitAll)
-            authorize("/about", permitAll)
-
-            authorize("/admin/**", hasRole("ADMIN")) // <3>
-            authorize("/db/**", "hasRole('ADMIN') and hasRole('DBA')") // <4>
-            authorize(anyRequest, denyAll) // <5>
-        }
-    }
-    return http.build()
-}
-----
-====
-<1> There are multiple authorization rules specified.
-Each rule is considered in the order they were declared.
-<2> We specified multiple URL patterns that any user can access.
-Specifically, any user can access a request if the URL starts with "/resources/", equals "/signup", or equals "/about".
-<3> Any URL that starts with "/admin/" will be restricted to users who have the role "ROLE_ADMIN".
-You will notice that since we are invoking the `hasRole` method we do not need to specify the "ROLE_" prefix.
-<4> Any URL that starts with "/db/" requires the user to have both "ROLE_ADMIN" and "ROLE_DBA".
-You will notice that since we are using the `hasRole` expression we do not need to specify the "ROLE_" prefix.
-<5> Any URL that has not already been matched on is denied access.
-This is a good strategy if you do not want to accidentally forget to update your authorization rules.
-====
-
-
-[[filtersecurityinterceptor-every-request]]
-== Configure FilterSecurityInterceptor with Dispatcher Types
-
-By default, the `FilterSecurityInterceptor` applies to every request.
-This means that if a request is dispatched from a request that was already filtered, the `FilterSecurityInterceptor` will perform the same authorization checks on the dispatched request.
-In some scenarios, you may not want to apply authorization on some dispatcher types:
-
-.Permit ASYNC and ERROR dispatcher types
-====
-.Java
-[source,java,role="primary"]
-----
-@Bean
-SecurityFilterChain web(HttpSecurity http) throws Exception {
-    http
-        .authorizeRequests((authorize) -> authorize
-            .dispatcherTypeMatchers(DispatcherType.ASYNC, DispatcherType.ERROR).permitAll()
-            .anyRequest.authenticated()
-        )
-        // ...
-
-    return http.build();
-}
-----
-.XML
-[source,xml]
-----
-<http auto-config="true">
-    <intercept-url request-matcher-ref="dispatcherTypeMatcher" access="permitAll" />
-    <intercept-url pattern="/**" access="authenticated"/>
-</http>
-
-<b:bean id="dispatcherTypeMatcher" class="org.springframework.security.web.util.matcher.DispatcherTypeRequestMatcher">
-    <b:constructor-arg value="ASYNC"/>
-    <b:constructor-arg value="ERROR"/>
-</b:bean>
-----
-====

+ 4 - 3
docs/modules/ROOT/pages/servlet/authorization/index.adoc

@@ -2,11 +2,12 @@
 = Authorization
 = Authorization
 :page-section-summary-toc: 1
 :page-section-summary-toc: 1
 
 
+Having established xref:servlet/authentication/index.adoc[how users will authenticate], you also need to configure your application's authorization rules.
+
 The advanced authorization capabilities within Spring Security represent one of the most compelling reasons for its popularity.
 The advanced authorization capabilities within Spring Security represent one of the most compelling reasons for its popularity.
 Irrespective of how you choose to authenticate (whether using a Spring Security-provided mechanism and provider or integrating with a container or other non-Spring Security authentication authority), the authorization services can be used within your application in a consistent and simple way.
 Irrespective of how you choose to authenticate (whether using a Spring Security-provided mechanism and provider or integrating with a container or other non-Spring Security authentication authority), the authorization services can be used within your application in a consistent and simple way.
 
 
-In this part, we explore the different `AbstractSecurityInterceptor` implementations, which were introduced in Part I.
-We then move on to explore how to fine-tune authorization through the use of domain access control lists.
-
+You should consider attaching authorization rules to xref:servlet/authorization/authorize-http-requests.adoc[request URIs] and xref:servlet/authorization/method-security.adoc[methods] to begin.
+Below there is also wealth of detail about xref:servlet/authorization/architecture.adoc[how Spring Security authorization works] and how, having established a basic model, it can be fine-tuned.
 
 
 
 

File diff suppressed because it is too large
+ 700 - 216
docs/modules/ROOT/pages/servlet/authorization/method-security.adoc


+ 0 - 143
docs/modules/ROOT/pages/servlet/authorization/secure-objects.adoc

@@ -1,143 +0,0 @@
-
-[[secure-object-impls]]
-= Secure Object Implementations
-
-This section covers how Spring Security handles Secure Object implementations.
-
-[[aop-alliance]]
-== AOP Alliance (MethodInvocation) Security Interceptor
-Prior to Spring Security 2.0, securing `MethodInvocation` instances needed a lot of boiler plate configuration.
-Now the recommended approach for method security is to use xref:servlet/configuration/xml-namespace.adoc#ns-method-security[namespace configuration].
-This way, the method security infrastructure beans are configured automatically for you, so you need not know about the implementation classes.
-We provide only a quick overview of the classes that are involved here.
-
-Method security is enforced by using a `MethodSecurityInterceptor`, which secures `MethodInvocation` instances.
-Depending on the configuration approach, an interceptor may be specific to a single bean or shared between multiple beans.
-The interceptor uses a `MethodSecurityMetadataSource` instance to obtain the configuration attributes that apply to a particular method invocation.
-`MapBasedMethodSecurityMetadataSource` is used to store configuration attributes keyed by method names (which can be wildcarded) and will be used internally when the attributes are defined in the application context using the `<intercept-methods>` or `<protect-point>` elements.
-Other implementations are used to handle annotation-based configuration.
-
-=== Explicit MethodSecurityInterceptor Configuration
-You can configure a `MethodSecurityInterceptor` directly in your application context for use with one of Spring AOP's proxying mechanisms:
-
-====
-[source,xml]
-----
-<bean id="bankManagerSecurity" class=
-	"org.springframework.security.access.intercept.aopalliance.MethodSecurityInterceptor">
-<property name="authenticationManager" ref="authenticationManager"/>
-<property name="accessDecisionManager" ref="accessDecisionManager"/>
-<property name="afterInvocationManager" ref="afterInvocationManager"/>
-<property name="securityMetadataSource">
-	<sec:method-security-metadata-source>
-	<sec:protect method="com.mycompany.BankManager.delete*" access="ROLE_SUPERVISOR"/>
-	<sec:protect method="com.mycompany.BankManager.getBalance" access="ROLE_TELLER,ROLE_SUPERVISOR"/>
-	</sec:method-security-metadata-source>
-</property>
-</bean>
-----
-====
-
-[[aspectj]]
-== AspectJ (JoinPoint) Security Interceptor
-The AspectJ security interceptor is very similar to the AOP Alliance security interceptor discussed in the previous section.
-We discuss only the differences in this section.
-
-The AspectJ interceptor is named `AspectJSecurityInterceptor`.
-Unlike the AOP Alliance security interceptor, which relies on the Spring application context to weave in the security interceptor through proxying, the `AspectJSecurityInterceptor` is woven in through the AspectJ compiler.
-It would not be uncommon to use both types of security interceptors in the same application, with `AspectJSecurityInterceptor` being used for domain object instance security and the AOP Alliance `MethodSecurityInterceptor` being used for services layer security.
-
-We first consider how the `AspectJSecurityInterceptor` is configured in the Spring application context:
-
-====
-[source,xml]
-----
-<bean id="bankManagerSecurity" class=
-	"org.springframework.security.access.intercept.aspectj.AspectJMethodSecurityInterceptor">
-<property name="authenticationManager" ref="authenticationManager"/>
-<property name="accessDecisionManager" ref="accessDecisionManager"/>
-<property name="afterInvocationManager" ref="afterInvocationManager"/>
-<property name="securityMetadataSource">
-	<sec:method-security-metadata-source>
-	<sec:protect method="com.mycompany.BankManager.delete*" access="ROLE_SUPERVISOR"/>
-	<sec:protect method="com.mycompany.BankManager.getBalance" access="ROLE_TELLER,ROLE_SUPERVISOR"/>
-	</sec:method-security-metadata-source>
-</property>
-</bean>
-----
-====
-
-The two interceptors can share the same `securityMetadataSource`, as the `SecurityMetadataSource` works with `java.lang.reflect.Method` instances rather than an AOP library-specific class.
-Your access decisions have access to the relevant AOP library-specific invocation (`MethodInvocation` or `JoinPoint`) and can consider a range of additional criteria (such as method arguments) when making access decisions.
-
-Next, you need to define an AspectJ `aspect`, as the following example shows:
-
-====
-[source,java]
-----
-
-package org.springframework.security.samples.aspectj;
-
-import org.springframework.security.access.intercept.aspectj.AspectJSecurityInterceptor;
-import org.springframework.security.access.intercept.aspectj.AspectJCallback;
-import org.springframework.beans.factory.InitializingBean;
-
-public aspect DomainObjectInstanceSecurityAspect implements InitializingBean {
-
-	private AspectJSecurityInterceptor securityInterceptor;
-
-	pointcut domainObjectInstanceExecution(): target(PersistableEntity)
-		&& execution(public * *(..)) && !within(DomainObjectInstanceSecurityAspect);
-
-	Object around(): domainObjectInstanceExecution() {
-		if (this.securityInterceptor == null) {
-			return proceed();
-		}
-
-		AspectJCallback callback = new AspectJCallback() {
-			public Object proceedWithObject() {
-				return proceed();
-			}
-		};
-
-		return this.securityInterceptor.invoke(thisJoinPoint, callback);
-	}
-
-	public AspectJSecurityInterceptor getSecurityInterceptor() {
-		return securityInterceptor;
-	}
-
-	public void setSecurityInterceptor(AspectJSecurityInterceptor securityInterceptor) {
-		this.securityInterceptor = securityInterceptor;
-	}
-
-	public void afterPropertiesSet() throws Exception {
-		if (this.securityInterceptor == null)
-			throw new IllegalArgumentException("securityInterceptor required");
-		}
-	}
-}
-----
-====
-
-
-In the preceding example, the security interceptor is applied to every instance of `PersistableEntity`, which is an abstract class not shown (you can use any other class or `pointcut` expression you like).
-For those curious, `AspectJCallback` is needed because the `proceed();` statement has special meaning only within an `around()` body.
-The `AspectJSecurityInterceptor` calls this anonymous `AspectJCallback` class when it wants the target object to continue.
-
-You need to configure Spring to load the aspect and wire it with the `AspectJSecurityInterceptor`.
-The following example shows a bean declaration that achieves this:
-
-====
-[source,xml]
-----
-
-<bean id="domainObjectInstanceSecurityAspect"
-	class="security.samples.aspectj.DomainObjectInstanceSecurityAspect"
-	factory-method="aspectOf">
-<property name="securityInterceptor" ref="bankManagerSecurity"/>
-</bean>
-----
-====
-
-Now you can create your beans from anywhere within your application, using whatever means you think fit (e.g. `new Person();`), and they have the security interceptor applied.

+ 1 - 1
docs/modules/ROOT/pages/servlet/oauth2/resource-server/index.adoc

@@ -27,7 +27,7 @@ The figure above builds off our xref:servlet/architecture.adoc#servlet-securityf
 
 
 image:{icondir}/number_1.png[] First, a user makes an unauthenticated request to the `/private` resource for which the user is not authorized.
 image:{icondir}/number_1.png[] First, a user makes an unauthenticated request to the `/private` resource for which the user is not authorized.
 
 
-image:{icondir}/number_2.png[] Spring Security's xref:servlet/authorization/authorize-requests.adoc#servlet-authorization-filtersecurityinterceptor[`FilterSecurityInterceptor`] indicates that the unauthenticated request is _Denied_ by throwing an `AccessDeniedException`.
+image:{icondir}/number_2.png[] Spring Security's xref:servlet/authorization/authorize-http-requests.adoc[`AuthorizationFilter`] indicates that the unauthenticated request is _Denied_ by throwing an `AccessDeniedException`.
 
 
 image:{icondir}/number_3.png[] Since the user is not authenticated, xref:servlet/architecture.adoc#servlet-exceptiontranslationfilter[`ExceptionTranslationFilter`] initiates _Start Authentication_.
 image:{icondir}/number_3.png[] Since the user is not authenticated, xref:servlet/architecture.adoc#servlet-exceptiontranslationfilter[`ExceptionTranslationFilter`] initiates _Start Authentication_.
 The configured xref:servlet/authentication/architecture.adoc#servlet-authentication-authenticationentrypoint[`AuthenticationEntryPoint`] is an instance of {security-api-url}org/springframework/security/oauth2/server/resource/authentication/BearerTokenAuthenticationEntryPoint.html[`BearerTokenAuthenticationEntryPoint`], which sends a `WWW-Authenticate` header.
 The configured xref:servlet/authentication/architecture.adoc#servlet-authentication-authenticationentrypoint[`AuthenticationEntryPoint`] is an instance of {security-api-url}org/springframework/security/oauth2/server/resource/authentication/BearerTokenAuthenticationEntryPoint.html[`BearerTokenAuthenticationEntryPoint`], which sends a `WWW-Authenticate` header.

+ 1 - 1
docs/modules/ROOT/pages/servlet/saml2/login/overview.adoc

@@ -16,7 +16,7 @@ The figure above builds off our xref:servlet/architecture.adoc#servlet-securityf
 
 
 image:{icondir}/number_1.png[] First, a user makes an unauthenticated request to the `/private` resource, for which it is not authorized.
 image:{icondir}/number_1.png[] First, a user makes an unauthenticated request to the `/private` resource, for which it is not authorized.
 
 
-image:{icondir}/number_2.png[] Spring Security's xref:servlet/authorization/authorize-requests.adoc#servlet-authorization-filtersecurityinterceptor[`FilterSecurityInterceptor`] indicates that the unauthenticated request is _Denied_ by throwing an `AccessDeniedException`.
+image:{icondir}/number_2.png[] Spring Security's xref:servlet/authorization/authorize-http-requests.adoc[`AuthorizationFilter`] indicates that the unauthenticated request is _Denied_ by throwing an `AccessDeniedException`.
 
 
 image:{icondir}/number_3.png[] Since the user lacks authorization, the xref:servlet/architecture.adoc#servlet-exceptiontranslationfilter[`ExceptionTranslationFilter`] initiates _Start Authentication_.
 image:{icondir}/number_3.png[] Since the user lacks authorization, the xref:servlet/architecture.adoc#servlet-exceptiontranslationfilter[`ExceptionTranslationFilter`] initiates _Start Authentication_.
 The configured xref:servlet/authentication/architecture.adoc#servlet-authentication-authenticationentrypoint[`AuthenticationEntryPoint`] is an instance of {security-api-url}org/springframework/security/web/authentication/LoginUrlAuthenticationEntryPoint.html[`LoginUrlAuthenticationEntryPoint`], which redirects to <<servlet-saml2login-sp-initiated-factory,the `<saml2:AuthnRequest>` generating endpoint>>, `Saml2WebSsoAuthenticationRequestFilter`.
 The configured xref:servlet/authentication/architecture.adoc#servlet-authentication-authenticationentrypoint[`AuthenticationEntryPoint`] is an instance of {security-api-url}org/springframework/security/web/authentication/LoginUrlAuthenticationEntryPoint.html[`LoginUrlAuthenticationEntryPoint`], which redirects to <<servlet-saml2login-sp-initiated-factory,the `<saml2:AuthnRequest>` generating endpoint>>, `Saml2WebSsoAuthenticationRequestFilter`.

Some files were not shown because too many files changed in this diff