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

Configurable authentication converter for resource-servers with token introspection #11665

Closed
wants to merge 1 commit into from

Conversation

ch4mpy
Copy link
Contributor

@ch4mpy ch4mpy commented Aug 5, 2022

This could close #11661

It adds configurable authentication converter for resource-servers with token introspection (something very similar to what JwtAuthenticationConverter does for resource-servers with JWT decoder).

The new (Reactive)OpaqueTokenAuthenticationConverter is given responsibility for converting successful token introspection result into an Authentication instance (which is currently done by private methods of OpaqueTokenAuthenticationProvider and OpaqueTokenReactiveAuthenticationManager).

(Reactive)BearerTokenAuthenticationConverter, the default (Reactive)OpaqueTokenAuthenticationConverter, behave the same as current private convert(OAuth2AuthenticatedPrincipal principal, String token) methods: map authorities from scope attribute and return a BearerTokenAuthentication.

New unit test classes are created for default authentication converters and tests related to authorities mapping are moved there.

Existing tests for OpaqueTokenAuthenticationProvider and OpaqueTokenReactiveAuthenticationManager are modified to simply assert that introspector and authenticationConverter are called and that resulting Authentication is propagated.

P.S.
I set 6.0 as target but can of course modify this to 5.8 or whatever depending on how you schedule the feature (additional XSDs could need an update depending on the branch this is merged to).

@spring-projects-issues spring-projects-issues added the status: waiting-for-triage An issue we've not yet triaged label Aug 5, 2022
@ch4mpy ch4mpy changed the title Gh 11661 Gh 11661 Configurable authentication converter for resource-servers with token introspection Aug 10, 2022
@ch4mpy
Copy link
Contributor Author

ch4mpy commented Aug 11, 2022

@sjohnr and @marcusdacoregio I believe this PR to be ready for review.

@sjohnr
Copy link
Member

sjohnr commented Aug 11, 2022

Thanks @ch4mpy! As we're working through some priority tasks for 5.8 and 6.0, it may be a slight delay before I'm able to take a look at this.

@sjohnr sjohnr self-assigned this Aug 11, 2022
@sjohnr sjohnr added status: duplicate A duplicate of another issue type: enhancement A general enhancement in: oauth2 An issue in OAuth2 modules (oauth2-core, oauth2-client, oauth2-resource-server, oauth2-jose) labels Aug 11, 2022
@ch4mpy
Copy link
Contributor Author

ch4mpy commented Aug 11, 2022

@sjohnr I understand. Just put it together right now because I had a little time and the idea was fresh in my mind.

I couldn't find the issue / PR I'm duplicating. Could you please point me to it?

@sjohnr
Copy link
Member

sjohnr commented Aug 11, 2022

Thanks for taking the time! We use the duplicate label for book-keeping so only one issue (either the issue or the PR) goes into the release notes, and so whoever did the work gets credit. Since you opened the issue AND the PR, I just marked this PR as the duplicate.

@ch4mpy
Copy link
Contributor Author

ch4mpy commented Aug 25, 2022

@sjohnr I added a separate commit for 5.8 XSD and doc, just in case you have some time to review any time soon. The commit is easy to remove otherwise.

There is no breaking change with this PR, default behavior should remain the same.

@sjohnr
Copy link
Member

sjohnr commented Aug 25, 2022

Thanks @ch4mpy. Apologies, I haven't been able to review it thoroughly yet, as I'm still heads down. However, glancing at it, I wanted to mention one thing to think about. You may want to consider the Converter interface from spring-core. It's used fairly extensively throughout the framework already, and we'd probably want to prefer that over introducing new interfaces. Switching that over will get you a bit ahead on review feedback.

I'll let you know when I have a bit more time to review.

@ch4mpy
Copy link
Contributor Author

ch4mpy commented Aug 25, 2022

Actually, I had considered using the Converter interface but had two reserves :

  • current convertion methods have two parameters (token string and OAuth2AuthenticatedPrincipal) => I'd have to create a new class, let's say IntrospectionResult, to wrap the two parameters into a single one.
  • due to generics erasure or something, in an application or two where I wanted to override several converters, I had to curry it for beans to be correctly wired (do semething like public interface ABConverter extends Converter<A, B> {}).

I'll update the PR with:

  • Converter<IntrospectionResult, ? extends Authentication> instead of OpaqueTokenAuthenticationConverter
  • Converter<IntrospectionResult, Mono<? extends Authentication>> instead of ReactiveOpaqueTokenAuthenticationConverter

Please confirm that IntrospectionResult is fine for naming the converter source type.

@sjohnr
Copy link
Member

sjohnr commented Aug 26, 2022

Please confirm that IntrospectionResult is fine for naming the converter source type.

I'll spend some time thinking about that.

Copy link
Member

@sjohnr sjohnr 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 @ch4mpy! I'm excited about this one. As I mentioned, I'm still a little behind on tasks, but I wanted to give this a bit of attention. See below comments for some suggestions to get you moving forward.

Also, I mention this below but putting it at the top so you can focus on it first:

At the moment, I'm re-thinking my position on using a Converter here. Would you mind reverting the changes to switch to this interface, so we have an OpaqueTokenAuthenticationConverter again? (Sorry for being indecisive!)

Or, if you're not using Spring Boot at all, then both of these components - the filter chain and a <<oauth2resourceserver-opaque-architecture-introspector,`OpaqueTokenIntrospector`>> can be specified in XML.
If the application doesn't expose an `OpaqueTokenAuthenticationConverter` bean, then Spring Boot will expose a `BearerTokenAuthenticationConverter`.

Or, if you're not using Spring Boot at all, then all of these components - the filter chain, an <<oauth2resourceserver-opaque-architecture-introspector,`OpaqueTokenIntrospector`>> and an `OpaqueTokenAuthenticationConverter` can be specified in XML.
Copy link
Member

Choose a reason for hiding this comment

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

Ideally, no changes in Spring Boot should be required, so I think this should be made a separate (standalone) paragraph that just describes the new configuration option with no mention of Spring Boot or other components.

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 tried to rephrase, but I'm not native English speaker. Please provide me with what you want if it still not what you expect.

Copy link
Member

Choose a reason for hiding this comment

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

Ok. Will do!

@sjohnr sjohnr removed the status: waiting-for-triage An issue we've not yet triaged label Aug 29, 2022
@ch4mpy
Copy link
Contributor Author

ch4mpy commented Aug 30, 2022

@sjohnr I:

  • rebased (twice, was lucky enough to pick an unstable main the first time)
  • reverted to OpaqueTokenAuthenticationConverter interface and made it a @FunctionalInterface
  • found a way to share code between servlet and reactive confs for default OpaqueTokenAuthenticationConverter
  • added a test to assert XML conf for optional OpaqueTokenAuthenticationConverter is actually used
  • removed breaking change by adding constructors with OpaqueTokenAuthenticationConverter argument (and keeping constructors without such an argument)
  • removed var and record occurences

@ch4mpy ch4mpy requested a review from sjohnr August 30, 2022 20:03
@ch4mpy ch4mpy force-pushed the gh-11661 branch 2 times, most recently from 6d19f16 to f32af34 Compare August 31, 2022 18:58
@ch4mpy
Copy link
Contributor Author

ch4mpy commented Aug 31, 2022

Rebased on main after #11773 was merged and squashed again.

@ch4mpy
Copy link
Contributor Author

ch4mpy commented Sep 7, 2022

@sjohnr, do you expect more changes from me?

Also, what about OpaqueTokenAuthenticationFactory instead of OpaqueTokenAuthenticationConverter?

Copy link
Member

@sjohnr sjohnr left a comment

Choose a reason for hiding this comment

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

This is definitely developing nicely @ch4mpy! Let's leave the existing interface name for now.

I have more suggestions to some specific areas of the PR, see below. Once we work through this round, any additional (small) changes could be applied as polish by the team when we're ready to merge. Please note that we will pause at that point and wait on this PR until after November (after the 5.8/6.0 release).

@ch4mpy
Copy link
Contributor Author

ch4mpy commented Sep 7, 2022

we will pause at that point and wait on this PR until after November (after the 5.8/6.0 release).

So I should remove modifications to 5.8 xsd and rnc too, maybe? And also modify @Since comments. Do you know what the target version will be?

@ch4mpy
Copy link
Contributor Author

ch4mpy commented Sep 7, 2022

@sjohnr I think I fixed everything as you requested, but static BearerTokenAuthentication convert(String introspectedToken, OAuth2AuthenticatedPrincipal authenticatedPrincipal) for which I set visibility to package instead of private to keep code de-duplication

@sjohnr
Copy link
Member

sjohnr commented Sep 7, 2022

So I should remove modifications to 5.8 xsd and rnc too, maybe? And also modify @since comments. Do you know what the target version will be?

We can wait on that, but thanks for asking! I'll try and keep you updated if anything changes.

Copy link
Member

@sjohnr sjohnr left a comment

Choose a reason for hiding this comment

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

It's looking really good @ch4mpy! I did find a few small things below. Sorry for missing them earlier!

@sjohnr sjohnr changed the title Gh 11661 Configurable authentication converter for resource-servers with token introspection Configurable authentication converter for resource-servers with token introspection Sep 7, 2022
@sjohnr
Copy link
Member

sjohnr commented Sep 9, 2022

Thanks for the updates @ch4mpy. After discussing with the team, I think we're good to merge PRs from the community into 5.8. As I mentioned, we've switched to merge-forward as a strategy, so we ultimately want to target 5.8 for this PR. If you happen to have a bit more time, you could squash commits and move the commit to the 5.8.x branch to see if it moves without conflicts (I believe you can edit the base of this PR without opening a new one). If you don't have time, don't worry about it and I can try and find time in the next week or two to get it moved over.

@ch4mpy ch4mpy changed the base branch from main to 5.8.x September 9, 2022 20:46
@ch4mpy ch4mpy changed the base branch from 5.8.x to main September 9, 2022 20:51
@ch4mpy ch4mpy force-pushed the gh-11661 branch 2 times, most recently from dbb003e to b436143 Compare September 9, 2022 23:24
@ch4mpy ch4mpy changed the base branch from main to 5.8.x September 9, 2022 23:24
Adds configurable authentication converter for resource-servers with token introspection (something very similar to what JwtAuthenticationConverter does for resource-servers with JWT decoder).

The new (Reactive)OpaqueTokenAuthenticationConverter is given responsibility for converting successful token introspection result into an Authentication instance (which is currently done by a private methods of OpaqueTokenAuthenticationProvider and OpaqueTokenReactiveAuthenticationManager).

The default (Reactive)OpaqueTokenAuthenticationConverter, behave the same as current private convert(OAuth2AuthenticatedPrincipal principal, String token) methods: map authorities from scope attribute and build a BearerTokenAuthentication.
@ch4mpy
Copy link
Contributor Author

ch4mpy commented Sep 12, 2022

@sjohnr squashed and rebased on 5.8.x.

Of course, 6.0 xsd and rnc modifications where lost in the process.

sjohnr added a commit that referenced this pull request Sep 14, 2022
sjohnr added a commit that referenced this pull request Sep 14, 2022
* Add authentication-converter-ref to 6.0
* Add @configuration to test configs
@sjohnr
Copy link
Member

sjohnr commented Sep 14, 2022

Merged to 5.8.x as 1efb633. I added polish in 355ef21 and 1aee40d.

@sjohnr sjohnr closed this Sep 14, 2022
@sjohnr sjohnr added this to the 5.8.0-M3 milestone Sep 14, 2022
jzheaux added a commit to jzheaux/spring-security that referenced this pull request Oct 6, 2022
jzheaux added a commit that referenced this pull request Oct 6, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
in: oauth2 An issue in OAuth2 modules (oauth2-core, oauth2-client, oauth2-resource-server, oauth2-jose) status: duplicate A duplicate of another issue type: enhancement A general enhancement
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Configurable authentication converter for resource-servers with token introspection
3 participants