使用 spring gateway 和 Oauth2 配置 Client Credentials Flow
Posted
技术标签:
【中文标题】使用 spring gateway 和 Oauth2 配置 Client Credentials Flow【英文标题】:Configure Client Credentials Flow with spring gateway and Oauth2 【发布时间】:2020-03-27 02:31:47 【问题描述】:我的客户端应用程序(我的 Spring 网关)中的客户端凭据流配置存在一些问题。
我的授权服务器功能正常,使用 Postman 进行测试没有任何问题。
但在我的客户端应用程序中,似乎 oauth2 配置被破坏而没有编译错误。
当我在我的服务器资源上调用一个受保护的资源时,我的客户端应用程序似乎试图在其基础而不是授权服务器中调用一个 URL。
查看代码 我的配置文件:
security:
oauth2:
client:
registration:
apigateway:
provider: apigateway
client-id: apigateway
client-secret: password
scope: generate_token,read,write
authorization-grant-type: client_credentials
redirect-uri: "baseUrl/login/oauth2/code/registrationId"
provider:
apigateway:
token-uri: https://localhost:9001/oauth/token
我的客户依赖:
<dependencies>
<!-- ************ SPRING DEPENDENCIES ************ -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-gateway</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
<exclusions>
<exclusion>
<groupId>org.junit.vintage</groupId>
<artifactId>junit-vintage-engine</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-oauth2-client</artifactId>
<version>5.2.1.RELEASE</version>
</dependency>
</dependencies>
我的 WebClient 的配置:
public class WebClientSecurityCustomizer implements WebClientCustomizer
private ServerOAuth2AuthorizedClientExchangeFilterFunction securityExchangeFilterFunction;
public WebClientSecurityCustomizer(
ServerOAuth2AuthorizedClientExchangeFilterFunction securityExchangeFilterFunction)
this.securityExchangeFilterFunction = securityExchangeFilterFunction;
@Override
public void customize(WebClient.Builder webClientBuilder)
SslProvider sslProvider = SslProvider.builder().sslContext(
SslContextBuilder.forClient().trustManager(InsecureTrustManagerFactory.INSTANCE)
)
.defaultConfiguration(SslProvider.DefaultConfigurationType.NONE).build();
TcpClient tcpClient = TcpClient.create().secure(sslProvider);
HttpClient httpClient = HttpClient.from(tcpClient);
ClientHttpConnector httpConnector = new ReactorClientHttpConnector(httpClient);
webClientBuilder.clientConnector(httpConnector);
webClientBuilder.filters((filterFunctions) ->
if (!filterFunctions.contains(this.securityExchangeFilterFunction))
filterFunctions.add(0, this.securityExchangeFilterFunction);
);
@Configuration
public class WebClientSecurityConfiguration
@Bean
public WebClientSecurityCustomizer webClientSecurityCustomizer(
ReactiveClientRegistrationRepository clientRegistrations)
// Provides support for an unauthenticated user such as an application
ServerOAuth2AuthorizedClientExchangeFilterFunction oauth = new ServerOAuth2AuthorizedClientExchangeFilterFunction(
clientRegistrations, new UnAuthenticatedServerOAuth2AuthorizedClientRepository());
// Build up a new WebClientCustomizer implementation to inject the oauth filter
// function into the WebClient.Builder instance
return new WebClientSecurityCustomizer(oauth);
/**
* Helper function to include the Spring CLIENT_REGISTRATION_ID_ATTR_NAME in a
* properties Map
*
* @param provider - OAuth2 authorization provider name
* @return consumer properties Map
*/
public static Consumer<Map<String, Object>> getExchangeFilterWith(String provider)
return ServerOAuth2AuthorizedClientExchangeFilterFunction.clientRegistrationId(provider);
我的资源调用者:
return webClientBuilder.build().get().uri(uri+"accessToken", accessToken)
.attributes(
WebClientSecurityConfiguration.getExchangeFilterWith("apigateway"))
.retrieve()
.bodyToMono(String.class)
.flatMap(response ->
ServerHttpRequest request = exchange.getRequest().mutate()
.header(jwtHeader, String.format("%s %s", jwtPrefix, response))
.build();
return chain.filter(exchange.mutate().request(request).build());
);
最后,客户端应用程序中生成的错误(似乎授权和资源服务没有收到请求):
2019-12-02 13:53:50.543 ERROR 11492 --- [ctor-http-nio-2] a.w.r.e.AbstractErrorWebExceptionHandler : [405f3f3c] 500 Server Error for HTTP GET "/oauth2/authorization/apigateway"
java.lang.IllegalArgumentException: Invalid Authorization Grant Type (client_credentials) for Client Registration with Id: apigateway
at org.springframework.security.oauth2.client.web.server.DefaultServerOAuth2AuthorizationRequestResolver.authorizationRequest(DefaultServerOAuth2AuthorizationRequestResolver.java:156) ~[spring-security-oauth2-client-5.2.1.RELEASE.jar:5.2.1.RELEASE]
非常感谢您的帮助。
【问题讨论】:
你解决了吗?我也面临同样的问题。 您好,Zia 女士,不,抱歉。在这篇文章之后,我们找到了 Spring Security 团队的一篇博文,解释他们正在放弃授权服务器。所以我们决定换一个具体的解决方案。 【参考方案1】:将下面提到的类添加到您的 Spring Boot 项目中。然后,它可以正常工作而不会出现上述问题。 您需要为任何自定义安全类扩展“WebSecurityConfigurerAdapter”。
import org.springframework.security.config.annotation.web.builders.WebSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
@EnableWebSecurity
public class SecurityConfiguration extends WebSecurityConfigurerAdapter
@Override
public void configure(WebSecurity web) throws Exception
web.ignoring()
.antMatchers("/**");
【讨论】:
以上是关于使用 spring gateway 和 Oauth2 配置 Client Credentials Flow的主要内容,如果未能解决你的问题,请参考以下文章
Spring Gateway OAuth - 重定向的完整 URL
Spring Cloud Gateway OAuth2 with Spring Security OAuth2 Authorization Server = loop
调用spring oauth2授权服务器时Spring Cloud Gateway卡住