Spring Cloud 应用程序中具有 Forbidden 状态的微服务请求响应
Posted
技术标签:
【中文标题】Spring Cloud 应用程序中具有 Forbidden 状态的微服务请求响应【英文标题】:inter micro-service request responds with Forbidden status in spring cloud application 【发布时间】:2018-10-27 12:22:18 【问题描述】:我正在研究微服务架构。我选择了spring cloud框架。
我的应用程序 shema 如下所示:
我也有发现服务器 eureka,但我决定跳过图片以简化它。
示例的完整源代码可以在 githib 上找到:https://github.com/gredwhite/spring-cloud
问题说明:
你好世界服务:
@GetMapping("/helloWorld")
@HystrixCommand(fallbackMethod = "reliable")
public String hello()
return this.restTemplate.getForObject("http://hello-service/hello?name=World", String.class);
你好服务:
@GetMapping("/hello")
public String hello(@RequestParam("name") String name) throws UnknownHostException, InterruptedException
return "Hello " + name + "!";
当我启动 hello service
并尝试访问 localhost:8082/h/hello?name=Vasya
(/h
- 上下文路径)时 - 请求成功发生,我在响应中看到 Hello Vasya
消息。 我需要说明该服务已禁用身份验证。
hello world service
有 index.html
页面,当我尝试访问它时 - 身份验证流程成功发生,最终此应用程序成功登录。然后我尝试从hello world service
执行方法/hello
并看到响应:
"timestamp":"2018-05-17T08:53:04.623+0000","status":403,"error":"Forbidden","message":"Forbidden","path":"/hw/helloWorld"
Oauth2 配置:
你好世界服务
@SpringBootApplication
@EnableEurekaClient
@RibbonClient(name = "say-hello")
@EnableAutoConfiguration
@EnableOAuth2Sso
public class HelloWorldStarter
public static void main(String[] args)
SpringApplication.run(HelloWorldStarter.class, args);
@RestController
@EnableDiscoveryClient
@EnableCircuitBreaker
public static class HelloWorldController
@Autowired
private RestTemplate restTemplate;
@Autowired
private DiscoveryClient discoveryClient;
@GetMapping("/helloWorld")
@HystrixCommand(fallbackMethod = "reliable")
public String hello()
return this.restTemplate.getForObject("http://hello-service/hello?name=World", String.class);
public String reliable()
return "Could not get response from service";
@org.springframework.context.annotation.Configuration
public static class Configuration
@Bean
@LoadBalanced
RestTemplate restTemplate()
return new RestTemplate();
application.yml:
spring:
application:
name: hello-world-service
server:
port: 8081
servlet:
context-path: /hw
eureka:
client:
serviceUrl:
defaultZone: http://localhost:8761/eureka
instance:
preferIpAddress: true
security:
oauth2:
client:
client-id: acme
client-secret: acmesecret
access-token-uri: http://localhost:8080/oauth/token
user-authorization-uri: http://localhost:8080/oauth/authorize
resource:
user-info-uri: http://localhost:8080/me
logging:
level:
org.springframework.security: DEBUG
org.springframework.web: DEBUG
问题
-
如何解决此问题?
在上一点修复之后,我想知道如何执行对该服务的授权请求。换句话说,我想在 hello 服务上启用 oauth 2 授权,并有可能从
hello world service
发出请求
【问题讨论】:
您是否尝试过使用OAuth2RestTemplate
而不是普通的RestTemplate
?在此处查看示例***.com/questions/27864295/…
【参考方案1】:
我认为您使用非常奇怪的方法来解决您的问题。
我建议你以下解决方案:
-
创建 FeignClient 服务。
@FeignClient(name = "hello-service", url = "http://hello-service")
public interface HelloService
@RequestMapping(method = RequestMethod.GET, value = "/hello")
String hello(@PathVariable("name") String name);
-
在 SpringBoot Application 类中添加 oauth2FeignRequestInterceptor
@Bean
public RequestInterceptor oauth2FeignRequestInterceptor()
return new RequestInterceptor()
@Override
public void apply(RequestTemplate requestTemplate)
OAuth2AuthenticationDetails details = (OAuth2AuthenticationDetails) SecurityContextHolder.getContext().getAuthentication().getDetails();
requestTemplate.header("Authorization", "bearer " + details.getTokenValue());
;
-
在 SpringBoot Application 类中添加几个注解
@EnableOAuth2Client
@EnableGlobalMethodSecurity(prePostEnabled = true)
@EnableFeignClients
public class HelloWorldStarter
希望对您有所帮助。
【讨论】:
所有与hello world服务应用相关的代码? 另外我不能说我需要 Feign。我现在对 restTemplate 很满意 是的,和hello world相关的服务代码应该放在HelloWorldStarter附近 restTemplate 内部没有任何身份验证逻辑,另一方面 oauth2FeignRequestInterceptor 包含它。 docs.spring.io/spring-security/oauth/apidocs/org/… 这个呢?以上是关于Spring Cloud 应用程序中具有 Forbidden 状态的微服务请求响应的主要内容,如果未能解决你的问题,请参考以下文章
如何允许 Spring Boot 应用程序使用具有 Spring Cloud 依赖关系的自定义 jar