mirror of
https://github.com/spring-projects/spring-security.git
synced 2025-06-26 05:42:31 +00:00
Deprecate SecurityMetadataSource
- Updated FAQ to replace SecurityMetadataSource recommendation with AuthorizationManager Issue gh-16772
This commit is contained in:
parent
8e9634d25c
commit
bb438578cb
@ -519,12 +519,8 @@ A security-conscious organization should be aware that the benefits of their dil
|
||||
If you have taken this into account (perhaps by using multiple layers of security within your application), Spring Security lets you fully customize the source of security metadata.
|
||||
You can make it fully dynamic if you choose.
|
||||
|
||||
Both method and web security are protected by subclasses of `AbstractSecurityInterceptor`, which is configured with a `SecurityMetadataSource` from which it obtains the metadata for a particular method or filter invocation.
|
||||
For web security, the interceptor class is `FilterSecurityInterceptor`, and it uses the `FilterInvocationSecurityMetadataSource` marker interface. The "`secured object`" type it operates on is a `FilterInvocation`. The default implementation (which is used both in the namespace `<http>` and when configuring the interceptor explicitly) stores the list of URL patterns and their corresponding list of "`configuration attributes`" (instances of `ConfigAttribute`) in an in-memory map.
|
||||
|
||||
To load the data from an alternative source, you must use an explicitly declared security filter chain (typically Spring Security's `FilterChainProxy`) to customize the `FilterSecurityInterceptor` bean.
|
||||
You cannot use the namespace.
|
||||
You would then implement `FilterInvocationSecurityMetadataSource` to load the data as you please for a particular `FilterInvocation`. The `FilterInvocation` object contains the `HttpServletRequest`, so you can obtain the URL or any other relevant information on which to base your decision, based on what the list of returned attributes contains. A basic outline would look something like the following example:
|
||||
Both method and web security are protected by implementations of `AuthorizationManager`.
|
||||
For web security, you can supply your own implementation of `AuthorizationManager<RequestAuthorizationContext>` and supply it to the filter chain DSL like so:
|
||||
|
||||
[tabs]
|
||||
======
|
||||
@ -532,59 +528,99 @@ Java::
|
||||
+
|
||||
[source,java,role="primary"]
|
||||
----
|
||||
@Component
|
||||
public class DynamicAuthorizationManager implements AuthorizationManager<RequestAuthorizationContext> {
|
||||
private final MyExternalAuthorizationService authz;
|
||||
|
||||
public class MyFilterSecurityMetadataSource implements FilterInvocationSecurityMetadataSource {
|
||||
// ...
|
||||
|
||||
public List<ConfigAttribute> getAttributes(Object object) {
|
||||
FilterInvocation fi = (FilterInvocation) object;
|
||||
String url = fi.getRequestUrl();
|
||||
String httpMethod = fi.getRequest().getMethod();
|
||||
List<ConfigAttribute> attributes = new ArrayList<ConfigAttribute>();
|
||||
@Override
|
||||
public AuthorizationDecision check(Supplier<Authentication> authentication, RequestAuthorizationContext context) {
|
||||
// query the external service
|
||||
}
|
||||
}
|
||||
|
||||
// Lookup your database (or other source) using this information and populate the
|
||||
// list of attributes
|
||||
|
||||
return attributes;
|
||||
}
|
||||
|
||||
public Collection<ConfigAttribute> getAllConfigAttributes() {
|
||||
return null;
|
||||
}
|
||||
|
||||
public boolean supports(Class<?> clazz) {
|
||||
return FilterInvocation.class.isAssignableFrom(clazz);
|
||||
}
|
||||
}
|
||||
// ...
|
||||
|
||||
http
|
||||
.authorizeHttpRequests((authorize) -> authorize.anyRequest().access(dynamicAuthorizationManager))
|
||||
----
|
||||
|
||||
Kotlin::
|
||||
+
|
||||
[source,kotlin,role="secondary"]
|
||||
----
|
||||
class MyFilterSecurityMetadataSource : FilterInvocationSecurityMetadataSource {
|
||||
override fun getAttributes(securedObject: Any): List<ConfigAttribute> {
|
||||
val fi = securedObject as FilterInvocation
|
||||
val url = fi.requestUrl
|
||||
val httpMethod = fi.request.method
|
||||
@Component
|
||||
class DynamicAuthorizationManager : AuthorizationManager<RequestAuthorizationContext?> {
|
||||
private val rules: MyAuthorizationRulesRepository? = null
|
||||
|
||||
// Lookup your database (or other source) using this information and populate the
|
||||
// list of attributes
|
||||
return ArrayList()
|
||||
// ...
|
||||
|
||||
override fun check(authentication: Supplier<Authentication?>?, context: RequestAuthorizationContext?): AuthorizationDecision {
|
||||
// look up rules from the database
|
||||
}
|
||||
}
|
||||
|
||||
override fun getAllConfigAttributes(): Collection<ConfigAttribute>? {
|
||||
return null
|
||||
}
|
||||
// ...
|
||||
|
||||
override fun supports(clazz: Class<*>): Boolean {
|
||||
return FilterInvocation::class.java.isAssignableFrom(clazz)
|
||||
http {
|
||||
authorizeHttpRequests {
|
||||
authorize(anyRequest, dynamicAuthorizationManager)
|
||||
}
|
||||
}
|
||||
----
|
||||
======
|
||||
|
||||
For more information, look at the code for `DefaultFilterInvocationSecurityMetadataSource`.
|
||||
For method security, you can supply your own implementation of `AuthorizationManager<MethodInvocation>` and supply it to Spring AOP like so:
|
||||
|
||||
[tabs]
|
||||
======
|
||||
Java::
|
||||
+
|
||||
[source,java,role="primary"]
|
||||
----
|
||||
@Component
|
||||
public class DynamicAuthorizationManager implements AuthorizationManager<MethodInvocation> {
|
||||
private final MyExternalAuthorizationService authz;
|
||||
|
||||
// ...
|
||||
|
||||
@Override
|
||||
public AuthorizationDecision check(Supplier<Authentication> authentication, MethodInvocation invocation) {
|
||||
// query the external service
|
||||
}
|
||||
}
|
||||
|
||||
// ...
|
||||
|
||||
@Bean
|
||||
static Advisor securedAuthorizationAdvisor(DynamicAuthorizationManager dynamicAuthorizationManager) {
|
||||
return AuthorizationManagerBeforeMethodInterceptor.secured(dynamicAuthorizationManager)
|
||||
}
|
||||
----
|
||||
|
||||
Kotlin::
|
||||
+
|
||||
[source,kotlin,role="secondary"]
|
||||
----
|
||||
@Component
|
||||
class DynamicAuthorizationManager : AuthorizationManager<MethodInvocation?> {
|
||||
private val authz: MyExternalAuthorizationService? = null
|
||||
|
||||
// ...
|
||||
override fun check(authentication: Supplier<Authentication?>?, invocation: MethodInvocation?): AuthorizationDecision {
|
||||
// query the external service
|
||||
}
|
||||
}
|
||||
|
||||
companion object {
|
||||
@Bean
|
||||
fun securedAuthorizationAdvisor(dynamicAuthorizationManager: DynamicAuthorizationManager): Advisor {
|
||||
return AuthorizationManagerBeforeMethodInterceptor.preAuthorize(dynamicAuthorizationManager)
|
||||
}
|
||||
}
|
||||
----
|
||||
======
|
||||
|
||||
|
||||
[[appendix-faq-ldap-authorities]]
|
||||
|
Loading…
x
Reference in New Issue
Block a user