【发布时间】:2022-01-18 07:19:06
【问题描述】:
我正在尝试实现将 Azure B2C 与 Spring Boot 的 Webflux Security 结合使用的能力。 虽然没有官方库可以实际执行此操作,但 someone at Microsoft 表示 Spring Security 5 的本机功能可以支持 Azure B2C。我已经关注了这个repository(虽然它不是基于 webflux 的)来了解如何实现这一点。 JWT 令牌通过应用程序的受众 UUID 进行验证。
一旦我尝试为请求实际提供 JWT 令牌,我会收到一个 HTTP 401 错误,指出 Authentication failed: Failed to validate the token。
问题是在示例存储库中,他们使用端点 https://login.microsoftonline.com/{tenantId}/v2.0 作为颁发者 url。
另一方面,从 B2C 返回的 JWT 令牌的发行者为 https://{tenantName}.b2clogin.com/{tenantId}/v2.0/。
如果我改用 issuer https://{tenantName}.b2clogin.com/{tenantId}/v2.0/,JWT 解码器将无法找到配置。
所以现在我觉得颁发者 URL 实际是什么不一致,这阻止了 Webflux 实际能够执行身份验证。
这是我的安全代码。
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.security.config.annotation.web.reactive.EnableWebFluxSecurity;
import org.springframework.security.config.web.server.ServerHttpSecurity;
import org.springframework.security.oauth2.core.DelegatingOAuth2TokenValidator;
import org.springframework.security.oauth2.core.OAuth2TokenValidator;
import org.springframework.security.oauth2.jwt.*;
import org.springframework.security.web.server.SecurityWebFilterChain;
@EnableWebFluxSecurity
public class SecurityConfiguration {
@Value("${spring.security.oauth2.resourceserver.jwt.issuer-uri}")
String issuerUri;
@Bean
public SecurityWebFilterChain springSecurityFilterChain(ServerHttpSecurity http)throws Exception {
return http.cors().and().csrf().disable()
.authorizeExchange()
.anyExchange()
.authenticated()
.and().oauth2ResourceServer().jwt().and().and().build();
}
@Bean
ReactiveJwtDecoder jwtDecoder() {
NimbusReactiveJwtDecoder jwtDecoder = (NimbusReactiveJwtDecoder) ReactiveJwtDecoders.fromIssuerLocation(issuerUri);
OAuth2TokenValidator<Jwt> audienceValidator = new AudienceValidator();
OAuth2TokenValidator<Jwt> withIssuer = JwtValidators.createDefaultWithIssuer(issuerUri);
OAuth2TokenValidator<Jwt> withAudience = new DelegatingOAuth2TokenValidator<>(withIssuer, audienceValidator);
jwtDecoder.setJwtValidator(withAudience);
return jwtDecoder;
}
}
观众验证器。
import org.springframework.security.oauth2.core.OAuth2Error;
import org.springframework.security.oauth2.core.OAuth2TokenValidator;
import org.springframework.security.oauth2.core.OAuth2TokenValidatorResult;
import org.springframework.security.oauth2.jwt.Jwt;
public class AudienceValidator implements OAuth2TokenValidator<Jwt> {
OAuth2Error error = new OAuth2Error("invalid_token", "The required audience is missing", null);
public OAuth2TokenValidatorResult validate(Jwt jwt) {
if (jwt.getAudience().contains("messaging")) {
return OAuth2TokenValidatorResult.success();
} else {
return OAuth2TokenValidatorResult.failure(error);
}
}
}
application.yml
spring:
security:
oauth2:
resourceserver:
jwt:
jwk-set-uri: https://login.microsoftonline.com/{tenantId}/discovery/v2.0/keys
issuer-uri: https://login.microsoftonline.com/{tenantId}/v2.0
audience: {audience-id}
所以,我有三个问题:
- 颁发者 URL 到底是怎么回事?
- 如何允许 Spring Security 5 响应式与 Azure B2C 一起使用?
- 我注意到 JWT 解码器在启动时只被调用一次。调用端点时不会调用它。为什么会这样?
【问题讨论】:
-
您是否尝试将
issuer-uri属性设置为b2clogin.comURL,但在@BeanReactiveJwtDecoder中使用login.microsoftonline.comURL? -
@SteveRiesenberg 在采用这种方法时,恐怕我会遇到同样的错误。我想知道我缺少什么细节?
-
您可以尝试启用调试日志记录,
logging.level.org.springframework.security=debug并提供日志。 -
@SteveRiesenberg 实际上,我有用于跟踪安全性的日志记录级别。但是,除了:
2021-12-17 22:15:18.062 DEBUG 97155 --- [r-http-kqueue-3] o.s.s.w.s.a.AuthenticationWebFilter : Authentication failed: Failed to validate the token之外,这并没有为我提供任何其他日志 -
{tenantId}来自哪里?在您引用的示例中,它是${tenant-id}(注意美元符号)。
标签: azure spring-security azure-ad-b2c spring-webflux spring-security-oauth2