Spring Security 5 客户端凭据授予与 azure 广告

Posted

技术标签:

【中文标题】Spring Security 5 客户端凭据授予与 azure 广告【英文标题】:Spring Security 5 client credenital grant with azure ad 【发布时间】:2021-10-25 03:39:12 【问题描述】:

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

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-*** 

Web客户端配置

@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 请求令牌?

【问题讨论】:

您好@user09,我可以提供此实现的完整示例吗?实际上,我也在使用 azure AD 和 spring security 实现相同的功能,但没有找到任何完整的示例,例如我们是否需要在控制器或某处添加注释。那么您能否通过让我知道在哪里可以找到完整实施示例的链接来帮助我? 【参考方案1】:

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

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

【讨论】:

以上是关于Spring Security 5 客户端凭据授予与 azure 广告的主要内容,如果未能解决你的问题,请参考以下文章

带有 spring-security 的 OAuth2 - 通过 HTTP 方法限制 REST 访问

Grails OAuth2 登录密码凭据授予返回 invalid_client

Spring OAuth2 - 客户端凭据授予类型中的用户信息

通过 Spring security ldap 对用户进行身份验证时未授予任何权限错误

Spring security oauth 2 和客户端凭据流

Spring Security OAuth 2.0 - 授权代码授予始终需要客户端密码