Asp.net core SigninManager.GetExternalLoginFoAsync()使用了错误的身份验证方案
我正在尝试将AzureAD身份验证添加到一个.Net Core 3应用程序中,该应用程序已在本地帐户中使用Identity。在ExternalLogin.OnGetCallbackAsync方法中处理回调的位置,一切都已就绪。当调用_signinManager.GetExternalLoginInfoAsync()时,它将返回null。通过查看SignInManager代码内部,我在方法中找到了以下行:Asp.net core SigninManager.GetExternalLoginFoAsync()使用了错误的身份验证方案,asp.net-core,azure-active-directory,asp.net-core-identity,Asp.net Core,Azure Active Directory,Asp.net Core Identity,我正在尝试将AzureAD身份验证添加到一个.Net Core 3应用程序中,该应用程序已在本地帐户中使用Identity。在ExternalLogin.OnGetCallbackAsync方法中处理回调的位置,一切都已就绪。当调用_signinManager.GetExternalLoginInfoAsync()时,它将返回null。通过查看SignInManager代码内部,我在方法中找到了以下行: var auth = await Context.AuthenticateAsync(Id
var auth = await Context.AuthenticateAsync(IdentityConstants.ExternalScheme);
我将其复制到我的方法中并输入了一个断点,然后看到IdentityCosntants.extnalscheme值是“Identity.External”。我将代码更改为:
var auth = await HttpContext.AuthenticateAsync(AzureADDefaults.AuthenticationScheme);
并看到auth变量包含正确的数据,而如果使用IdentityConstants.ExternalScheme执行它,则返回null。所以我的问题是,如何配置我的应用程序,使IdentityConstants.ExternalScheme返回与AzureAddFaults.AuthenticationScheme相同的值,这实际上只是字符串“AzureAD”
这是我的简历:
using Microsoft.AspNetCore.Authentication;
using Microsoft.AspNetCore.Authentication.AzureAD.UI;
using Microsoft.AspNetCore.Authentication.OpenIdConnect;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Identity;
using Microsoft.AspNetCore.Mvc.Authorization;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Newtonsoft.Json;
using Newtonsoft.Json.Serialization;
using NLog;
using SURe.Business.Helpers;
using SURe.Business.Interfaces;
using SURe.Business.Resources;
using SURe.Business.Stores;
using SURe.Data.Contexts;
using SURe.Data.Models;
using SURe.Presentation.Web.Settings;
using SURe.Utilities.Email;
using System;
namespace SURe.Presentation.Web
{
public class Startup
{
public Startup(IConfiguration configuration)
{
Configuration = configuration;
}
public IConfiguration Configuration { get; }
// This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services)
{
services.Configure<AppSettings>(Configuration.GetSection("AppSettings"));
services.AddDbContext<ApplicationContext>(options =>
options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection"))
);
services.AddDefaultIdentity<AppUser>(options =>
{
options.User.AllowedUserNameCharacters = string.Empty; // This allows us to use special characters in the UserName property, specifically '\' and '-'
options.User.RequireUniqueEmail = true;
options.Lockout.MaxFailedAccessAttempts = 3;
})
.AddRoles<AppRole>()
.AddEntityFrameworkStores<ApplicationContext>();
services.AddAuthentication(AzureADDefaults.AuthenticationScheme)
.AddAzureAD(options => Configuration.Bind("AzureAd", options));
// Configure Dependency Injection (DI)
services.AddTransient<IEmailSender, EmailSender>();
services.AddTransient<IEmployeeStore, EmployeeStore>();
services.AddTransient<IFederalSkillLevelStore, FederalSkillLevelStore>();
services.AddTransient<ILocationCodeStore, LocationCodeStore>();
services.AddTransient<IHttpHelper, HttpHelper>();
services.AddTransient<IModuleStore, ModuleStore>();
services.AddTransient<IModuleClaimStore, ModuleClaimStore>();
services.AddTransient<ISubscriptionStore, SubscriptionStore>();
services.AddTransient<IAccountStore, AccountStore>();
services.AddTransient<IMenuStore, MenuStore>();
services.AddTransient<IAccessRequestStore, AccessRequestStore>();
services.AddTransient<IAccessRequestApproverStore, AccessRequestApproverStore>();
services.AddTransient<IXmlDocStore, XmlDocStore>();
services.AddTransient<ISupportRequestStore, SupportRequestStore>();
services.AddAuthorizationCore(options =>
{
options.AddPolicy("AdminOnly", policy =>
{
policy.RequireAuthenticatedUser();
policy.RequireClaim("Role", "Application_Admin");
});
options.AddPolicy("UserAdmin", policy =>
{
policy.RequireAuthenticatedUser();
policy.RequireClaim("Role", "Application_Admin");
});
options.AddPolicy("MenuManager", policy =>
{
policy.RequireAuthenticatedUser();
policy.RequireClaim("Role", "Application_Admin");
});
options.AddPolicy("ModuleManager", policy =>
{
policy.RequireAuthenticatedUser();
policy.RequireClaim("Role", "Application_Admin");
});
options.AddPolicy("AccessRequestApprovers", policy => {
policy.RequireAuthenticatedUser();
policy.RequireClaim("Role", "Application_Admin", "Access_Request_Approver");
});
});
services.ConfigureApplicationCookie(options =>
{
// Cookie settings
options.AccessDeniedPath = "/Status403";
options.Cookie.Name = "SUReWeb";
options.Cookie.HttpOnly = true;
options.ExpireTimeSpan = TimeSpan.FromMinutes(45);
options.SlidingExpiration = true;
});
services.AddControllers()
.AddNewtonsoftJson(options =>
{
options.SerializerSettings.ContractResolver = new DefaultContractResolver();
options.SerializerSettings.ReferenceLoopHandling = ReferenceLoopHandling.Ignore;
});
services.AddRazorPages()
.AddRazorPagesOptions(options => {
options.Conventions.AllowAnonymousToPage("/Login/AccountDisabled");
})
.AddMvcOptions(options =>
{
var policy = new AuthorizationPolicyBuilder()
.RequireAuthenticatedUser()
.Build();
options.Filters.Add(new AuthorizeFilter(policy));
});
// Configure Hsts
services.AddHsts(options =>
{
options.Preload = true;
options.IncludeSubDomains = true;
options.MaxAge = TimeSpan.FromHours(1);
});
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
// Configure NLog settings
GlobalDiagnosticsContext.Set("configDir", Configuration.GetSection("AppSettings")["NLogDir"]);
GlobalDiagnosticsContext.Set("connectionString", Configuration.GetConnectionString("DefaultConnection"));
//Configure Aspose license(s)
var licenseCells = new Aspose.Cells.License();
licenseCells.SetLicense(Messages.AsposeFilePath);
var licenseWords = new Aspose.Words.License();
licenseWords.SetLicense(Messages.AsposeFilePath);
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
app.UseDatabaseErrorPage();
}
else
{
app.UseExceptionHandler("/Error");
// Configure security settings
app.UseXContentTypeOptions(); // sets the X-Content-Type-Options to no-sniff
app.UseReferrerPolicy(opts => opts.NoReferrer());
app.UseXXssProtection(options => options.EnabledWithBlockMode());
app.UseXfo(options => options.Deny()); // Block iframes
// See services.AddHsts above for settings
app.UseHsts();
}
app.UseStatusCodePagesWithReExecute("/Status{0}"); // Status403.cshtml, Status404.cshtml, etc.
app.UseRouting();
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseAuthentication();
app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
endpoints.MapRazorPages();
endpoints.MapControllers();
});
}
}
但是我仍然在IdentityConstants.ExternalScheme中得到了错误的值。我有一个解决办法,基本上是手动执行GetExternalLoginInfoAsync()的功能,但这看起来太脏了
TIA对此有任何解决方案,我们会遇到相同的问题。对此有任何解决方案,我们会遇到相同的问题。
services.AddAuthentication(options => {
options.DefaultAuthenticateScheme = AzureADDefaults.AuthenticationScheme;
options.DefaultChallengeScheme = AzureADDefaults.AuthenticationScheme;
options.DefaultScheme = AzureADDefaults.AuthenticationScheme;
options.DefaultSignInScheme = AzureADDefaults.AuthenticationScheme; ;
})
.AddAzureAD(options => Configuration.Bind("AzureAd", options));