Merge pull request #11759 from hmdrzsharifi/BAEL-5300
Bael 5300: Provide an OAuth2 Token to a Feign Client
This commit is contained in:
commit
c4065e80b4
|
@ -48,7 +48,15 @@
|
|||
<dependency>
|
||||
<groupId>io.github.openfeign.form</groupId>
|
||||
<artifactId>feign-form-spring</artifactId>
|
||||
</dependency>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-security</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.security</groupId>
|
||||
<artifactId>spring-security-oauth2-client</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-test</artifactId>
|
||||
|
|
|
@ -0,0 +1,16 @@
|
|||
package com.baeldung.cloud.openfeign.client;
|
||||
|
||||
import com.baeldung.cloud.openfeign.model.Payment;
|
||||
import com.baeldung.cloud.openfeign.oauthfeign.OAuthFeignConfig;
|
||||
import org.springframework.cloud.openfeign.FeignClient;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMethod;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@FeignClient(name = "payment-client", url = "http://localhost:8081/resource-server-jwt", configuration = OAuthFeignConfig.class)
|
||||
public interface PaymentClient {
|
||||
|
||||
@RequestMapping(value = "/payments", method = RequestMethod.GET)
|
||||
List<Payment> getPayments();
|
||||
}
|
|
@ -0,0 +1,24 @@
|
|||
package com.baeldung.cloud.openfeign.controller;
|
||||
|
||||
import com.baeldung.cloud.openfeign.client.PaymentClient;
|
||||
import com.baeldung.cloud.openfeign.model.Payment;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@RestController
|
||||
public class PaymentController {
|
||||
|
||||
private final PaymentClient paymentClient;
|
||||
|
||||
public PaymentController(PaymentClient paymentClient) {
|
||||
this.paymentClient = paymentClient;
|
||||
}
|
||||
|
||||
@GetMapping("/payments")
|
||||
public List<Payment> getPayments() {
|
||||
List<Payment> payments = paymentClient.getPayments();
|
||||
return payments;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,23 @@
|
|||
package com.baeldung.cloud.openfeign.model;
|
||||
|
||||
public class Payment {
|
||||
|
||||
private String id;
|
||||
private double amount;
|
||||
|
||||
public String getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(String id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public double getAmount() {
|
||||
return amount;
|
||||
}
|
||||
|
||||
public void setAmount(double amount) {
|
||||
this.amount = amount;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,19 @@
|
|||
package com.baeldung.cloud.openfeign.oauthfeign;
|
||||
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
|
||||
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
|
||||
|
||||
@Configuration
|
||||
public class OAuth2WebSecurityConfigurerAdapter extends WebSecurityConfigurerAdapter {
|
||||
|
||||
@Override
|
||||
protected void configure(HttpSecurity http) throws Exception {
|
||||
http
|
||||
.csrf()
|
||||
.disable()
|
||||
.oauth2Client();
|
||||
http
|
||||
.authorizeRequests().anyRequest().permitAll();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,85 @@
|
|||
package com.baeldung.cloud.openfeign.oauthfeign;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.security.core.Authentication;
|
||||
import org.springframework.security.core.GrantedAuthority;
|
||||
import org.springframework.security.oauth2.client.OAuth2AuthorizeRequest;
|
||||
import org.springframework.security.oauth2.client.OAuth2AuthorizedClient;
|
||||
import org.springframework.security.oauth2.client.OAuth2AuthorizedClientManager;
|
||||
import org.springframework.security.oauth2.client.registration.ClientRegistration;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
|
||||
import static java.util.Objects.isNull;
|
||||
|
||||
public class OAuthClientCredentialsFeignManager {
|
||||
|
||||
private static final Logger logger = LoggerFactory.getLogger(OAuthClientCredentialsFeignManager.class);
|
||||
|
||||
private final OAuth2AuthorizedClientManager manager;
|
||||
private final Authentication principal;
|
||||
private final ClientRegistration clientRegistration;
|
||||
|
||||
public OAuthClientCredentialsFeignManager(OAuth2AuthorizedClientManager manager, ClientRegistration clientRegistration) {
|
||||
this.manager = manager;
|
||||
this.clientRegistration = clientRegistration;
|
||||
this.principal = createPrincipal();
|
||||
}
|
||||
|
||||
private Authentication createPrincipal() {
|
||||
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();
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
public String getAccessToken() {
|
||||
try {
|
||||
OAuth2AuthorizeRequest oAuth2AuthorizeRequest = OAuth2AuthorizeRequest
|
||||
.withClientRegistrationId(clientRegistration.getRegistrationId())
|
||||
.principal(principal)
|
||||
.build();
|
||||
OAuth2AuthorizedClient client = manager.authorize(oAuth2AuthorizeRequest);
|
||||
if (isNull(client)) {
|
||||
throw new IllegalStateException("client credentials flow on " + clientRegistration.getRegistrationId() + " failed, client is null");
|
||||
}
|
||||
return client.getAccessToken().getTokenValue();
|
||||
} catch (Exception exp) {
|
||||
logger.error("client credentials error " + exp.getMessage());
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,46 @@
|
|||
package com.baeldung.cloud.openfeign.oauthfeign;
|
||||
|
||||
import feign.RequestInterceptor;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.security.oauth2.client.*;
|
||||
import org.springframework.security.oauth2.client.registration.ClientRegistration;
|
||||
import org.springframework.security.oauth2.client.registration.ClientRegistrationRepository;
|
||||
|
||||
@Configuration
|
||||
public class OAuthFeignConfig {
|
||||
|
||||
public static final String CLIENT_REGISTRATION_ID = "keycloak";
|
||||
|
||||
private final OAuth2AuthorizedClientService oAuth2AuthorizedClientService;
|
||||
private final ClientRegistrationRepository clientRegistrationRepository;
|
||||
|
||||
public OAuthFeignConfig(OAuth2AuthorizedClientService oAuth2AuthorizedClientService,
|
||||
ClientRegistrationRepository clientRegistrationRepository) {
|
||||
this.oAuth2AuthorizedClientService = oAuth2AuthorizedClientService;
|
||||
this.clientRegistrationRepository = clientRegistrationRepository;
|
||||
}
|
||||
|
||||
@Bean
|
||||
public RequestInterceptor requestInterceptor() {
|
||||
ClientRegistration clientRegistration = clientRegistrationRepository.findByRegistrationId(CLIENT_REGISTRATION_ID);
|
||||
OAuthClientCredentialsFeignManager clientCredentialsFeignManager =
|
||||
new OAuthClientCredentialsFeignManager(authorizedClientManager(), clientRegistration);
|
||||
return requestTemplate -> {
|
||||
requestTemplate.header("Authorization", "Bearer " + clientCredentialsFeignManager.getAccessToken());
|
||||
};
|
||||
}
|
||||
|
||||
@Bean
|
||||
OAuth2AuthorizedClientManager authorizedClientManager() {
|
||||
OAuth2AuthorizedClientProvider authorizedClientProvider = OAuth2AuthorizedClientProviderBuilder.builder()
|
||||
.clientCredentials()
|
||||
.build();
|
||||
|
||||
AuthorizedClientServiceOAuth2AuthorizedClientManager authorizedClientManager =
|
||||
new AuthorizedClientServiceOAuth2AuthorizedClientManager(clientRegistrationRepository, oAuth2AuthorizedClientService);
|
||||
authorizedClientManager.setAuthorizedClientProvider(authorizedClientProvider);
|
||||
return authorizedClientManager;
|
||||
}
|
||||
|
||||
}
|
|
@ -1,3 +1,10 @@
|
|||
server.port=8085
|
||||
spring.main.allow-bean-definition-overriding=true
|
||||
spring.application.name= openfeign
|
||||
logging.level.com.baeldung.cloud.openfeign.client: DEBUG
|
||||
feign.hystrix.enabled=true
|
||||
|
||||
spring.security.oauth2.client.registration.keycloak.authorization-grant-type=client_credentials
|
||||
spring.security.oauth2.client.registration.keycloak.client-id=payment-app
|
||||
spring.security.oauth2.client.registration.keycloak.client-secret=863e9de4-33d4-4471-b35e-f8d2434385bb
|
||||
spring.security.oauth2.client.provider.keycloak.token-uri=http://localhost:8083/auth/realms/master/protocol/openid-connect/token
|
||||
|
|
|
@ -0,0 +1,30 @@
|
|||
package com.baeldung.cloud.openfeign;
|
||||
|
||||
import com.baeldung.cloud.openfeign.client.PaymentClient;
|
||||
import com.baeldung.cloud.openfeign.model.Payment;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
import org.springframework.test.context.junit4.SpringRunner;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import static org.junit.Assert.assertFalse;
|
||||
|
||||
@RunWith(SpringRunner.class)
|
||||
@SpringBootTest
|
||||
public class PaymentClientUnitTest {
|
||||
|
||||
@Autowired
|
||||
private PaymentClient paymentClient;
|
||||
|
||||
@Test
|
||||
public void whenGetPayment_thenListPayments() {
|
||||
|
||||
List<Payment> payments = paymentClient.getPayments();
|
||||
|
||||
assertFalse(payments.isEmpty());
|
||||
}
|
||||
|
||||
}
|
Loading…
Reference in New Issue