Skip to content

Add AuthorizationManager #8996

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Dec 16, 2020
Merged

Conversation

evgeniycheban
Copy link
Contributor

@evgeniycheban evgeniycheban commented Sep 7, 2020

Closes gh-8900

@evgeniycheban evgeniycheban marked this pull request as draft September 7, 2020 01:36
@spring-projects-issues spring-projects-issues added the status: waiting-for-triage An issue we've not yet triaged label Sep 7, 2020
@evgeniycheban evgeniycheban force-pushed the gh-8900 branch 3 times, most recently from 0030029 to 3011ece Compare September 8, 2020 11:19
Copy link
Contributor

@jzheaux jzheaux left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks, @evgeniycheban, this is going in the right direction. I've left a couple of comments inline.

@evgeniycheban evgeniycheban force-pushed the gh-8900 branch 4 times, most recently from 2275b04 to c006f21 Compare September 14, 2020 19:19
@evgeniycheban evgeniycheban force-pushed the gh-8900 branch 11 times, most recently from 036bff5 to 5ae5b68 Compare October 5, 2020 15:39
@evgeniycheban evgeniycheban marked this pull request as ready for review October 5, 2020 15:40
@evgeniycheban evgeniycheban requested a review from jzheaux October 5, 2020 16:44
@evgeniycheban evgeniycheban force-pushed the gh-8900 branch 5 times, most recently from 3528c21 to b4ad09b Compare October 6, 2020 02:06
Copy link
Contributor

@jzheaux jzheaux left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Great progress, @evgeniycheban, it's nice to see this starting to take shape. I've left some additional feedback inline.

@@ -115,6 +118,8 @@

private AccessDecisionManager accessDecisionManager;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's remove this reference once it's not used anymore.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It might make sense to consider introducing a new filter that will use an AuthorizationManager similar to AuthorizationWebFilter.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agreed that it's worth considering. It doesn't change the fact that AbstractSecurityInterceptor needs to stop using AccessDecisionManager, but it would probably be worth it to file a ticket and start that conversation.

*/
public final class AffirmativeBasedAuthorizationManager<T> implements AuthorizationManager<T> {

private final List<AccessDecisionVoter<?>> decisionVoters;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think the ideal would be to initialize instances of AuthorizationManager with the correct security metadata instead of retrieving the security metadata each time an authentication is being checked.

Instead of routing the rules configured in the DSL through the ConfigAttribute API, have you already considered having the DSL construct a delegating AuthorizationManager that is composed of delegates that already have the security metadata?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this implementation requires less changes and we can reuse voters.
I'm not sure how this can be implemented for Method Security, the AffirmativeBasedAuthorizationManager is also used in GlobalMethodSecurityConfiguration.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

While I agree that this might be less change, we don't want to introduce a public API that continues to have the same level of complexity as the existing API. The primary goal of this PR is to simplify the authorization API. Generally speaking, we ought to, going forward, avoid using the ConfigAttribute approach.

As you mentioned, this is more deeply embedded in method security. I wonder if this class could be package-private to method security configuration, and we can introduce another ticket to continue to rework method security.

Copy link
Contributor Author

@evgeniycheban evgeniycheban Oct 9, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I forget that AffirmativeBasedAuthorizationManager is also used for Web Socket configuration in AbstractSecurityWebSocketMessageBrokerConfigurer, maybe for now we can use an adapter for AccessDecisionManager and rework Method Security and Web Socket configurations in another ticket?

@jzheaux
Copy link
Contributor

jzheaux commented Dec 11, 2020

Thanks, @evgeniycheban! Let's now have @rwinch take a look as I anticipate that he will also have some feedback.

Copy link
Member

@rwinch rwinch left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the PR @evgeniycheban! I'm really happy how this turned out.

I think we should revisit #8996 (comment)

If it is a bug, then I think we should create a separate ticket and commit with tests for it. This makes it easier for users to track changes (that it changed and why it changed). It also makes it easier for us to backport bug fixes.

Comment on lines 47 to 57
/**
* Determines if access should be granted for a specific authentication and object.
* @param authentication the {@link Supplier} of the {@link Authentication} to check
* @param object the {@link T} object to check
* @return true if access is granted, false if denied
*/
default boolean isGranted(Supplier<Authentication> authentication, T object) {
AuthorizationDecision decision = check(authentication, object);
return decision == null || decision.isGranted();
}

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
/**
* Determines if access should be granted for a specific authentication and object.
* @param authentication the {@link Supplier} of the {@link Authentication} to check
* @param object the {@link T} object to check
* @return true if access is granted, false if denied
*/
default boolean isGranted(Supplier<Authentication> authentication, T object) {
AuthorizationDecision decision = check(authentication, object);
return decision == null || decision.isGranted();
}

I'd prefer to leave this out to keep the interface as simple as possible and provide better symmetry to ReactiveAuthorizationManager. We can always add it later if necessary since it would be passive.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is an old diff, please see the last (62283faa) commit.


private final Collection<String> authorities;

public AuthorityAuthorizationManager(Collection<String> authorities) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it might be better to make the constructor package scope and add some static factory methods like AuthorityReactiveAuthorizationManager does.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is an old diff, please see the last (62283fa) commit.

@evgeniycheban
Copy link
Contributor Author

@rwinch I reverted changes for MvcRequestMatcher and AntPathRequestMatcher.

@evgeniycheban
Copy link
Contributor Author

@rwinch Currently, MvcRequestMatcher.matcher doesn't check HttpMethod and servletPath like MvcRequestMatcher.matches does. Should I create a separate ticket for this or leave my changes in this PR?

@jzheaux
Copy link
Contributor

jzheaux commented Dec 16, 2020

@evgeniycheban If the changes aren't required for this PR, then it's best to file a separate ticket, especially since the changes aren't related to the ticket that this PR is resolving.

The reason for that is it simplifies backporting bug fixes to other branches. Also, it makes release notes clearer for users that are affected by the bugs as they'll see a separate line item in the notes.

@jzheaux
Copy link
Contributor

jzheaux commented Dec 16, 2020

@evgeniycheban, I added #9284 and #9285 to address MvcRequestMatcher and AntPathRequestMatcher, respectively.

@jzheaux jzheaux merged commit 34b4b10 into spring-projects:master Dec 16, 2020
@jzheaux
Copy link
Contributor

jzheaux commented Dec 16, 2020

Thanks for all your work on this PR, @evgeniycheban! It's very exciting.

In addition to the above two tasks, I've created #9286, #9287, and #9288 for other improvements that we identified during the PR.

@jzheaux jzheaux self-assigned this Dec 17, 2020
@jzheaux jzheaux added in: core An issue in spring-security-core type: enhancement A general enhancement and removed status: waiting-for-triage An issue we've not yet triaged labels Dec 17, 2020
@jzheaux jzheaux added this to the 5.5.0-M2 milestone Dec 17, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
in: core An issue in spring-security-core type: enhancement A general enhancement
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Add AuthorizationManager
4 participants