We should add an AuthorizationManager which is an imperative version of ReactiveAuthorizationManager. The class should look something like:
public interface AuthorizationManager<T> {
AuthorizationDecision check(Supplier<Authentication> authentication, T object);
default void verify(Supplier<Authentication> authentication, T object) {
AuthorizationDecision decision = check(authentication, object);
if (!decision.isGranted()) {
throw new AccessDeniedException("Access Denied");
}
}
}
Using something that allows delaying looking up the Authentication like Supplier<Authentication> vs an Authentication directly.
We should also add support for AuthorizationManager in HttpSecurity.authorizeRequests().
Finally, we should change around the existing classes that use AccessDecisionManager should migrate to AuthorizationManager and AccessDecisionManager should be marked as deprecated.
Comment From: evgeniycheban
@rwinch I would like to work on this.
Comment From: jzheaux
It's yours, @evgeniycheban
Comment From: evgeniycheban
@jzheaux I created a very draft PR.
Please take a look when you have a moment. Am I moving in the right direction?
Comment From: evgeniycheban
Thanks for the review @jzheaux
@rwinch @jzheaux I have a few questions.
1. Should we implement an AuthorizationManager for Method Security within this task?
2. By default, HttpSecurity.authorizeRequests() uses ExpressionUrlAuthorizationConfigurer, should we add an AuthorizationManager that supports SpEL expressions?
I've currently added support for AuthorizationManager to UrlAuthorizationConfigurer in the c006f21
Comment From: jzheaux
Good questions, @evgeniycheban.
- Should we implement an AuthorizationManager for Method Security within this task?
One of the goals of this ticket is to deprecate AccessDecisionManager. Given that, we should see if we can eliminate any internal use of it and deprecate any public use.
Ideally, then, AbstractSecurityInterceptor would stop referring to the AccessDecisionManager interface in favor of AuthorizationManager.
Since the public API allows an application to configure an AccessDecisionManager, an AuthorizationManager implementation that adapts to an AccessDecisionManager may be helpful.
One of the tricky parts here seems to be how to deal with the SecurityMetadataSource and its associated ConfigAttributes. Since ConfigAttribute isn't part of AuthorizationManager's contract, this adapter might need to have a SecurityMetadataSource. I also wonder what effect this should have on the events that are fired since some of them depend on knowing the list of ConfigAttributes. What do you think, @rwinch?
- By default, HttpSecurity.authorizeRequests() uses ExpressionUrlAuthorizationConfigurer, should we add an AuthorizationManager that supports SpEL expressions?
Yes, I think that makes sense, though I think it should be internal to that class.
Comment From: evgeniycheban
@jzheaux I've implemented an adapter, but we need to check that an AccessDecisionManager supports a ConfigAttribute in AbstractSecurityInterceptor.validateAttributeDefs. Is this validation still needed?
The adapter code is shown below.
AuthorizationManagerAdapter
public class AuthorizationManagerAdapter<T> implements AuthorizationManager<T> {
private final AccessDecisionManager accessDecisionManager;
private final SecurityMetadataSource metadataSource;
public AuthorizationManagerAdapter(AccessDecisionManager accessDecisionManager,
SecurityMetadataSource metadataSource) {
this.accessDecisionManager = accessDecisionManager;
this.metadataSource = metadataSource;
}
@Override
public AuthorizationDecision check(Supplier<Authentication> authentication, T object) {
Collection<ConfigAttribute> attributes = this.metadataSource.getAttributes(object);
try {
this.accessDecisionManager.decide(authentication.get(), object, attributes);
}
catch (AccessDeniedException e) {
return new AuthorizationDecision(false);
}
return new AuthorizationDecision(true);
}
}
Comment From: evgeniycheban
@jzheaux I've updated the PR, please take a look.
Comment From: winer77444
I added it at the gateway ,However, you can only enter the check method when adding the authentication header,If it is not added, the null pointer exception will be reported if it is forwarded to the corresponding service through the gateway. What's the matter