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>
|
<dependency>
|
||||||
<groupId>io.github.openfeign.form</groupId>
|
<groupId>io.github.openfeign.form</groupId>
|
||||||
<artifactId>feign-form-spring</artifactId>
|
<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>
|
<dependency>
|
||||||
<groupId>org.springframework.boot</groupId>
|
<groupId>org.springframework.boot</groupId>
|
||||||
<artifactId>spring-boot-starter-test</artifactId>
|
<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
|
spring.application.name= openfeign
|
||||||
logging.level.com.baeldung.cloud.openfeign.client: DEBUG
|
logging.level.com.baeldung.cloud.openfeign.client: DEBUG
|
||||||
feign.hystrix.enabled=true
|
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…
x
Reference in New Issue
Block a user