标签: spring-cloud

Spring OAuth:具有授权服务器后端的资源服务器

我想开发两个独立的服务,一个用于业务,一个用于使用Spring OAuth 2进行用户身份验证

我们称之为商业服务和OAuth服务.

现在,如果请求未经过身份验证,我希望将Business-Service委托给OAuth-Service.客户端应用程序(Android应用程序)不应该事先知道OAuth-Service,它应该只由Business-Service委托给它,并且302 HTTP重定向用于非认证请求.确切地说,我希望我的API登录页面提供指向http://businessservice.com/login的链接,当我的客户端应用程序决定关注此链接时,它会被重定向到OAuth-Service.

如果我使用@ EnableOAuth2Resource注释Business-Service ,那么当我在没有访问令牌的情况下卷曲它时,它的所有资源都会受到保护,返回401.到现在为止还挺好.如果我提供这样的访问令牌:

curl -v http://localhost:8667/resource/ -H "Authorization: Bearer $TOKEN"
Run Code Online (Sandbox Code Playgroud)

我可以访问该资源.还好.

但是,如果我使用@ EnableOAuth2Sso注释业务服务以启用重定向到OAuth服务,则会失去使用访问令牌访问资源的功能(与上面相同的卷曲),它只返回302到登录页面http: //本地主机:8667 /登录

如果我同时使用两个注释,@ EnableOAuth2Resource似乎总是"赢",因为身份验证有效,但调用http:// localhost:8667/login返回404.

那么创建一个委托给auth服务器进行非认证调用的资源服务器的正确方法是什么?

spring-security oauth-2.0 spring-security-oauth2 spring-cloud

9
推荐指数
1
解决办法
5756
查看次数

如何覆盖Spring Cloud OAuth2客户端自动配置?

我们想要设置一个提供REST API的微服务,以便将其配置为OAuth2资源服务器.此服务还应充当具有客户端凭据授权的OAuth2客户端.这是配置:

spring.oauth2.client.id=clientCredentialsResource
spring.oauth2.client.accessTokenUri=http://localhost:9003/oauth/token
spring.oauth2.client.userAuthorizationUri=http://localhost:9003/oauth/authorize
spring.oauth2.client.grantType=client_credentials
spring.oauth2.client.clientId=<service-id>
spring.oauth2.client.clientSecret=<service-pw>
Run Code Online (Sandbox Code Playgroud)

资源服务器部分工作正常.对于客户端部分,我们要使用Feign,Ribbon和Eureka:

@FeignClient("user")
public interface UserClient
{
  @RequestMapping( method = RequestMethod.GET, value = "/user/{uid}")
  Map<String, String> getUser(@PathVariable("uid") String uid);
}
Run Code Online (Sandbox Code Playgroud)

基于问题的主旨https://github.com/spring-cloud/spring-cloud-security/issues/56我创建了一个假装请求拦截器,它在假装请求头中设置自动装配的OAuth2RestOperations模板中的访问令牌

@Autowired
private OAuth2RestOperations restTemplate; 

template.header(headerName, String.format("%s %s", tokenTypeName, restTemplate.getAccessToken().toString()));
Run Code Online (Sandbox Code Playgroud)

但这给了我调用用户服务的错误:

error="access_denied", error_description="Unable to obtain a new access token for resource 'clientCredentialsResource'. The provider manager is not configured to support it.
Run Code Online (Sandbox Code Playgroud)

正如我所看到的,OAuth2ClientAutoConfiguration始终为Web应用程序创建AuthorizationCodeResourceDetails实例,但不创建仅用于非Web应用程序的必需ClientCredentialsResourceDetails.最后,no access token privider负责资源详细信息并且调用失败

AccessTokenProviderChain.obtainNewAccessTokenInternal(AccessTokenProviderChain.java:146) 
Run Code Online (Sandbox Code Playgroud)

我试图覆盖自动配置但失败了.有人可以给我一个提示怎么做?

spring spring-security spring-boot spring-security-oauth2 spring-cloud

9
推荐指数
1
解决办法
8741
查看次数

AWS Instance Profile不适用于Spring Cloud AWS

我有一个小的Spring Boot应用程序,使用Spring Cloud AWS(1.0.0.RELEASE)来访问SQS队列.它部署在具有实例配置文件集的EC2实例上.似乎AWS的一面正在发挥作用,因为我可以访问两个相关的元数据链接:iam/info并且iam/security-credentials/role-name,它们确实包含正确的信息.只是为了确定,我已经使用了aws cmdline实用程序(aws sqs list-queues)并且确实有效,所以我猜设置正常.但是,当应用程序启动时,它会读取application.properties(包含行cloud.aws.credentials.instanceProfile=true),然后在警告后丢弃:com.amazonaws.util.EC2MetadataUtils: Unable to retrieve the requested metadata最后抛出以下异常:

Caused by: com.amazonaws.AmazonServiceException: The security token included in the request is invalid. (Service: AmazonSQS; Status Code: 403; Error Code: InvalidClientTokenId; Request ID: xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx)
        at com.amazonaws.http.AmazonHttpClient.handleErrorResponse(AmazonHttpClient.java:1071)
        at com.amazonaws.http.AmazonHttpClient.executeOneRequest(AmazonHttpClient.java:719)
        at com.amazonaws.http.AmazonHttpClient.executeHelper(AmazonHttpClient.java:454)
        at com.amazonaws.http.AmazonHttpClient.execute(AmazonHttpClient.java:294)
        at com.amazonaws.services.sqs.AmazonSQSClient.invoke(AmazonSQSClient.java:2291)
        at com.amazonaws.services.sqs.AmazonSQSClient.getQueueUrl(AmazonSQSClient.java:516)
        at com.amazonaws.services.sqs.buffered.AmazonSQSBufferedAsyncClient.getQueueUrl(AmazonSQSBufferedAsyncClient.java:278)
        at org.springframework.cloud.aws.messaging.support.destination.DynamicQueueUrlDestinationResolver.resolveDestination(DynamicQueueUrlDestinationResolver.java:78)
        at org.springframework.cloud.aws.messaging.support.destination.DynamicQueueUrlDestinationResolver.resolveDestination(DynamicQueueUrlDestinationResolver.java:37)
        at org.springframework.messaging.core.CachingDestinationResolverProxy.resolveDestination(CachingDestinationResolverProxy.java:88)
        at org.springframework.cloud.aws.messaging.listener.AbstractMessageListenerContainer.start(AbstractMessageListenerContainer.java:295)
        at org.springframework.cloud.aws.messaging.listener.SimpleMessageListenerContainer.start(SimpleMessageListenerContainer.java:38)
        at org.springframework.context.support.DefaultLifecycleProcessor.doStart(DefaultLifecycleProcessor.java:173)
        ... 17 common frames omitted
Run Code Online (Sandbox Code Playgroud)

...这意味着由于某种原因,Spring …

java amazon-web-services spring-boot spring-cloud

9
推荐指数
1
解决办法
4580
查看次数

为什么Eureka DS Replicas Links不起作用?

为什么DS副本不能在Spring gui中运行?当您点击链接时,他们会尝试访问http:// hostname:8761/eureka /.该链接不应指向http:// hostname:8761 /

Eureka GUI

spring-cloud

9
推荐指数
1
解决办法
4330
查看次数

具有Spring Session/Redis的Spring Zuul API网关在同一请求中进行身份验证和路由

过去几天我一直在寻找如何做到这一点的最高点和最低点,并最终决定承认失败并请求帮助,拜托!

我跟随Dave Syer博士关于Angular和Spring Security的教程,特别是Zuul代理作为api网关,并使用Red Session的Spring Session(https://github.com/spring-guides/tut-spring-security-and-angular-js/tree/master/double#_sso_with_oauth2_angular_js_and_spring_security_part_v)

我遇到的问题是我通过网关从具有以下标头的外部应用程序调用资源休息服务:

String plainCreds = "user:password";
byte[] plainCredsBytes = plainCreds.getBytes();
byte[] base64CredsBytes = Base64.getEncoder().encode(plainCredsBytes);
String base64Creds = new String(base64CredsBytes);

HttpHeaders headers = new HttpHeaders();
headers.add("Authorization", "Basic " + base64Creds);
Run Code Online (Sandbox Code Playgroud)

要经过身份验证然后由zuul路由,然后通过redis访问资源以访问经过身份验证的会话.

问题是会话似乎只在请求响应后才在网关中提交redis.所以发生的事情是,当我使用标头调用资源服务时,我可以看到在网关和会话中发生了成功的身份验证,但是由于会话之后没有处于redis状态,因此我在资源中获得了403通过zuul路由.

但是,如果我收到错误,请获取会话ID并将其添加到标头并再次尝试,因为现在我的身份验证会话在路由后可用于资源项目.

请有人指出我如何通过网关接听我的电话进行身份验证并在同一请求中路由吗?

谢谢贾斯汀

spring-security spring-session spring-cloud

9
推荐指数
1
解决办法
8270
查看次数

Zuul/Ribbon/Hystrix没有在不同的实例上重试

背景

我正在使用Spring云Brixton.RC2,与Zuul和Eureka一起使用.

我有一个网关服务@EnableZuulProxybook-service一个status方法.通过配置,我可以status通过休眠一段规定的时间来模拟方法的工作.

Zuul路线很简单

zuul.routes.foos.path=/foos/**
zuul.routes.foos.serviceId=reservation-service
Run Code Online (Sandbox Code Playgroud)

我运行了两个实例book-service.当我将休眠时间设置为低于Hystrix超时阈值(1000毫秒)时,我可以看到请求同时发送到图书服务的两个实例.这很好用.

问题

据我所知,如果Hystrix命令失败,Ribbon应该可以在另一台服务器上重试该命令.这应该使故障对客户端透明.

我阅读了Ribbon配置并在Zuul中添加了以下配置:

zuul.routes.reservation-service.retryable=true //not sure which one to try
zuul.routes.foos.retryable=true //not sure which one to try

ribbon.MaxAutoRetries=0 // I don't want to retry on the same host, I also tried with 1 it doesn't work either
ribbon.MaxAutoRetriesNextServer=2
ribbon.OkToRetryOnAllOperations=true
Run Code Online (Sandbox Code Playgroud)

现在我更新配置,以便只有一个服务睡眠时间超过1秒,这意味着我有一个健康服务,一个健康服务.

当我调用网关时,调用会发送到两个实例,一半调用返回500.在网关中,我看到Hystrix超时:

com.netflix.zuul.exception.ZuulException: Forwarding error
    [...]
Caused by: com.netflix.hystrix.exception.HystrixRuntimeException: reservation-service timed-out and no fallback available.
    [...]
Caused by: java.util.concurrent.TimeoutException: null
Run Code Online (Sandbox Code Playgroud)

为什么Ribbon不会在另一个实例上重试调用?

我在这里想念什么吗?


参考

  • 与此 …

hystrix spring-cloud netflix-zuul netflix-ribbon spring-cloud-netflix

9
推荐指数
1
解决办法
3278
查看次数

Spring Cloud Config Server环境变量的优先级

在使用spring cloud配置服务器时,我对环境变量的优先级有疑问

在我的服务中,我有一个application.yml包含此内容的本地属性文件

foo:
  bar: "some"
  buz: "some"
  joe: "some"
Run Code Online (Sandbox Code Playgroud)

该服务还连接到配置服务器,配置存储库包含一个文件testservice-api.yml(其中testservice-api是服务的spring应用程序名称).该文件的内容是:

foo:
  bar: "some-specific"
Run Code Online (Sandbox Code Playgroud)

因此,使用此设置,运行时的配置将导致:

{
    "foo.bar": "some-specific",
    "foo.buz": "some",
    "foo.joe": "some"
}
Run Code Online (Sandbox Code Playgroud)

现在我尝试覆盖foo.barfoo.joe使用环境变量.

所以我用这个命令启动服务:

FOO_BAR=some-env FOO_JOE=some-env gradle bootRun

从我在spring boot文档这一部分中读到的内容,环境变量应优先于配置文件 - spring cloud配置文档也没有说明不同 - 所以我希望结果如下:

{
    "foo.bar": "some-env",
    "foo.buz": "some",
    "foo.joe": "some-env"
}
Run Code Online (Sandbox Code Playgroud)

但相反,我得到:

{
    "foo.bar": "some-specific",
    "foo.buz": "some",
    "foo.joe": "some-env"
}
Run Code Online (Sandbox Code Playgroud)

因此,只有来自jar内部的本地配置文件的配置被环境变量覆盖 - 来自config repo的属性似乎优先于环境变量.

这是可以解释的 - 或者这是一个错误?这一个有什么提示吗?

请在此处找到示例代码:

https://github.com/mduesterhoeft/configserver-test …

java spring spring-boot spring-cloud spring-cloud-config

9
推荐指数
1
解决办法
5321
查看次数

将 Spring Cloud Sleuth 中的 traceId 添加到响应中

我目前正在我们的项目中实施 Spring Cloud Sleuth。我需要将 traceId 添加到响应标头中。有没有办法做到这一点?

谢谢,
阿努普

spring-cloud spring-cloud-sleuth

9
推荐指数
4
解决办法
2万
查看次数

如何从Spring Cloud Config Server读取多个配置文件

Spring云配置服务器支持使用名称读取属性文件${spring.application.name}.properties.但是我的应用程序中有2个属性文件.

a.properties
b.properties
Run Code Online (Sandbox Code Playgroud)

我可以让配置服务器读取这两个属性文件吗?

spring-cloud spring-cloud-config

9
推荐指数
3
解决办法
5669
查看次数

SpringCloud 2020.0.2升级产生测试错误

我正在尝试将项目从 SpringCloud BOM 升级2020.0.12020.0.2

当我更改 BOM 并重新构建时,我在 JUnit 测试中收到一个错误,说spring.config.import没有为 configserver 设置新参数。

这个项目不是ConfigServer,也没有使用ConfigServer(评论配置客户端)

这是测试中报告的错误 contextLoads()

java.lang.IllegalStateException: Failed to load ApplicationContext
    at org.springframework.test.context.cache.DefaultCacheAwareContextLoaderDelegate.loadContext(DefaultCacheAwareContextLoaderDelegate.java:132)
    at org.springframework.test.context.support.DefaultTestContext.getApplicationContext(DefaultTestContext.java:124)
    at org.springframework.test.context.support.DependencyInjectionTestExecutionListener.injectDependencies(DependencyInjectionTestExecutionListener.java:118)
    .. Many more
Caused by: org.springframework.cloud.config.client.ConfigServerConfigDataMissingEnvironmentPostProcessor$ImportException: No spring.config.import set
    at org.springframework.cloud.config.client.ConfigServerConfigDataMissingEnvironmentPostProcessor.postProcessEnvironment(ConfigServerConfigDataMissingEnvironmentPostProcessor.java:60)
    at org.springframework.boot.env.EnvironmentPostProcessorApplicationListener.onApplicationEnvironmentPreparedEvent(EnvironmentPostProcessorApplicationListener.java:100)
    at org.springframework.boot.env.EnvironmentPostProcessorApplicationListener.onApplicationEvent(EnvironmentPostProcessorApplicationListener.java:86)
    ... Many more
Run Code Online (Sandbox Code Playgroud)

这是我的 build.gradle

plugins {
    id 'org.springframework.boot' version '2.4.2'
    id 'io.spring.dependency-management' version '1.0.11.RELEASE'
    id 'java'
}

group = 'com.example.microservices.composite.product'
version = '1.0.0-SNAPSHOT'
sourceCompatibility = '1.8'

repositories {
    mavenCentral()
    maven {
        url 'https://repo.spring.io/milestone'
    } …
Run Code Online (Sandbox Code Playgroud)

spring spring-test spring-boot spring-cloud

9
推荐指数
3
解决办法
8799
查看次数