问题: 在我的 ASP.NET Core 3.1 MVC Web 应用程序中,我在startup.cs 中使用
services.AddSignIn(Configuration);
(由 Microsoft.Identity.Web 0.1.5-preview 提供),并且我想在登录时注册用户,回调方法ExternalLoginInfo info = await _signInManager.GetExternalLoginInfoAsync();
始终返回null。
背景:
详情: 我的appsettings.json:
"AzureAd": {
"Instance": "https://login.microsoftonline.com/",
"Domain": "something.onmicrosoft.com",
"TenantId": "GUID",
"ClientId": "GUID",
"CallbackPath": "/signin-oidc",
"SignedOutCallbackPath ": "/signout-callback-oidc",
"ClientSecret": "GUID"
}
启动cs:
services.AddDbContext<UserDbContext>(options =>
options.UseSqlServer(
Configuration.GetConnectionString("DefaultConnection"), u => u.MigrationsAssembly("DatabaseLayer.Core")));
services.AddIdentity<AppUser, IdentityRole>(options =>
{
options.User.RequireUniqueEmail = true;
})
.AddEntityFrameworkStores<UserDbContext>()
.AddDefaultTokenProviders();
services.Configure<CookiePolicyOptions>(options =>
{
// This lambda determines whether user consent for non-essential cookies is needed for a given request.
options.CheckConsentNeeded = context => true;
options.MinimumSameSitePolicy = SameSiteMode.Unspecified;
// Handling SameSite cookie according to https://learn.microsoft.com/en-us/aspnet/core/security/samesite?view=aspnetcore-3.1
options.HandleSameSiteCookieCompatibility();
});
services.AddOptions();
services.AddSignIn(Configuration);
问题:我需要配置什么才能返回任何外部登录以注册用户?
根据this,无法使用 MSAL 捕获外部用户。此外,也不可能使用任何内部用户,因为它们会干扰登录的 MSAL 用户。
所以微软的 ASP.NET Core Identity 框架与他们的身份框架不兼容,很好。 (遗憾的是,这使得 MSAL 对我来说毫无用处,而且我无法想到任何业务案例,高效的应用程序不需要任何内部用户存储库即可正常工作。即使我只需要存储用户的设置,我也会使用用于此目的的身份框架)。
可以通过将 MSAL 访问令牌中的
uid
和 utid
声明保存在本地用户声明存储中来实现。当键入其令牌存储时,MSAL 库会查找这些声明。
Blazor 8 Web 应用程序模板中的代码示例,位于函数
Components\Account\Pages\ExternalLogin.razor
中的文件 OnValidSubmitAsync
:
private async Task OnValidSubmitAsync()
{
...
var claimsStore = GetClaimsStore();
string? OptClaim(List<string> claimTypes) =>
claimTypes.Select(s => externalLoginInfo.Principal.FindFirstValue(s))
.SingleOrDefault(s => s is not null);
const string tenantIdClaimType = "utid";
var tenantId = OptClaim([tenantIdClaimType]);
const string objectIdClaimType = "uid";
var objectId = OptClaim([objectIdClaimType]);
if (tenantId is not null) {
await claimsStore.AddClaimsAsync(user, [new(tenantIdClaimType, tenantId)], default);
}
if (objectId is not null) {
await claimsStore.AddClaimsAsync(user, [new(objectIdClaimType, objectId)], default);
}