Skip to content
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

AuthorizationManager should return AuthorizationResult #14846

Merged
merged 3 commits into from
Oct 14, 2024

Conversation

franticticktick
Copy link
Contributor

Added a new authorization method to AuthorizationManager that returns AuthorizationResult.

Closes gh-14843

@spring-projects-issues spring-projects-issues added the status: waiting-for-triage An issue we've not yet triaged label Apr 4, 2024
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, @CrazyParanoid.

With check deprecated, we should no longer call it in from other non-deprecated production code in Spring Security. Can you also make those corresponding changes? Please leave tests as-is, though.

Also, please add tests to ensure that the new method works.

Finally, please take a look at AuthorizaitonManagerBeforeMethodInterceptor and other method interceptors to ensure that they are no longer casting expression values to AuthorizationDecision. Instead, they should implement the authorize method, have their check method call it, and then perform the cast there.

@jzheaux jzheaux self-assigned this Apr 5, 2024
@franticticktick franticticktick force-pushed the gh-14843 branch 3 times, most recently from a368cd1 to 8ee5742 Compare April 7, 2024 15:33
@franticticktick
Copy link
Contributor Author

Hi @jzheaux ! I added the authorize method to the AuthorizationManager and made the default implementation of the check method:

default AuthorizationDecision check(Supplier<Authentication> authentication, T object) {
		return (AuthorizationDecision) authorize(authentication, object);
	}

With this implementation, it will not be possible to leave the tests as is, because in some tests, a mock of the check method is made and its invocation is verified:

verify(this.mockAuthorizationManager).check(any(), any());

And it needs to be changed to authorize, since the mock was made for example:

given(this.mockAuthorizationManager.check(any(), any())).willReturn(new AuthorizationDecision(true));

In addition, there are several delegating components that make call check method of delegate. Here you need to mock the authorize and verify its invocation.

@franticticktick franticticktick requested a review from jzheaux April 10, 2024 14:22
@jzheaux jzheaux changed the title Add support AuthorizationResult for AuthorizationManager AuthorizationManager should return AuthorizationResult Apr 17, 2024
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 for the updates and for your patience as I got back to this PR, @CrazyParanoid. I've left my feedback inilne.

@jzheaux
Copy link
Contributor

jzheaux commented Sep 17, 2024

@CrazyParanoid, also if you have time, once we are aligned on the servlet changes, it would be great if the PR could have the reactive bits as well. I'm happy to add a polish for that if needed.

@franticticktick
Copy link
Contributor Author

Hi @jzheaux. Thanks for your feedback! I will complete this issue in the next few days.

@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 Sep 24, 2024
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.

Looking good, @CrazyParanoid, we're nearly there. I've left some additional feedback inline.

@jzheaux
Copy link
Contributor

jzheaux commented Oct 1, 2024

Additionally, the build appears to be failing due to formatting concerns. Please try running from the command line the following:

./gradlew format && ./gradlew checkstyleMain checkstyleTest

This will correct what it can and then give you a report of the things that you need to change manually from a code convention standpoint.

@franticticktick
Copy link
Contributor Author

Hi @jzheaux , thanks for your feedback! I'll get back to working on this issue soon. But I'm still a little worried about the correctness of the chosen solution - if the authorize method is marked as default, it turns out that all lambdas will implement the check method, is this a problem and how easy will it be to switch all lambdas to the authorize method?

@jzheaux
Copy link
Contributor

jzheaux commented Oct 7, 2024

Good point, @CrazyParanoid, though I think this is something we'll have to take in stride. We don't want to break folks when they upgrade, which is what is driving the decision to mark authorize as default.

I believe the main consequence is that they will not be able to use a lambda and a custom implementation of AuthorizationResult together. Since that feature isn't in Spring Security yet, no one has lost anything.

Either way, it should not be an issue for very long, given that Spring Security 7 will be released next fall where we can remove the check method.

How well does that address your concern?

@franticticktick
Copy link
Contributor Author

I'm not sure if this is type safe. For example, we started using authorize instead of check and get AuthrorizationResult. In this case, eventPublisher is implemented as a noPublish lambda, this lambda requires an object of type AuthorizationDecision, but there is no guarantee that authorize will return exactly AuthorizationDecision, it can return any AuthrorizationResult. Which will immediately result in an error in noPublish.

@franticticktick
Copy link
Contributor Author

This concerns the publisher, I think that, as you said, it would be better to open another ticket for NoOpAuthorizationEventPublisher.

@jzheaux
Copy link
Contributor

jzheaux commented Oct 10, 2024

I agree that the no-publish lambda may not be able to stay. A concrete implementation will likely improve readability as well. It just needs to remain package-private or private (inline) for now.

@franticticktick franticticktick force-pushed the gh-14843 branch 2 times, most recently from 1a5f29c to b88977c Compare October 11, 2024 14:51
@jzheaux jzheaux added this to the 6.4.0-RC1 milestone Oct 14, 2024
@jzheaux jzheaux merged commit 9ce5a76 into spring-projects:main Oct 14, 2024
6 checks passed
@jzheaux
Copy link
Contributor

jzheaux commented Oct 14, 2024

Nice, @CrazyParanoid! This for all this work. I ended up polishing the event support a bit more than expected, so I opened a separate ticket and adjusted the commits accordingly. I also added some polish, largely to remove deprecated usages and references to things like AuthorizationResult decision.

This is now merged into main.

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
Archived in project
Development

Successfully merging this pull request may close these issues.

AuthorizationManager should support returning an AuthorizationResult
3 participants