1
0
mirror of synced 2026-08-04 01:07:02 +00:00

Add AuthorizationManagerFactory

Signed-off-by: Steve Riesenberg <5248162+sjohnr@users.noreply.github.com>
This commit is contained in:
Steve Riesenberg
2025-09-02 12:47:53 -05:00
committed by Rob Winch
parent a4f813ab29
commit eeb4574bb3
37 changed files with 2719 additions and 178 deletions
@@ -144,6 +144,43 @@ Another manager is the `AuthenticatedAuthorizationManager`.
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.
[[authz-authorization-manager-factory]]
=== Creating AuthorizationManager instances
The javadoc:org.springframework.security.authorization.AuthorizationManagerFactory[] interface (introduced in Spring Security 7.0) is used to create generic ``AuthorizationManager``s in xref:servlet/authorization/authorize-http-requests.adoc[request-based] and xref:servlet/authorization/method-security.adoc[method-based] authorization components.
The following is a sketch of the `AuthorizationManagerFactory` interface:
[source,java]
----
public interface AuthorizationManagerFactory<T> {
AuthorizationManager<T> permitAll();
AuthorizationManager<T> denyAll();
AuthorizationManager<T> hasRole(String role);
AuthorizationManager<T> hasAnyRole(String... roles);
AuthorizationManager<T> hasAuthority(String authority);
AuthorizationManager<T> hasAnyAuthority(String... authorities);
AuthorizationManager<T> authenticated();
AuthorizationManager<T> fullyAuthenticated();
AuthorizationManager<T> rememberMe();
AuthorizationManager<T> anonymous();
}
----
The default implementation is javadoc:org.springframework.security.authorization.DefaultAuthorizationManagerFactory[], which allows for customizing the `rolePrefix` (defaults to `"ROLE_"`), `RoleHierarchy` and `AuthenticationTrustManager` that are provided to the ``AuthorizationManager``s created by the factory.
In order to customize the default instance used by Spring Security, simply publish a bean as in the following example:
include-code::./AuthorizationManagerFactoryConfiguration[tag=config,indent=0]
[TIP]
It is also possible to target a specific usage of this factory within Spring Security by providing a concrete parameterized type instead of a generic type.
See examples of each in the xref:servlet/authorization/authorize-http-requests.adoc#customizing-authorization-managers[request-based] and xref:servlet/authorization/method-security.adoc#customizing-authorization-managers[method-based] sections of the documentation.
In addition to simply customizing the default instance of `AuthorizationManagerFactory`, you can provide your own implementation to fully customize the instances created by the factory and provide your own implementations.
[NOTE]
The {gh-url}/core/src/main/java/org/springframework/security/authorization/AuthorizationManagerFactory.java[actual interface] provides default implementations for all factory methods, which allows custom implementations to only implement the methods that need to be customized.
[[authz-authorization-managers]]
==== AuthorizationManagers
There are also helpful static factories in javadoc:org.springframework.security.authorization.AuthorizationManagers[] for composing individual ``AuthorizationManager``s into more sophisticated expressions.
@@ -57,6 +57,7 @@ In many cases, your authorization rules will be more sophisticated than that, so
* 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
* I want to <<customizing-authorization-managers,customize how authorization managers are created>>
[[request-authorization-architecture]]
== Understanding How Request Authorization Components Work
@@ -765,6 +766,24 @@ You will notice that since we are using the `hasRole` expression we do not need
<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.
[[customizing-authorization-managers]]
== Customizing Authorization Managers
When you use the `authorizeHttpRequests` DSL, Spring Security takes care of creating the appropriate `AuthorizationManager` instances for you.
In certain cases, you may want to customize what is created in order to have complete control over how authorization decisions are made xref:servlet/authorization/architecture.adoc#authz-delegate-authorization-manager[at the framework level].
In order to take control of creating instances of `AuthorizationManager` for authorizing HTTP requests, you can create a custom xref:servlet/authorization/architecture.adoc#authz-authorization-manager-factory[`AuthorizationManagerFactory`].
For example, let's say you want to create a convention that authenticated users must be authenticated _AND_ have the `USER` role.
To do this, you can create a custom implementation for HTTP requests as in the following example:
include-code::./CustomHttpRequestsAuthorizationManagerFactory[tag=class,indent=0]
Now, whenever you <<activate-request-security,require authentication>>, Spring Security will automatically invoke your custom factory to create an instance of `AuthorizationManager` that requires authentication _AND_ the `USER` role.
[TIP]
We use this as a simple example of creating a custom `AuthorizationManagerFactory`, though it is also possible (and often simpler) to replace a specific `AuthorizationManager` only for a particular request.
See <<remote-authorization-manager>> for an example.
[[authorization-expressions]]
== Expressing Authorization with SpEL
@@ -1995,6 +1995,24 @@ This works on both classes and interfaces.
This does not work for interfaces, since they do not have debug information about the parameter names.
For interfaces, either annotations or the `-parameters` approach must be used.
[[customizing-authorization-managers]]
== Customizing Authorization Managers
When you use SpEL expressions with <<use-preauthorize,`@PreAuthorize`>>, <<use-postauthorize,`@PostAuthorize`>>, <<use-prefilter,`@PreFilter`>> and <<use-postfilter,`@PostFilter`>>, Spring Security takes care of creating the appropriate `AuthorizationManager` instances for you.
In certain cases, you may want to customize what is created in order to have complete control over how authorization decisions are made xref:servlet/authorization/architecture.adoc#authz-delegate-authorization-manager[at the framework level].
In order to take control of creating instances of `AuthorizationManager` for pre- and post-annotations, you can create a custom xref:servlet/authorization/architecture.adoc#authz-authorization-manager-factory[`AuthorizationManagerFactory`].
For example, let's say you want to allow users with the `ADMIN` role whenever any other role is required.
To do this, you can create a custom implementation for method security as in the following example:
include-code::./CustomMethodInvocationAuthorizationManagerFactory[tag=class,indent=0]
Now, whenever you <<use-preauthorize,use the `@PreAuthorize` annotation>> with `hasRole` or `hasAnyRole`, Spring Security will automatically invoke your custom factory to create an instance of `AuthorizationManager` that allows access for the given role(s) _OR_ the `ADMIN` role.
[TIP]
We use this as a simple example of creating a custom `AuthorizationManagerFactory`, though the same outcome could be accomplished with <<favor-granting-authorities,a role hierarchy>>.
Use whichever approach fits best in your situation.
[[authorize-object]]
== Authorizing Arbitrary Objects
+1
View File
@@ -12,6 +12,7 @@ Each section that follows will indicate the more notable removals as well as the
== Core
* Removed `AuthorizationManager#check` in favor of `AuthorizationManager#authorize`
* Added xref:servlet/authorization/architecture.adoc#authz-authorization-manager-factory[`AuthorizationManagerFactory`] for creating `AuthorizationManager` instances in xref:servlet/authorization/authorize-http-requests.adoc#customizing-authorization-managers[request-based] and xref:servlet/authorization/method-security.adoc#customizing-authorization-managers[method-based] authorization components
== Config