-
Notifications
You must be signed in to change notification settings - Fork 6k
Register RestOperations @Bean for OAuth 2.0 Client #8732
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
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,5 +1,5 @@ | ||
/* | ||
* Copyright 2002-2018 the original author or authors. | ||
* Copyright 2002-2020 the original author or authors. | ||
* | ||
* Licensed under the Apache License, Version 2.0 (the "License"); | ||
* you may not use this file except in compliance with the License. | ||
|
@@ -20,12 +20,14 @@ | |
import org.springframework.context.ApplicationContext; | ||
import org.springframework.security.config.annotation.web.HttpSecurityBuilder; | ||
import org.springframework.security.config.annotation.web.configurers.AbstractHttpConfigurer; | ||
import org.springframework.security.config.oauth2.client.OAuth2ClientBeanNames; | ||
import org.springframework.security.oauth2.client.InMemoryOAuth2AuthorizedClientService; | ||
import org.springframework.security.oauth2.client.OAuth2AuthorizedClientService; | ||
import org.springframework.security.oauth2.client.registration.ClientRegistrationRepository; | ||
import org.springframework.security.oauth2.client.web.AuthenticatedPrincipalOAuth2AuthorizedClientRepository; | ||
import org.springframework.security.oauth2.client.web.OAuth2AuthorizedClientRepository; | ||
import org.springframework.util.StringUtils; | ||
import org.springframework.web.client.RestOperations; | ||
|
||
import java.util.Map; | ||
|
||
|
@@ -96,4 +98,9 @@ private static <B extends HttpSecurityBuilder<B>> OAuth2AuthorizedClientService | |
} | ||
return (!authorizedClientServiceMap.isEmpty() ? authorizedClientServiceMap.values().iterator().next() : null); | ||
} | ||
|
||
static <B extends HttpSecurityBuilder<B>> RestOperations getRestOperationsBean(B builder) { | ||
return builder.getSharedObject(ApplicationContext.class).getBean( | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This looks like it would fail if there isn't a bean by that name and type or if there is more than one bean of this type. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Is there a reason you think we should use a bean name here? We don't typically do the lookups by bean name. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
I thought this is what we decided on, as per comment Furthermore, an application may register one or more Also, see tests in There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Rather than relying on There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Can you please be specific and provide a code sample I could reference? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @rwinch Are you referring to the way we conditionally There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We often try to get a Bean if it doesn't exist we create a default instance. An example is PasswordEncoder |
||
OAuth2ClientBeanNames.REST_OPERATIONS, RestOperations.class); | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm having trouble seeing the value of registering
OAuth2AuthorizedClientManager
with a known bean name.Doing so with
RestOperations
makes sense since there are many use cases when an application publishes aRestOperations
but doesn't intend it to be used by Spring Security.What is it about
OAuth2AuthorizedClientManager
that requires the same treatment asRestOperations
? Is this a needed pattern for other OAuth 2.0 Client beans?There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The
OAuth2AuthorizedClientManager
is the central interface for client since 5.2. It is used primarily byServletOAuth2AuthorizedClientExchangeFilterFunction
andOAuth2AuthorizedClientArgumentResolver
. It indirectly usesRestOperations
. The relationship chain is as follows:OAuth2AuthorizedClientManager
has 1 or moreOAuth2AuthorizedClientProvider
OAuth2AuthorizedClientProvider
has anOAuth2AccessTokenResponseClient
OAuth2AccessTokenResponseClient
has aRestOperations
If an application configures a custom
RestOperations
then it will automatically be configured with the "default"OAuth2AuthorizedClientManager
and associatedOAuth2AuthorizedClientProvider
's, and the user could leverage this default@Bean
instead of explicitly configuring it. It really is meant to be a convenience mechanism.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
One important thing to note is that an application may configure more than 1
OAuth2AuthorizedClientManager
in their setup. For example, they may have a background service that performsclient_credentials
grant and anotherOAuth2AuthorizedClientManager
that handlesauthorization_code
andrefresh_token
in the web context.The "default"
OAuth2AuthorizedClientManager
will be wired into theOAuth2AuthorizedClientArgumentResolver
and may be used byServletOAuth2AuthorizedClientExchangeFilterFunction
.