You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

.NET 8 Blazor应用Microsoft SSO无法写入AspNetUserLogins问题求助

解决.NET 8 Blazor Web App中微软SSO登录后AspNetUserLogins表为空的问题

核心问题分析

你已成功获取微软外部登录信息,但AspNetUserLogins表未写入数据,导致ExternalLoginSignInAsync失败——本质是外部登录信息未与本地用户完成关联,而.NET 8 Blazor Web App的Identity流程、模板结构相比.NET 7存在差异。

具体解决步骤

1. 启用Razor Pages端点路由

.NET 8 Blazor Web App(尤其是Auto/Interactive Server模式)默认可能未开启Razor Pages路由,但Identity的外部登录回调依赖该路由。在Program.cs的中间件配置中添加:

app.MapRazorPages();

需将其放在app.MapBlazorHub()和app.MapFallbackToPage("/_Host")之前,保证路由优先级正确。

2. 完善ExternalLogin回调的用户关联逻辑

在ExternalLogin页面的OnLoginCallbackAsync方法中,当ExternalLoginSignInAsync返回失败时,需手动处理用户创建+外部登录关联逻辑,替代旧的PerformExternalLogin模块:

public async Task<IActionResult> OnGetCallbackAsync(string returnUrl = null, string remoteError = null)
{
    returnUrl ??= Url.Content("~/");
    if (remoteError != null)
    {
        return RedirectToPage("./Login", new { ReturnUrl = returnUrl, Error = remoteError });
    }
    
    var info = await _signInManager.GetExternalLoginInfoAsync();
    if (info == null)
    {
        return RedirectToPage("./Login", new { ReturnUrl = returnUrl, Error = "加载外部登录信息失败" });
    }

    // 尝试用外部登录信息直接登录
    var result = await _signInManager.ExternalLoginSignInAsync(info.LoginProvider, info.ProviderKey, isPersistent: false, bypassTwoFactor: true);
    if (result.Succeeded)
    {
        return LocalRedirect(returnUrl);
    }
    else
    {
        // 获取外部用户邮箱
        var email = info.Principal.FindFirstValue(ClaimTypes.Email);
        if (email != null)
        {
            var user = await _userManager.FindByEmailAsync(email);
            
            // 本地用户不存在则创建
            if (user == null)
            {
                user = new ApplicationUser 
                { 
                    UserName = email, 
                    Email = email,
                    EmailConfirmed = true // 微软登录默认已验证邮箱
                };
                var createResult = await _userManager.CreateAsync(user);
                if (!createResult.Succeeded)
                {
                    foreach (var error in createResult.Errors)
                    {
                        ModelState.AddModelError(string.Empty, error.Description);
                    }
                    return Page();
                }
            }
            
            // 将外部登录信息关联到本地用户
            var addLoginResult = await _userManager.AddLoginAsync(user, info);
            if (addLoginResult.Succeeded)
            {
                await _signInManager.SignInAsync(user, isPersistent: false);
                return LocalRedirect(returnUrl);
            }
            
            // 处理关联错误
            foreach (var error in addLoginResult.Errors)
            {
                ModelState.AddModelError(string.Empty, error.Description);
            }
        }
        
        return Page();
    }
}

3. 验证Identity数据库迁移

确认ApplicationDbContext已正确应用.NET 8 Identity的迁移,AspNetUserLogins表结构完整:

  • 运行Add-Migration AddExternalLoginFix(若需新增迁移)
  • 运行Update-Database同步数据库结构

4. 检查微软应用注册的回调URL

确保Azure门户中微软应用注册的重定向URI与应用实际回调地址一致,默认地址为https://localhost:{端口}/signin-microsoft;若自定义回调路径,需在配置中指定:

.AddMicrosoftAccount(microsoftOptions =>
{
    microsoftOptions.ClientId = builder.Configuration["MicrosoftClientID"];
    microsoftOptions.ClientSecret = builder.Configuration["MicrosoftClientSecret"];
    microsoftOptions.CallbackPath = "/custom-signin-microsoft"; // 自定义路径时添加
});

内容的提问来源于stack exchange,提问作者Christian Hansen

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.16 16:19:54