Base solution for your next web application
Open Closed

OpenID ProviderKey #12597


User avatar
0
niengineering created

Dear Support,

I see that in OpenID login the ProviderKey is set to "sub" field instead of "oid". I would like to use "oid" so I can import and map users in AbpUserLogins (I'm activating Azure AD on existings users). I found the place where "sub" is used in the Angular frontend but I don't know how to map it correctly in the backend.

Markdown is supported
Copy & paste or drag & drop images (max 30 MB per image)

1 Answer(s)
  • User Avatar
    0
    oguzhanagir created
    Support Team

    Hi @niengineering

    According to the OpenID Connect specification, the sub claim represents a stable and globally unique identifier for the authenticated user. ASP.NET Zero follows this standard and therefore uses the sub claim as the default ProviderKey.

    This assignment is performed on the backend inside the OpenIdConnectAuthProviderApi.GetUserInfo method.

    For this reason, changing anything only on the Angular side does not affect the ProviderKey value.

    Using oid instead

    In Azure AD scenarios, you may want to use the oid claim in order to match or import existing users.

    To achieve this, you need to inherit from OpenIdConnectAuthProviderApi and override the GetUserInfo method.

    In the Web.Host or Web.Core project:

    using System.Linq;
    using System.Threading.Tasks;
    using Abp.AspNetZeroCore.Web.Authentication.External;
    using Abp.AspNetZeroCore.Web.Authentication.External.OpenIdConnect;
    using Abp.Extensions;
    
    public class CustomOpenIdConnectAuthProviderApi : OpenIdConnectAuthProviderApi
    {
        public override async Task<ExternalAuthUserInfo> GetUserInfo(string token)
        {
            var userInfo = await base.GetUserInfo(token);
    
            // Azure AD object id (oid)
            var oid = userInfo.Claims
                .FirstOrDefault(c => c.Type == "oid")?.Value;
    
            if (!oid.IsNullOrWhiteSpace())
            {
                userInfo.ProviderKey = oid;
            }
    
            return userInfo;
        }
    }
    

    At this point, the ProviderKey will be set to oid instead of sub.

    Register the custom provider

    After creating the custom provider, you must update TenantBasedOpenIdConnectExternalLoginInfoProvider to use it.

    Web.Host

    return new ExternalLoginProviderInfo(
        OpenIdConnectAuthProviderApi.Name,
        settings.ClientId,
        settings.ClientSecret,
        typeof(CustomOpenIdConnectAuthProviderApi), // custom provider
        new Dictionary<string, string>
        {
            { "Authority", settings.Authority },
            { "LoginUrl", settings.LoginUrl },
            { "ValidateIssuer", settings.ValidateIssuer.ToString() },
            { "ResponseType", settings.ResponseType }
        },
        jsonClaimMappings
    );
    

    Do not change the provider name (OpenIdConnectAuthProviderApi.Name). Otherwise, the frontend will not recognize the provider.

    appsettings.json To ensure the oid claim is available on the backend, you can add the following mapping: OpenId

    "ClaimsMapping": [
      {
        "claim": "oid",
        "key": "oid"
      },
      {
        "claim": "unique_name",
        "key": "preferred_username"
      }
    ]
    

    If the issue is not resolved after applying these changes, please do not hesitate to contact us.

    Related Document

    Markdown is supported
    Copy & paste or drag & drop images (max 30 MB per image)