-
Notifications
You must be signed in to change notification settings - Fork 41.2k
Broaden OAuth2 client auto-configuration to include non servlet web applications #40997
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
Comments
@mcordeiro73, can you please share an example of how you're setting up the @rwinch, do you think this makes sense for imperative non-web apps as #14350 did for reactive non-web apps? |
Below is the configuration of my @Bean
public RestClient oktaRestClient(RestClient.Builder builder, ClientRegistrationRepository clientRegistrationRepository, OAuth2AuthorizedClientService oauth2AuthorizedClientService) {
OAuth2AuthorizedClientManager authorizedClientManager = new AuthorizedClientServiceOAuth2AuthorizedClientManager(clientRegistrationRepository, oauth2AuthorizedClientService);
ClientRegistration clientRegistration = clientRegistrationRepository.findByRegistrationId("okta");
return builder.requestInterceptor(new Oauth2ClientHttpRequestInterceptor(authorizedClientManager, clientRegistration))
.defaultStatusHandler(RemoveAuthorizedClientOAuth2ResponseErrorHandler.unauthorizedStatusPredicate(), RemoveAuthorizedClientOAuth2ResponseErrorHandler.createErrorHandler(oauth2AuthorizedClientService, clientRegistration))
.build();
} public class Oauth2ClientHttpRequestInterceptor implements ClientHttpRequestInterceptor {
private final OAuth2AuthorizedClientManager oAuth2AuthorizedClientManager;
private final ClientRegistration clientRegistration;
public Oauth2ClientHttpRequestInterceptor(@NotNull OAuth2AuthorizedClientManager oAuth2AuthorizedClientManager, @NotNull ClientRegistration clientRegistration) {
this.oAuth2AuthorizedClientManager = oAuth2AuthorizedClientManager;
this.clientRegistration = clientRegistration;
}
@Override
public ClientHttpResponse intercept(HttpRequest request, byte[] body, ClientHttpRequestExecution execution) throws IOException {
request.getHeaders()
.setBearerAuth(getBearerToken());
return execution.execute(request, body);
}
private String getBearerToken() {
OAuth2AuthorizeRequest oAuth2AuthorizeRequest = OAuth2AuthorizeRequest.withClientRegistrationId(clientRegistration.getRegistrationId())
.principal(clientRegistration.getClientId())
.build();
OAuth2AuthorizedClient client = oAuth2AuthorizedClientManager.authorize(oAuth2AuthorizeRequest);
Assert.notNull(client, () -> "Authorized client failed for Registration id: '" + clientRegistration.getRegistrationId() + "', returned client is null");
return client.getAccessToken()
.getTokenValue();
}
} public class RemoveAuthorizedClientOAuth2ResponseErrorHandler extends DefaultResponseErrorHandler {
private static final Predicate<HttpStatusCode> STATUS_PREDICATE = httpStatusCode -> httpStatusCode.value() == HttpStatus.UNAUTHORIZED.value();
private final OAuth2AuthorizedClientService oauth2AuthorizedClientService;
private final ClientRegistration clientRegistration;
public RemoveAuthorizedClientOAuth2ResponseErrorHandler(@NotNull OAuth2AuthorizedClientService oauth2AuthorizedClientService, @NotNull ClientRegistration clientRegistration) {
this.oauth2AuthorizedClientService = oauth2AuthorizedClientService;
this.clientRegistration = clientRegistration;
}
@Override
public void handleError(ClientHttpResponse clientHttpResponse) throws IOException {
if (STATUS_PREDICATE.test(clientHttpResponse.getStatusCode())) {
oauth2AuthorizedClientService.removeAuthorizedClient(clientRegistration.getRegistrationId(), clientRegistration.getClientId());
}
super.handleError(clientHttpResponse);
}
public static RestClient.ResponseSpec.ErrorHandler createErrorHandler(@NotNull OAuth2AuthorizedClientService oauth2AuthorizedClientService, @NotNull ClientRegistration clientRegistration) {
ResponseErrorHandler responseErrorHandler = new RemoveAuthorizedClientOAuth2ResponseErrorHandler(oauth2AuthorizedClientService, clientRegistration);
return (request, response) -> responseErrorHandler.handleError(response);
}
public static Predicate<HttpStatusCode> unauthorizedStatusPredicate() {
return STATUS_PREDICATE;
}
} |
@wilkinsona This sounds like a useful change since clients are not necessarily web applications. |
Thanks, @rwinch. When we come to implement this, we may want to review the package that |
+1 to this request. We just faced this issue today in our batch app. While it was simple enough to copy the |
It's looking for a non-servlet app, that is to say a reactive web appplication or a non-web application. I'm afraid we can't change that as it would break anyone who's using a reactive client in a non-web application. |
So what is the best way to use OIDC client in a batch ? |
@neoludo please read the whole issue if you have not already done so. @mcordeiro73 has kindly already described how they're configuring things manually in the auto-configuration's absence. If you have specific questions about how to configure things manually, please ask them on Stack Overflow. As mentioned in the guidelines for contributing, we prefer to use GitHub issues only for bugs and enhancements. |
I did. So there is no plan to have an official starter working for non web
apps ?
Le jeu. 10 oct. 2024, 11:52, Andy Wilkinson ***@***.***> a
écrit :
… @neoludo <https://github.com/neoludo> please read the whole issue if you
have not already done so. @mcordeiro73 <https://github.com/mcordeiro73>
has kindly already described how they're configuring things manually in the
auto-configuration's absence. If you have specific questions about how to
configure things manually, please ask them on Stack Overflow. As mentioned
in the guidelines for contributing
<https://github.com/spring-projects/spring-boot/blob/main/CONTRIBUTING.adoc#using-github-issues>,
we prefer to use GitHub issues only for bugs and enhancements.
—
Reply to this email directly, view it on GitHub
<#40997 (comment)>,
or unsubscribe
<https://github.com/notifications/unsubscribe-auth/AAD76MKELJNSPZEWSEZKBEDZ2ZE43AVCNFSM6AAAAABI27UH7KVHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMZDIMBUGYZDKNRZHA>
.
You are receiving this because you were mentioned.Message ID:
***@***.***>
|
Why do you assume there's no plan when this issue, that remains open, is tracking the improvement that you seem to want? We hope to implement it in a future Spring Boot 3.x release. In the meantime, "the best way to use OIDC client" in a non-web app is described above. |
Glad to hear that. I just had done a bad interpretation of your last comment last month. Sorry for that. |
I looked at this, and we have the following situation at the moment:
|
|
If we now change the condition for
Is that what we want? |
I'd do this:
That'd give us this:
And taking #40997 (comment) in account, I'd move |
Attempting to setup a Spring Boot application that is not a Web Application, unable to rely on auto configuration of OAuth2Client due to
OAuth2ClientAutoConfiguration
having@ConditionalOnWebApplication(type = ConditionalOnWebApplication.Type.SERVLET)
.The batch job we are attempting to setup has a client to a Rest API that requires OAuth2 authentication. When attempting to Autowire
ClientRegistrationRepository
andOAuth2AuthorizedClientService
into a Bean method in order so setup theRestClient
, received error thatParameter 1 of method oauth2RestClient in com.sample.batch.configuration.RestClientConfiguration required a bean of type 'org.springframework.security.oauth2.client.registration.ClientRegistrationRepository' that could not be found
.We were able to get around this by providing our own
ClientRegistrationRepository
andOAuth2AuthorizedClientService
beans, but I believe that these auto configured beans should not require the Spring Boot app to be running in a servlet environment.The text was updated successfully, but these errors were encountered: