I'm using Spring Boot 2.3.4 and I need to call an external web service that needs the oauth2 authentication.
Currently I've achieved that in this way using feign
Client
@FeignClient(name = "myClient", value = "myClient", url = "${app.my.client.apiUrl}", configuration = MyClientConfiguration.class)
public interface MyClient {
@GetMapping(value = "/api/my-url", consumes = "application/json")
String getSomeData();
}
Client Configuration
public class MyClientConfiguration {
private final OAuth2AuthorizedClientService oAuth2AuthorizedClientService;
private final ClientRegistrationRepository clientRegistrationRepository;
public MyClientConfiguration(OAuth2AuthorizedClientService oAuth2AuthorizedClientService, ClientRegistrationRepository clientRegistrationRepository) {
this.oAuth2AuthorizedClientService = oAuth2AuthorizedClientService;
this.clientRegistrationRepository = clientRegistrationRepository;
}
@Bean
public RequestInterceptor requestInterceptor() {
ClientRegistration clientRegistration = clientRegistrationRepository.findByRegistrationId("my-client");
AuthorizedClientServiceOAuth2AuthorizedClientManager authorizedClientManager = new AuthorizedClientServiceOAuth2AuthorizedClientManager(clientRegistrationRepository, oAuth2AuthorizedClientService);
authorizedClientManager.setAuthorizedClientProvider(OAuth2AuthorizedClientProviderBuilder.builder().clientCredentials().build());
return new OAuthClientCredentialsRestTemplateInterceptor(authorizedClientManager, clientRegistration);
}
}
OAuth Interceptor
public class OAuthClientCredentialsRestTemplateInterceptor implements RequestInterceptor {
private static final String BEARER_HEADER_NAME = "Bearer";
private final OAuth2AuthorizedClientManager manager;
private final Authentication emptyPrincipal;
private final ClientRegistration clientRegistration;
public OAuthClientCredentialsRestTemplateInterceptor(OAuth2AuthorizedClientManager manager, ClientRegistration clientRegistration) {
this.manager = manager;
this.clientRegistration = clientRegistration;
this.emptyPrincipal = createEmptyPrincipal();
}
@Override
public void apply(RequestTemplate requestTemplate) {
OAuth2AuthorizeRequest oAuth2AuthorizeRequest = OAuth2AuthorizeRequest.withClientRegistrationId(clientRegistration.getRegistrationId()).principal(emptyPrincipal).build();
OAuth2AuthorizedClient client = manager.authorize(oAuth2AuthorizeRequest);
if (client == null)
throw new IllegalStateException("Cannot retrieve a valid client for registration " + clientRegistration.getRegistrationId());
requestTemplate.header(HttpHeaders.AUTHORIZATION, BEARER_HEADER_NAME + " " + client.getAccessToken().getTokenValue());
}
private Authentication createEmptyPrincipal() {
return new Authentication() {
@Override
public Collection<? extends GrantedAuthority> getAuthorities() {
return Collections.emptySet();
}
@Override
public Object getCredentials() {
return null;
}
@Override
public Object getDetails() {
return null;
}
@Override
public Object getPrincipal() {
return this;
}
@Override
public boolean isAuthenticated() {
return false;
}
@Override
public void setAuthenticated(boolean isAuthenticated) throws IllegalArgumentException {
}
@Override
public String getName() {
return clientRegistration.getClientId();
}
};
}
}
properties
spring:
security:
oauth2:
client:
registration:
microsoft:
client-id: ******
client-secret: ******
scope: ******
authorization-grant-type: client_credentials
provider: my-client
provider:
my-client:
token-uri: ******
app:
my-client:
apiUrl: https://my-url.com
feign:
hystrix:
enabled: false
client:
config:
default:
connect-timeout: 3000
In another project I need the same BUT it's a spring boot application without the web environment, and I've the following error
bean of type 'org.springframework.security.oauth2.client.OAuth2AuthorizedClientService' that could not be found.
How can I solve this situation?
Is it possible to use the oauth2 auto-configuration in an environment without a tomcat (or similar)?