0

我有 spring boot 服务 A 使用 spring security server config 保护

spring:
    security:
      oauth2:
        resourceserver:
          jwt:
            issuer-uri: https://sts.windows.net/****-azure-tenant-id-***/
        client:
          provider:
            azure-ad:
              issuer-uri: https://sts.windows.net/****-azure-tenant-id-***/
audience-id: ****-resource-id-**** 

安全配置

@EnableWebFluxSecurity
@EnableReactiveMethodSecurity
public class WebSecurityConfiguration {

    @Value("${audience-id}")
    private String audience;

    @Value("${spring.security.oauth2.client.provider.azure-ad.issuer-uri}")
    private String issuer;

    @Autowired
    ReactiveJwtDecoder jwtDecoder;

    @Bean
    @Order(10)
    public SecurityWebFilterChain oAuth2SecurityWebFilter(ServerHttpSecurity http) {
        return http
                .securityMatcher(new PathPatternParserServerWebExchangeMatcher("/**"))
                .anyExchange().authenticated()
                .and()
                .oauth2ResourceServer()
                .jwt()
                .jwtDecoder(jwtDecoder)
                .and()
                .and()
                .build();
    }

    @Bean
    public ReactiveJwtDecoder reactiveJwtDecoder() {
        OAuth2TokenValidator<Jwt> withIssuer = JwtValidators.createDefaultWithIssuer(issuer);
        OAuth2TokenValidator<Jwt> withAudience = new DelegatingOAuth2TokenValidator<>(withIssuer, new AudienceValidator(audience));

        NimbusReactiveJwtDecoder reactiveJwtDecoder = (NimbusReactiveJwtDecoder) ReactiveJwtDecoders.fromIssuerLocation(issuer);
        reactiveJwtDecoder.setJwtValidator(withAudience);
        return reactiveJwtDecoder;
    }
}

所以这个应用程序是安全的,需要一个带有资源 ID 的不记名令牌****-resource-id-****来访问 API。

我有另一个服务 B 与此服务 A 对话并授予客户凭证

spring:
   security:
      oauth2:
        client:
          provider:
            azure-ad:
              token-uri: https://login.microsoftonline.com/***-tenant-id-**/oauth2/token
          registration:
            azure-ad:
              authorization-grant-type: client_credentials
              client-id: ****-resource-id-****
              client-secret: ****-client-seret-*** 

网页客户端配置

@Configuration
public class WebClientConfiguration {
    @Bean
    WebClient webClient(ReactiveClientRegistrationRepository clientRegistrationRepository) {
        ServerOAuth2AuthorizedClientExchangeFilterFunction oauth = new ServerOAuth2AuthorizedClientExchangeFilterFunction(clientRegistrationRepository, new UnAuthenticatedServerOAuth2AuthorizedClientRepository());
        oauth.setDefaultClientRegistrationId("azure-ad");
        return WebClient.builder().filter(oauth).build();
    }
}

当通过自动装配 webclient 调用从服务 B 到服务 A 时,webclient 正在发送一个承载令牌,但该承载不用于服务 A 的资源 ID,并且由于 403 被禁止而失败。如何配置 webclient 以请求服务 A 的资源 ID 的令牌?

4

1 回答 1

0

使用客户端凭据(共享密钥或证书)的服务到服务调用

Azure AD 还允许调用服务使用证书(而不是共享机密)作为凭据

带有证书的访问令牌请求

HTTP POST 请求带有证书的https://service.contoso.com/ Web 服务的访问令牌。client_id 标识请求访问令牌的 Web 服务。

POST /contoso.com/oauth2/token HTTP/1.1
Host: login.microsoftonline.com
Content-Type: application/x-www-form-urlencoded

grant_type=client_credentials&client_id=625bc9f6-3bf6-4b6d-94ba-e97cf07a22de&client_secret=qkDwDJlDfig2IpeuUZYKH1Wb8q1V0ju6sILxQQqhJ+s=&resource=https%3A%2F%2Fservice.contoso.com%2F

参考使用访问令牌访问受保护的资源和访问令牌请求与共享密钥

https://docs.microsoft.com/en-us/azure/active-directory/azuread-dev/v1-oauth2-client-creds-grant-flow

于 2021-08-25T05:57:13.537 回答