从 netcore upgrade 1.0.0 升级到 1.1.0 后 Azure 身份验证失败
Azure authentication fails after upgrade from netcore upgrade 1.0.0 to 1.1.0
将我的项目升级到 1.1.0 后,我现在遇到了针对我的 azure AD 开放 ID 身份验证的身份验证错误。
Fiddler 将错误显示为:
WWW-Authenticate: Bearer error="invalid_request", error_codes="[90010]", error_description="AADSTS90010: JWT 令牌不能与 UserInfo 端点一起使用。% 0d%0aTrace。
这与 400 错误 BadRequest 相关,用户无法登录。
app.UseOpenIdConnectAuthentication(new OpenIdConnectOptions
{
AutomaticAuthenticate = true,
AutomaticChallenge = true,
ClientId = Configuration["Authentication:AzureAd:ClientId"],
Authority = Configuration["Authentication:AzureAd:AADInstance"] + Configuration["Authentication:AzureAd:TenantId"],
ClientSecret = Configuration["Authentication:AzureAd:ClientSecret"],
CallbackPath = Configuration["Authentication:AzureAd:CallbackPath"],
ResponseType = OpenIdConnectResponseType.CodeIdToken,
GetClaimsFromUserInfoEndpoint = true,
Events = new OpenIdConnectEvents
{
OnAuthenticationFailed = OnAuthenticationFailed,
OnAuthorizationCodeReceived = OnAuthorizationCodeReceived,
OnMessageReceived = OnMessageReceived,
OnTicketReceived = OnTicketRecieved,
OnTokenValidated = OnTokenValidated,
OnUserInformationReceived = OnUserInformationReceived,
OnTokenResponseReceived = OnTokenResponseRecieved,
OnRemoteFailure = OnRemoteFailure
}
private async Task OnAuthorizationCodeReceived(AuthorizationCodeReceivedContext context)
{
var aadInstance = "https://login.microsoftonline.com/";
var graphResourceId = "https://graph.windows.net";
string userObjectId = (context.Ticket.Principal.FindFirst("http://schemas.microsoft.com/identity/claims/objectidentifier"))?.Value;
ClientCredential clientCred = new ClientCredential(clientId, clientSecret);
AuthenticationContext authContext = new AuthenticationContext(aadInstance + tenant);
AuthenticationResult authResult = await authContext.AcquireTokenByAuthorizationCodeAsync(
context.ProtocolMessage.Code, new Uri(context.Properties.Items[OpenIdConnectDefaults.RedirectUriForCodePropertiesKey]), clientCred, graphResourceId);
context.HandleCodeRedemption(authResult.AccessToken, authResult.IdToken);
}
由于我正在使用 CodeIdToken 并尝试使用 GetClaimsFromuserInfoEndpoint 选项,我现在是否需要以不同方式处理用户声明?
编辑:如果我注释掉 GetClaimsFromUserInfoEndpoint 这很好用
您还有其他自定义代码吗?它对我来说效果很好,这里是供您参考的代码:
app.UseOpenIdConnectAuthentication(new OpenIdConnectOptions
{
AutomaticAuthenticate = true,
AutomaticChallenge = true,
ClientId = Configuration["AzureAD:ClientId"],
Authority = String.Format(Configuration["AzureAd:AadInstance"], Configuration["AzureAd:Tenant"]),
ClientSecret = Configuration["AzureAd:ClientSecret"],
CallbackPath = new PathString("/signin-oidc"),
ResponseType = OpenIdConnectResponseType.CodeIdToken,
GetClaimsFromUserInfoEndpoint = true,
Events = new OpenIdConnectEvents
{
OnAuthenticationFailed = OnAuthenticationFailed,
OnAuthorizationCodeReceived = OnAuthorizationCodeReceived,
OnMessageReceived = OnMessageReceived,
OnTicketReceived = OnTicketRecieved,
OnTokenValidated = OnTokenValidated,
OnUserInformationReceived = OnUserInformationReceived,
OnTokenResponseReceived = OnTokenResponseRecieved,
OnRemoteFailure = OnRemoteFailure
}
});
private Task OnRemoteFailure(FailureContext context)
{
context.HandleResponse();
context.Response.Redirect("/Home/Error?message=" + context.Failure.Message);
return Task.FromResult(0);
}
private Task OnAuthenticationFailed(AuthenticationFailedContext context)
{
return Task.FromResult(0);
}
private Task OnAuthorizationCodeReceived(AuthorizationCodeReceivedContext context)
{
return Task.FromResult(0);
}
private Task OnMessageReceived(MessageReceivedContext context)
{
return Task.FromResult(0);
}
private Task OnTicketRecieved(TicketReceivedContext context)
{
return Task.FromResult(0);
}
private Task OnTokenValidated(TokenValidatedContext context)
{
return Task.FromResult(0);
}
private Task OnUserInformationReceived(UserInformationReceivedContext context)
{
return Task.FromResult(0);
}
private Task OnTokenResponseRecieved(TokenResponseReceivedContext context)
{
return Task.FromResult(0);
}
这是 project.json 文件:
{
"buildOptions": {
"emitEntryPoint": true,
"preserveCompilationContext": true
},
"runtimeOptions": {
"gcServer": true
},
"dependencies": {
"Microsoft.AspNetCore.Diagnostics": "1.0.0",
"Microsoft.AspNetCore.Mvc": "1.0.0",
"Microsoft.AspNetCore.Mvc.TagHelpers": "1.0.0",
"Microsoft.AspNetCore.Server.IISIntegration": "1.0.0",
"Microsoft.AspNetCore.StaticFiles": "1.0.0",
"Microsoft.Extensions.Configuration.FileExtensions": "1.0.0",
"Microsoft.Extensions.Configuration.Json": "1.0.0",
"Microsoft.Extensions.Logging": "1.0.0",
"Microsoft.Extensions.Logging.Console": "1.0.0",
"Microsoft.Extensions.Logging.Debug": "1.0.0",
"Microsoft.AspNetCore.Authentication.Cookies": "1.0.0",
"Microsoft.AspNetCore.Server.Kestrel": "1.0.0",
"Microsoft.AspNetCore.Authentication.OpenIdConnect": "1.0.0",
"Microsoft.NETCore.App": {
"type": "platform",
"version": "1.1.0"
},
"Microsoft.VisualStudio.Web.BrowserLink.Loader": "14.0.0"
},
"frameworks": {
"netcoreapp1.1": {
"imports": [
"dotnet5.6",
"dnxcore50",
"portable-net45+win8"
]
}
},
"tools": {
"Microsoft.AspNetCore.Server.IISIntegration.Tools": {
"version": "1.0.0-preview2-final",
"imports": "portable-net45+win8+dnxcore50"
}
},
"publishOptions": {
"include": [
"wwwroot",
"Views",
"appsettings.json",
"web.config"
]
},
"scripts": {
"prepublish": [ "npm install", "bower install", "gulp clean", "gulp min" ],
"postpublish": [ "dotnet publish-iis --publish-folder %publish:OutputPath%" ]
}
}
将我的项目升级到 1.1.0 后,我现在遇到了针对我的 azure AD 开放 ID 身份验证的身份验证错误。
Fiddler 将错误显示为:
WWW-Authenticate: Bearer error="invalid_request", error_codes="[90010]", error_description="AADSTS90010: JWT 令牌不能与 UserInfo 端点一起使用。% 0d%0aTrace。
这与 400 错误 BadRequest 相关,用户无法登录。
app.UseOpenIdConnectAuthentication(new OpenIdConnectOptions
{
AutomaticAuthenticate = true,
AutomaticChallenge = true,
ClientId = Configuration["Authentication:AzureAd:ClientId"],
Authority = Configuration["Authentication:AzureAd:AADInstance"] + Configuration["Authentication:AzureAd:TenantId"],
ClientSecret = Configuration["Authentication:AzureAd:ClientSecret"],
CallbackPath = Configuration["Authentication:AzureAd:CallbackPath"],
ResponseType = OpenIdConnectResponseType.CodeIdToken,
GetClaimsFromUserInfoEndpoint = true,
Events = new OpenIdConnectEvents
{
OnAuthenticationFailed = OnAuthenticationFailed,
OnAuthorizationCodeReceived = OnAuthorizationCodeReceived,
OnMessageReceived = OnMessageReceived,
OnTicketReceived = OnTicketRecieved,
OnTokenValidated = OnTokenValidated,
OnUserInformationReceived = OnUserInformationReceived,
OnTokenResponseReceived = OnTokenResponseRecieved,
OnRemoteFailure = OnRemoteFailure
}
private async Task OnAuthorizationCodeReceived(AuthorizationCodeReceivedContext context)
{
var aadInstance = "https://login.microsoftonline.com/";
var graphResourceId = "https://graph.windows.net";
string userObjectId = (context.Ticket.Principal.FindFirst("http://schemas.microsoft.com/identity/claims/objectidentifier"))?.Value;
ClientCredential clientCred = new ClientCredential(clientId, clientSecret);
AuthenticationContext authContext = new AuthenticationContext(aadInstance + tenant);
AuthenticationResult authResult = await authContext.AcquireTokenByAuthorizationCodeAsync(
context.ProtocolMessage.Code, new Uri(context.Properties.Items[OpenIdConnectDefaults.RedirectUriForCodePropertiesKey]), clientCred, graphResourceId);
context.HandleCodeRedemption(authResult.AccessToken, authResult.IdToken);
}
由于我正在使用 CodeIdToken 并尝试使用 GetClaimsFromuserInfoEndpoint 选项,我现在是否需要以不同方式处理用户声明?
编辑:如果我注释掉 GetClaimsFromUserInfoEndpoint 这很好用
您还有其他自定义代码吗?它对我来说效果很好,这里是供您参考的代码:
app.UseOpenIdConnectAuthentication(new OpenIdConnectOptions
{
AutomaticAuthenticate = true,
AutomaticChallenge = true,
ClientId = Configuration["AzureAD:ClientId"],
Authority = String.Format(Configuration["AzureAd:AadInstance"], Configuration["AzureAd:Tenant"]),
ClientSecret = Configuration["AzureAd:ClientSecret"],
CallbackPath = new PathString("/signin-oidc"),
ResponseType = OpenIdConnectResponseType.CodeIdToken,
GetClaimsFromUserInfoEndpoint = true,
Events = new OpenIdConnectEvents
{
OnAuthenticationFailed = OnAuthenticationFailed,
OnAuthorizationCodeReceived = OnAuthorizationCodeReceived,
OnMessageReceived = OnMessageReceived,
OnTicketReceived = OnTicketRecieved,
OnTokenValidated = OnTokenValidated,
OnUserInformationReceived = OnUserInformationReceived,
OnTokenResponseReceived = OnTokenResponseRecieved,
OnRemoteFailure = OnRemoteFailure
}
});
private Task OnRemoteFailure(FailureContext context)
{
context.HandleResponse();
context.Response.Redirect("/Home/Error?message=" + context.Failure.Message);
return Task.FromResult(0);
}
private Task OnAuthenticationFailed(AuthenticationFailedContext context)
{
return Task.FromResult(0);
}
private Task OnAuthorizationCodeReceived(AuthorizationCodeReceivedContext context)
{
return Task.FromResult(0);
}
private Task OnMessageReceived(MessageReceivedContext context)
{
return Task.FromResult(0);
}
private Task OnTicketRecieved(TicketReceivedContext context)
{
return Task.FromResult(0);
}
private Task OnTokenValidated(TokenValidatedContext context)
{
return Task.FromResult(0);
}
private Task OnUserInformationReceived(UserInformationReceivedContext context)
{
return Task.FromResult(0);
}
private Task OnTokenResponseRecieved(TokenResponseReceivedContext context)
{
return Task.FromResult(0);
}
这是 project.json 文件:
{
"buildOptions": {
"emitEntryPoint": true,
"preserveCompilationContext": true
},
"runtimeOptions": {
"gcServer": true
},
"dependencies": {
"Microsoft.AspNetCore.Diagnostics": "1.0.0",
"Microsoft.AspNetCore.Mvc": "1.0.0",
"Microsoft.AspNetCore.Mvc.TagHelpers": "1.0.0",
"Microsoft.AspNetCore.Server.IISIntegration": "1.0.0",
"Microsoft.AspNetCore.StaticFiles": "1.0.0",
"Microsoft.Extensions.Configuration.FileExtensions": "1.0.0",
"Microsoft.Extensions.Configuration.Json": "1.0.0",
"Microsoft.Extensions.Logging": "1.0.0",
"Microsoft.Extensions.Logging.Console": "1.0.0",
"Microsoft.Extensions.Logging.Debug": "1.0.0",
"Microsoft.AspNetCore.Authentication.Cookies": "1.0.0",
"Microsoft.AspNetCore.Server.Kestrel": "1.0.0",
"Microsoft.AspNetCore.Authentication.OpenIdConnect": "1.0.0",
"Microsoft.NETCore.App": {
"type": "platform",
"version": "1.1.0"
},
"Microsoft.VisualStudio.Web.BrowserLink.Loader": "14.0.0"
},
"frameworks": {
"netcoreapp1.1": {
"imports": [
"dotnet5.6",
"dnxcore50",
"portable-net45+win8"
]
}
},
"tools": {
"Microsoft.AspNetCore.Server.IISIntegration.Tools": {
"version": "1.0.0-preview2-final",
"imports": "portable-net45+win8+dnxcore50"
}
},
"publishOptions": {
"include": [
"wwwroot",
"Views",
"appsettings.json",
"web.config"
]
},
"scripts": {
"prepublish": [ "npm install", "bower install", "gulp clean", "gulp min" ],
"postpublish": [ "dotnet publish-iis --publish-folder %publish:OutputPath%" ]
}
}