当前位置: 首页 > 知识库问答 >
问题:

使用spring网关和Oauth2配置客户端凭据流

鲜于德业
2023-03-14

我在我的客户端应用程序(我的Spring网关)中配置客户端凭据流时遇到了一些问题。

我的授权服务器功能正常,与邮递员一起测试,没有任何问题。

但在我的客户机应用程序中,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>

我的网络客户端的配置:

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]

非常感谢你的帮助。

共有1个答案

薄瑞
2023-03-14

将下面提到的类添加到Spring引导项目中。然后,它正常工作,没有上述问题。您需要为任何自定义安全类扩展"WebSecurityConfigrerAdapter"。

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("/**");

    }

}
 类似资料:
  • 顺便说一句,这些微服务只会通过中间件层互相交谈,我的意思是不需要用户凭据来允许授权(用户登录过程如Facebook)。 我在Internet上寻找了一些示例,展示了如何创建一个授权和资源服务器来管理这种通信。然而,我只是找到了一些例子,解释了如何使用用户凭据(三条腿)来实现它。 有没有人有在Spring Boot和Oauth2中如何做的样例?如果有可能提供更多关于所用范围的详细信息,令牌交换将不胜

  • 问题内容: 我正在尝试了解和实现新的REST服务器与现有的客户端应用程序之间的客户端凭证流。我已经像这样设置了spring-security OAuth2 。从到目前为止的理解来看,我的服务器现在应该支持以下请求: 但我明白了 由引起的是这里(弹簧安全码): 看来,我需要首先 针对服务器 进行 身份验证 。但这 不是我想做的 。我希望我的两个服务器使用共享密钥相互通信。OAuth提供者服务器应应请

  • 我试图使用spring OAuth2在Spring Boot服务中实现服务到服务的安全性。我希望一个服务访问另一个服务的安全资源,而不涉及任何用户操作。 我可以设置auth服务器并使用curl请求获取令牌。我发现的测试使用Http对象来检查状态代码。 如何在具有RestTemplate和spring OAuth2的java客户机中使用客户机凭据授权类型? 我想它一定像添加一个依赖项、一个注释和一个

  • 我试图实现一个简单的客户端凭证流spring-security-oauth2 api。我试图改编sparklr和tonr的例子,但没有成功。我也尝试按照这个线程的代码:Spring-2-leged(客户端凭证)OAuth2服务器的安全上下文设置,但它似乎不适合我。谁能给我举个例子,或者帮我做些什么来让这个工作。 spring servlet。Sparkr应用程序中的xml Spring式.xml在

  • 我开发Spring Cloud(使用Netflix OSS堆栈)微服务架构已经有一段时间了。正如您所料,我已经将授权服务器分离为一个独立的微服务。我的前端应用程序使用“密码”授权类型用于用户登录目的。但是,对于从前端服务到其他后端服务的rest调用,我使用的是“Client-Credentials”授权类型。客户机凭据授予类型也在其他后端服务中使用。通过这样做,我无法确定谁是请求的实际调用者(当前

  • 我有一个相当基本的Spring Boot设置,我已经安装了Spring Security,我已经成功地设置了OAuth2来保护我的API。 几天前,我遇到了一些麻烦,问(并回答)了一个关于达到endpoint的问题。我很快发现问题在于,我试图在请求的正文中发送客户机凭据,但令牌endpoint在Spring Security中被配置为通过HTTP Basic Auth接受客户机凭据(和)。 我使用