Azure 설명서는 올바르게 작동하도록 명확한 예를 제공 할 수 있습니다.Angular4 및 WebAPI Core2 토큰 유효성 검사 문제가있는 Azure AD B2C
Azure B2C에서 구성한 Angular4 (WebApp) 및 WebAPI Core 2.0 백엔드가 있습니다. 두 개의 애플리케이션이 구성되었습니다. WebApp는 API 액세스에 WebAPI 앱을 보유하고 있습니다.
웹 응용 프로그램은 https://login.microsoftonline.com/ {tenant} /oauth2/v2.0/authorize로 리디렉션됩니다. 여기에 자격 증명이 제공된 다음 AAD B2C는 access_token, token_type, expires_in, id_token URL 매개 변수로 웹 애플리케이션 페이지를 다시 호출합니다.
그런 다음 WebApp는 Authorization 헤더의 access_token을 사용하여 백엔드의 보호 된 끝점에 요청합니다. MessageReceivedAsync는 요청이 백엔드에 도달 할 때 호출되며 토큰 유효성 검사를 통해 진행됩니다.
그러나 프로세스가 다음 단계의 메소드를 종료하면 오류로 AuthenticationFailed가됩니다.
"IDX10501: Signature validation failed. Unable to match 'kid': 'Base64_kid',
token: '{"alg":"RS256","typ":"JWT","kid":"Base64_kid"}.{"iss":"number of claims"}'."
잠재 고객은 WebAPI 애플리케이션 ID임을 이해합니다. 나는 SingIn/Up 정책 만 가지고있다.
오류가없는 jwt 수동 검증을 완료하려면 여기에 무엇이 누락 되었습니까? 또 다른 질문은 claimPrincipal이 토큰 유효성 검사를 할 때 만들어지면 보호 된 끝점에 액세스 할 수 있도록 요청 컨텍스트로 어떻게 이동합니까?
public IServiceProvider ConfigureServices(IServiceCollection services)
{
services.AddCors();
services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
.AddJwtBearer(options =>
{
options.SaveToken = true;
options.RequireHttpsMetadata = false;
options.Authority = string.Format("https://login.microsoftonline.com/{0}/v2.0/",
Configuration["Authentication:AzureAd:ida:Tenant"], Configuration["Authentication:AzureAd:ida:Policy"]);
options.Audience = Configuration["Authentication:AzureAd:ida:ClientId"];
options.Events = new JwtBearerEvents
{
OnAuthenticationFailed = AuthenticationFailed,
OnMessageReceived = MessageReceivedAsync,
OnChallenge = Challenge,
OnTokenValidated = TokenValidated
};
});
...
}
private Task MessageReceivedAsync(MessageReceivedContext arg)
{
string jwtToken = null;
var aadInstance = Configuration["Authentication:AzureAd:ida:AADInstance"];
var tenant = Configuration["Authentication:AzureAd:ida:Tenant"];
var audience = Configuration["Authentication:AzureAd:ida:Audience"];
var policy = Configuration["Authentication:AzureAd:ida:Policy"];
var authority = String.Format(CultureInfo.InvariantCulture, aadInstance, tenant);
string _issuer = string.Empty;
List<SecurityKey> _signingTokens = null;
var authHeader = arg.HttpContext.Request.Headers["Authorization"];
// 7 = (Bearer + " ").Length
var token = authHeader.ToString().Substring(7);
try
{
string stsDiscoveryEndpoint = string.Format("{0}/v2.0/.well-known/openid-configuration?p={1}", authority, policy);
var configManager = new ConfigurationManager<OpenIdConnectConfiguration>(stsDiscoveryEndpoint,
new OpenIdConnectConfigurationRetriever());
OpenIdConnectConfiguration config = null;
var openIdConfigTask = Task.Run(async() => {
config = await configManager.GetConfigurationAsync();
});
openIdConfigTask.Wait();
_issuer = config.Issuer;
_signingTokens = config.SigningKeys.ToList();
}
catch(Exception ex)
{
...
}
var tokenHandler = new JwtSecurityTokenHandler();
var validationParameters = new TokenValidationParameters
{
ValidAudience = audience,
ValidIssuer = _issuer,
IssuerSigningKeys = _signingTokens
};
var claimsPrincipal = tokenHandler.ValidateToken(token, validationParameters, out var validatedToken);
//Thread.CurrentPrincipal = claimsPrincipal; ?
//var ticket = new AuthenticationTicket(claimsPrincipal, arg.Scheme.Name); ?
//arg.HttpContext.User = claimsPrincipal; ?
return Task.FromResult(0);
}
동일한 문제가있었습니다. 'MetadataAddress' 속성을 수동으로 설정해야했습니다. 중복을 참조하십시오 이유와 [this code sample] (https://github.com/spottedmahn/NetCoreAngularAzureB2CMsal/blob/b543ccbedbb4a83e1809351b38cb34afc4f02c62/StartupAuth.cs#L24) – spottedmahn
두 옵션 모두 작동했습니다. – Maxim