Activities of "papusa"

I've send a link to the BankID test app.

  • National identity number: 04080599469
  • One-time code: otp
  • BankID password: qwer1234

It's always null when context.EndpointType == OpenIddictServerEndpointType.Authorization.

I’ve been trying to do that, but both IdentityTokenPrincipal and AccessTokenPrincipal are null. Maybe this needs to be handled in a different event? I’m not very familiar with OpenIddict, what do you think?

You can use a custom claim to check it. eg nationalidentitynumber then try to get this claim from CurrentUser.

Here is my claims contributor:

public class BankIdClaimsPrincipalContributor : IAbpClaimsPrincipalContributor, ITransientDependency
{
    private readonly AbpSignInManager _signInManager;

    public BankIdClaimsPrincipalContributor(AbpSignInManager signInManager)
    {
        _signInManager = signInManager;
    }

    public async Task ContributeAsync(AbpClaimsPrincipalContributorContext context)
    {
        var identity = context.ClaimsPrincipal.Identities.FirstOrDefault();
        
        var externalLogin = await _signInManager.GetExternalLoginInfoAsync();
        if (externalLogin == null)
        {
            // Contributor is executed 4 times. Last 2 times externalLogin is null.
            // It results in 2 "isbankidauthenticated" claims, one has value of false and another is true.
            identity?.AddClaim(new Claim("isbankidauthenticated", false.ToString().ToLower()));
            return;
        }
        
        var isBankIdAuthenticated = externalLogin.LoginProvider == "Criipto";
        var claim = new Claim("isbankidauthenticated", isBankIdAuthenticated.ToString().ToLower());
        identity?.AddClaim(claim);
    }
}

I noticed that it gets executed 4 times. Is this the expected behavior? This causes an issue because I cannot reliably set my claim value to false.

You can check the BankID platform to see if it supports adding custom claims for a user.

I don’t quite understand how BankID is related here. As far as I know, the claims are set within the ABP application itself. Am I missing something? Previously, you suggested implementing IOpenIddictServerHandler<OpenIddictServerEvents.ProcessSignInContext>. This works, but it only adds the claim to the access_token. How can I also include the claim in the id_token?

public class BankIdOpenIddictServerHandler :  IOpenIddictServerHandler<OpenIddictServerEvents.ProcessSignInContext>
{
    public static OpenIddictServerHandlerDescriptor Descriptor { get; }
        = OpenIddictServerHandlerDescriptor.CreateBuilder<OpenIddictServerEvents.ProcessSignInContext>()
            .UseSingletonHandler<BankIdOpenIddictServerHandler>()
            .SetOrder(100_000)
            .SetType(OpenIddictServerHandlerType.Custom)
            .Build();

    public async ValueTask HandleAsync(OpenIddictServerEvents.ProcessSignInContext context)
    {
        if (context.EndpointType != OpenIddictServerEndpointType.Authorization ||
            context.AuthorizationCodePrincipal == null)
        {
            return;
        }

        var httpContext = context.Transaction.GetHttpRequest()?.HttpContext;
        if (httpContext == null)
        {
            return;
        }

        var identity = await httpContext.AuthenticateAsync(IdentityConstants.ApplicationScheme);
        if (identity.Principal == null)
        {
            return;
        }

        var bankIdClaim = identity.Principal.FindFirst("isbankidauthenticated");
        if (bankIdClaim != null)
        {
            context.AuthorizationCodePrincipal.AddClaim("isbankidauthenticated", bankIdClaim.Value);
        }
    }
}

To determine if a user logged in with a local account or via an external login (such as BankID), you can inspect the user's login providers. ABP's Identity system stores external login information in the user logins table.

As I understand it, this only shows which providers are associated with the user (from the user logins table), not which provider was actually used for the current login session. Is there a way to detect the login type of the current session?

To include a custom claim in both the access_token and id_token, you can use claims contributors in ABP. Implement IAbpClaimsPrincipalContributor and register it. In your contributor, add a custom claim (e.g., "login_type") based on the authentication context. This claim will be included in the generated tokens if added during the authentication process.

I have already implemented a claims contributor. But is this the recommended approach? I noticed it is executed four (4) times when a user logs in from Angular. Also, it does not add the claim to the id_token or access_token received on the client. This was partially solved by the suggested IOpenIddictServerHandler<OpenIddictServerEvents.ProcessSignInContext> implementation from my previous ticket, but that only adds the claim to the access_token, which is not very convenient on the client side.

The AI answer didn’t really address my third question either. Could you please clarify the recommended way to handle the scenario where a user adds a new external login?

It works. Thank you!

I've shared a link to the BankID demo project via OneDrive. You should receive e-mail with link.

While testing the demo, I noticed that the issue only occurs when an external login is added to an existing user. If the user is registered directly via BankID, the problem doesn't appear.

Here are the steps to reproduce the issue:

  1. Log in using any local user (e.g., admin).
  2. Navigate to External Logins.
  3. Add an external BankID account using the following test credentials:
    • National identity number: 04080599469
    • One-time code: otp
    • BankID password: qwer1234
  4. After linking the external login, log out.
  5. Log in using BankID.
  6. In the Angular app's Home page, click the "Test national identity claim" button.
  7. Expected: It should display the national identity number. Actual: It shows a message indicating the claim is not found.

Below is result for same user in angular and swagger:

I will test your case with GitHub login.

Sounds good. Thanks

I can definitely create and share a demo project with you, but please note that I won’t be able to include the external login provider credentials (like the client secret), since those are sensitive. Would that still work for you?

I can provide a test user (test identity number), or you're welcome to generate one yourself using this link: https://ra-preprod.bankidnorge.no/#/generate We're using Criipto for Norwegian BankID. You can get test account for free.

That said, I assumed the issue wasn't specific to BankID, and that any external login provider would be sufficient for testing in a demo setup. Please let me know how you'd prefer to proceed!

Previously, I was using HttpContextAccessor.HttpContext.AuthenticateAsync(IdentityConstants.ExternalScheme) to retrieve the external claims principal.

After reviewing the link you provided, I switched to using SignInManager, but the behavior hasn't changed. When logging into the Angular app, the external login is null, and I'm not receiving the expected claims when calling the API from the Angular front end.

Here's the code for my IAbpClaimsPrincipalContributor implementation. Could you please take a look and let me know if there's anything wrong or missing?

public class BankIdClaimsPrincipalContributor : IAbpClaimsPrincipalContributor, ITransientDependency { private readonly SignInManager<IdentityUser> _signInManager;

public BankIdClaimsPrincipalContributor(SignInManager&lt;IdentityUser&gt; signInManager)
{
    _signInManager = signInManager;
}

public async Task ContributeAsync(AbpClaimsPrincipalContributorContext context)
{
    var identity = context.ClaimsPrincipal.Identities.FirstOrDefault();
    
    var externalLogin = await _signInManager.GetExternalLoginInfoAsync();
    if (externalLogin == null)
    {
        identity?.AddClaim(new Claim("isbankidauthenticated", false.ToString().ToLower()));
        return;
    }
    
    var authenticationTypeClaim = externalLogin.Principal.FindFirst(Claims.BankId.AuthenticationType);
    var isBankIdAuthenticated = authenticationTypeClaim is { Value: Claims.BankId.NorwegianAuthenticationTypeValue };
    identity?.AddClaim(new Claim("isbankidauthenticated", isBankIdAuthenticated.ToString().ToLower()));

    if (!isBankIdAuthenticated)
    {
        return;
    }

    ForwardClaim("socialno", "nationalidentitynumber");
    ForwardClaim("dateofbirth", "dateofbirth");
    
    return;
    
    void ForwardClaim(string bankIdClaimType, string claimType)
    {
        var claim = externalLogin.Principal.FindFirst(bankIdClaimType);
        if (claim != null)
        {
            identity?.AddClaim(new Claim(claimType, claim.Value));
        }
    }
}

}


I think it might be more convenient if you could create a demo project yourself with the setup you have in mind. :)

Showing 11 to 20 of 33 entries
Boost Your Development
ABP Live Training
Packages
See Trainings
Mastering ABP Framework Book
The Official Guide
Mastering
ABP Framework
Learn More
Mastering ABP Framework Book
Made with ❤️ on ABP v10.1.0-preview. Updated on December 12, 2025, 10:36
1
ABP Assistant
🔐 You need to be logged in to use the chatbot. Please log in first.