我正在尝试实现将 Azure B2C 与 Spring Boot 的 Webflux 安全性结合使用的功能。 虽然没有官方库可以真正做到这一点,但 someone at Microsoft 表示。 Spring Security 5 的 native 功能可以支持 Azure B2C。我已经关注了这个repository (尽管它不是基于 webflux 的)来了解如何实现这一点。 JWT token 通过应用程序的受众 UUID 进行验证。
一旦我尝试实际向请求提供 JWT token ,就会收到 HTTP 401 错误,指出身份验证失败:无法验证 token
。
问题是,在示例存储库中,他们使用端点 https://login.microsoftonline.com/{tenantId}/v2.0
作为颁发者 URL。
另一方面,从 B2C 返回的 JWT token 具有颁发者 https://{tenantName}.b2clogin.com/{tenantId}/v2.0/
。
如果我使用颁发者 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);
}
}
}
应用程序.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}
所以,我有三个问题:
- 发行人网址到底发生了什么?
- 如何允许 Spring Security 5 响应式与 Azure B2C 配合使用?
- 我注意到 JWT Decoder 在启动时仅被调用一次。当端点被调用时它不会被调用。为什么会这样?
最佳答案
颁发者 URL https://login.microsoftonline.com/{tenantId}/v2.0
用于 Azure AD。
由于 Azure B2C 依赖于定义的配置文件,因此您必须使用https://{tenantName}.b2clogin.com/tfp/{tenantId}/{profileName}/v2.0/
作为发行人 URL。
虽然 https://{tenantName}.b2clogin.com/{tenantId}/{profileName}/v2.0/
也是有效的颁发者,Spring Security 会提示颁发者 URL 不一致由于发行人实际上是 https://{tenantName}.b2clogin.com/{tenantId}/v2.0/
。
Azure B2C 似乎没有一般发行者,也没有包含所有 key 的 JWK 列表。
关于azure - WebFlux : Can't authenticate JWT token from Azure B2C,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/70358027/