2

我正在尝试从“ServiceA”调用“ServiceB”,这两个服务都是资源服务器,我正在尝试通过“Feign Client and OAuth2 toke”进行此服务间调用,这与配置类中的以下 bean 实现工作正常:

@Bean    
public RequestInterceptor requestTokenBearerInterceptor() {

    return new RequestInterceptor() {

        @Override
        public void apply(RequestTemplate requestTemplate) {

            OAuth2AuthenticationDetails details = (OAuth2AuthenticationDetails)

            SecurityContextHolder.getContext().getAuthentication()
                    .getDetails();

            requestTemplate.header("Authorization",
                    "bearer " + details.getTokenValue());

        }

    };

}

当我尝试使用带有后备功能的 Feign 客户端时,即没有 OAuth 令牌的 Hystrix(即,当所有服务都不是资源服务器时)也可以正常工作。

但是在尝试同时使用其中三个(即 Feignclient、Hystrix 和 OAuth2)时,它不起作用。尽管所有服务都已启动并正在运行,但每次它都会采用回退方法。

以下是我的代码:

应用程序.java

import org.json.simple.JSONObject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.circuitbreaker.EnableCircuitBreaker;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
import org.springframework.cloud.netflix.feign.EnableFeignClients;
import org.springframework.context.annotation.Bean;
import org.springframework.security.core.context.SecurityContextHolder;
import        org.springframework.security.oauth2.provider.authentication.OAuth2AuthenticationDetails;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;

import feign.RequestInterceptor;
import feign.RequestTemplate;


@SpringBootApplication
@RestController
@EnableFeignClients
@EnableEurekaClient
@EnableCircuitBreaker
public class App 
{

/*@Autowired
@Qualifier("abc")
private GitHubClient gitHub;*/
@Autowired
private CallService callService;
public static void main( String[] args )
{
    SpringApplication.run(App.class, args);
}
    @RequestMapping(value="/feign",method=RequestMethod.POST,consumes="application/json")
public String contributors1(@RequestBody JSONObject payLoad) {
        String callservice2 = callService.callservice(payLoad);
        return callservice2;
}

@Bean
public RequestInterceptor requestTokenBearerInterceptor() {

    return new RequestInterceptor() {

        @Override
        public void apply(RequestTemplate requestTemplate) {

            OAuth2AuthenticationDetails details = (OAuth2AuthenticationDetails)

            SecurityContextHolder.getContext().getAuthentication()
                    .getDetails();

            requestTemplate.header("Authorization",
                    "bearer " + details.getTokenValue());

        }

    };

}



}

Callervice.java

import org.json.simple.JSONObject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Service;

@Service
public class CallService {


@Autowired
@Qualifier("abc")
private GitHubClient gitHub;

public String callservice(JSONObject payLoad){
    String forObject =gitHub.contributors(payLoad);
    return forObject;
}

}

HystrixWrappedClient.java

import org.json.simple.JSONObject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Component;

import com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand;

@Component("abc")
public class HystrixWrappedClient implements GitHubClient{

@Autowired
@Qualifier("gitHubClient")
private GitHubClient gitHub;

@Override
@HystrixCommand(fallbackMethod="failure")
public String contributors(JSONObject payLoad) {
    return gitHub.contributors(payLoad);
}

public String failure(JSONObject payLoad){
    System.out.println(payLoad);
    return "Failure";
}
}

GitHubClient.java

import org.json.simple.JSONObject;
import org.springframework.cloud.netflix.feign.FeignClient;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;

@FeignClient("MockRestService")
interface GitHubClient {


@RequestMapping(method = RequestMethod.POST, value =     "/test",consumes="application/json")
String contributors(@RequestBody JSONObject payLoad);

}

pom.xml

<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>1.2.5.RELEASE</version>
</parent>


<dependencies>
    <dependency>
        <groupId>com.googlecode.json-simple</groupId>
        <artifactId>json-simple</artifactId>
        <version>1.1.1</version>
    </dependency>
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-config-client</artifactId>
        <version>1.0.0.RELEASE</version>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-actuator</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-eureka</artifactId>
        <version>1.0.1.RELEASE</version>
    </dependency>
    <!-- For swagger documenation -->
    <dependency>
        <groupId>com.mangofactory</groupId>
        <artifactId>swagger-springmvc</artifactId>
        <version>1.0.2</version>
    </dependency>
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-security</artifactId>
    </dependency>

    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-hystrix</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.security.oauth</groupId>
        <artifactId>spring-security-oauth2</artifactId>
    </dependency>

    <!-- NEW -->
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-feign</artifactId>
    </dependency>


</dependencies>
<dependencyManagement>
    <dependencies>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-parent</artifactId>
            <version>1.0.1.RELEASE</version>
            <type>pom</type>
            <scope>import</scope>
        </dependency>
    </dependencies>
</dependencyManagement>

请建议。每当尝试同时使用 Feignclient、OAuth2 和 Hystrix 时,它总是会使用 Fallback 方法。

4

2 回答 2

2

您是否以某种方式与 Hystrix 共享 Spring Security 上下文?

Spring Cloud Netflix 1.2.0开始,您可以使用配置参数与 Hystrix 共享安全上下文

hystrix.shareSecurityContext: true

于 2017-03-24T07:57:18.610 回答
1

您可以查看此http://kodgemisi.com/2017/02/use-securitycontext-feign-requestinterceptor/ Hystrix 在另一个/不同的线程中执行,通过 HystrixRequestVariableDefault 传输您的安全上下文

于 2017-03-23T06:15:29.387 回答