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

ABP Framework 5.3.5添加外部OAuth认证及用户关联问题

ABP Framework 5.3.5 外部OAuth认证集成与内部用户关联问题解决

背景

应用基于ABP Framework 5.3.5开发,采用传统用户名/密码登录方式,内部通过AbpUsers表做身份验证,需要新增外部OAuth认证功能,并将外部登录用户关联到内部用户。

初始尝试与问题

最初编写的OAuth配置代码如下:

context.Services.AddAuthentication()
    .AddOAuth("...", options =>
    {
        options.SignInScheme = IdentityServerConstants.ExternalCookieAuthenticationScheme;

        options.ClientId = configuration["...:ClientId"];
        options.ClientSecret = configuration["...:ClientSecret"];
        options.AuthorizationEndpoint = configuration["...:AuthorizationEndpoint"];
        options.CallbackPath = new PathString(configuration["...:CallbackPath"]);
        options.TokenEndpoint = configuration["...:TokenEndpoint"];

        options.Scope.Add("...");

        options.Events = new OAuthEvents()
        {
            OnCreatingTicket = async context =>
            {
                var email = context.TokenResponse.Response.RootElement.GetProperty("userinfo").GetProperty("email").ToString();
                context.Identity.AddClaim(new Claim(ClaimTypesEnum.UserEmail.GetDescription(), email));
                Console.WriteLine(email);

                // TODO Link external user to internal, authorize user as internal user
            }
        };
    });

这段代码能完成基础OAuth流程:引导用户到外部OAuth服务登录、携带授权码重定向回Identity Server并获取令牌,但用户最终会回到Identity Server登录界面,无法完成内部用户关联与授权。同时在OnCreatingTicket事件中尝试获取UserManager和SignInManager时遇到阻碍。

中间尝试的报错情况

  • 尝试直接获取内部用户并登录时,出现错误:

The navigation 'IdentityUser.Claims' cannot be loaded because the entity is not being tracked. Navigations can only be loaded for tracked entities.

  • 2024-06-11更新代码后出现警告:External login info is not available.,排查发现SignInManager中await this.Context.AuthenticateAsync(IdentityConstants.ExternalScheme)返回null。

最终解决代码

2024-06-12更新后的代码解决了所有问题:

context.Services.AddAuthentication()
    .AddOAuth("...", options =>
    {
        options.SignInScheme = IdentityConstants.ExternalScheme;

        options.ClientId = configuration["...:ClientId"];
        options.ClientSecret = configuration["...:ClientSecret"];
        options.AuthorizationEndpoint = configuration["...:AuthorizationEndpoint"];
        options.CallbackPath = new PathString(configuration["...:CallbackPath"]);
        options.TokenEndpoint = configuration["...:TokenEndpoint"];

        options.Scope.Add("...:auth ...:userinfo");

        options.Events = new OAuthEvents()
        {
            OnCreatingTicket = async context =>
            {
                var userInfo = context.TokenResponse.Response.RootElement.GetProperty("userinfo");
                var email = userInfo.GetProperty("email").ToString();
                var sub = userInfo.GetProperty("sub").ToString();

                context.Principal.Identities.First().AddClaim(new Claim(ClaimTypes.NameIdentifier, sub));
                context.Principal.Identities.First().AddClaim(new Claim(ClaimTypes.Email, email));
            }
        };
    });

关键修改点

  1. 调整SignInScheme:将IdentityServerConstants.ExternalCookieAuthenticationScheme替换为IdentityConstants.ExternalScheme,确保外部认证信息能被ABP的Identity模块正确识别。
  2. 完善Scope配置:添加了包含用户信息和权限的Scope(...:auth ...:userinfo),确保能获取到完整的用户身份数据。
  3. 添加标准声明:在OnCreatingTicket中,为Principal.Identity添加标准的ClaimTypes.NameIdentifier(对应外部用户的sub)和ClaimTypes.Email声明,替代之前的自定义Claim类型,让ABP能正确关联内部用户。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.22 16:46:18