Open Closed

HOW TO AUTHENTICATE EXERNAL SSO TOKEN WITH ADMIN APIS #5427


User avatar
0
shijo created
  • ABP Framework version: v7.3.0

  • UI type: Angular

  • DB provider: EF Core

  • Tiered (MVC) or Auth Server Separated (Angular): yes

  • Exception message and stack trace:

  • Steps to reproduce the issue:"

    1. Client Application/Mobile app getting authorized and obtained token from External SSO Application
    2. API call initiated with the tenant and generated token

    How to configure extra authentication to validate this external token in abp api application ? Here is the sample flow diagram.

Markdown supported.
Copy, paste, or drag & drop images and files (max 100 MB per file, 100 MB total per post)

37 Answer(s)
  • User Avatar
    0
    maliming created
    Support Team Fullstack Developer

    hi

    obtained token from External SSO Application

    What kind of SSO application? Is the token a JWT token?

    Markdown supported.
    Copy, paste, or drag & drop images and files (max 100 MB per file, 100 MB total per post)
  • User Avatar
    0
    shijo created

    hi

    obtained token from External SSO Application

    What kind of SSO application? Is the token a JWT token?

    Yes JWT token

    Markdown supported.
    Copy, paste, or drag & drop images and files (max 100 MB per file, 100 MB total per post)
  • User Avatar
    0
    maliming created
    Support Team Fullstack Developer

    hi

    You can add a jwt authentication scheme by AddJwtBearer("your_jwt_schema", ...) and call the AuthenticateAsync of httpcontext

    
    var result = await httpContext.AuthenticateAsync("your_jwt_schema");
    if (result.Succeeded && result.Principal != null)
    {
        ctx.User = result.Principal;
    }
    
    Markdown supported.
    Copy, paste, or drag & drop images and files (max 100 MB per file, 100 MB total per post)
  • User Avatar
    0
    shijo created

    your_jwt_schema

    Hi, can you share a sample code ? Where should I call the AuthenticateAsync ?

    In My API layer I have already one jwt authentication scheme is there, can I add multiple scheme? This is my existing

    private void ConfigureAuthentication(ServiceConfigurationContext context, IConfiguration configuration)
        {
        context.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
                .AddJwtBearer(options =>
                {
                    options.Authority = configuration["AuthServer:Authority"];
                    options.RequireHttpsMetadata = Convert.ToBoolean(configuration["AuthServer:RequireHttpsMetadata"]);
                    options.Audience = "Test1";
                });
        }
    
    Markdown supported.
    Copy, paste, or drag & drop images and files (max 100 MB per file, 100 MB total per post)
  • User Avatar
    0
    maliming created
    Support Team Fullstack Developer

    Yes, You can add multiple scheme

    context.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
                .AddJwtBearer(options =>
                {
                    options.Authority = configuration["AuthServer:Authority"];
                    options.RequireHttpsMetadata = Convert.ToBoolean(configuration["AuthServer:RequireHttpsMetadata"]);
                    options.Audience = "Test1";
                }).AddJwtBearer("your_jwt_schema", options =>
                {
                    options...
                })
    
    
    Markdown supported.
    Copy, paste, or drag & drop images and files (max 100 MB per file, 100 MB total per post)
  • User Avatar
    0
    shijo created

    Yes, You can add multiple scheme

    context.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme) 
                .AddJwtBearer(options => 
                { 
                    options.Authority = configuration["AuthServer:Authority"]; 
                    options.RequireHttpsMetadata = Convert.ToBoolean(configuration["AuthServer:RequireHttpsMetadata"]); 
                    options.Audience = "Test1"; 
                }).AddJwtBearer("your_jwt_schema", options => 
                { 
                    options... 
                }) 
     
    

    Ok this one I mapped, Where should I add this code ?

    var result = await httpContext.AuthenticateAsync("your_jwt_schema");
    if (result.Succeeded && result.Principal != null)
    {
        ctx.User = result.Principal;
    }
    
    Markdown supported.
    Copy, paste, or drag & drop images and files (max 100 MB per file, 100 MB total per post)
  • User Avatar
    0
    maliming created
    Support Team Fullstack Developer

    hi

    You can call this code on controllers or Authorize with a specific scheme in ASP.NET Core

    https://learn.microsoft.com/en-us/aspnet/core/security/authorization/limitingidentitybyscheme?view=aspnetcore-7.0

    Markdown supported.
    Copy, paste, or drag & drop images and files (max 100 MB per file, 100 MB total per post)
  • User Avatar
    0
    shijo created

    hi

    You can call this code on controllers or Authorize with a specific scheme in ASP.NET Core

    https://learn.microsoft.com/en-us/aspnet/core/security/authorization/limitingidentitybyscheme?view=aspnetcore-7.0

    Hi, I added [Authorize(AuthenticationSchemes = "Bearer,jwt2")] attribute in the controller it's working fine. How can I apply both schemes by default in all controllers?

    Markdown supported.
    Copy, paste, or drag & drop images and files (max 100 MB per file, 100 MB total per post)
  • User Avatar
    0
    maliming created
    Support Team Fullstack Developer

    hi

    https://learn.microsoft.com/en-us/aspnet/core/security/authorization/limitingidentitybyscheme?view=aspnetcore-7.0#use-multiple-authentication-schemes

    Markdown supported.
    Copy, paste, or drag & drop images and files (max 100 MB per file, 100 MB total per post)
  • User Avatar
    0
    shijo created

    hi

    https://learn.microsoft.com/en-us/aspnet/core/security/authorization/limitingidentitybyscheme?view=aspnetcore-7.0#use-multiple-authentication-schemes

    I mapped the schemes globally, working fine when I placed [Authorize] attribute in controller. But in ABP we don't have any [Authorize] attribute, it is in ApplicationService. If I remove [Authorize] attribute from controller and keeping [Authorize] attribute in ApplicationService class, it's giving me unauthorized.

    [RemoteService(IsEnabled = false)]
    [Authorize]
    public class AuthorsAppService : ApplicationService, IAuthorsAppService{
        ctor...
        
        public virtual async Task<PagedResultDto<AuthorDto>> GetListAsync(GetAuthorsInput input)
        {}
    }
    
    [RemoteService]
    public class AuthorController : AbpController, IAuthorsAppService{
    
    }
    
    Markdown supported.
    Copy, paste, or drag & drop images and files (max 100 MB per file, 100 MB total per post)
  • User Avatar
    0
    maliming created
    Support Team Fullstack Developer

    hi

    Can you share a simple project? liming.ma@volosoft.com

    I will download and check it.

    Markdown supported.
    Copy, paste, or drag & drop images and files (max 100 MB per file, 100 MB total per post)
  • User Avatar
    0
    shijo created

    hi

    Can you share a simple project? liming.ma@volosoft.com

    I will download and check it.

    Ok I will create and sample project and share. One more question regarding the user mapping, How can I map user which is authenticated by external sso and our admin api, we have to match the users with email and set currentuser for permission management.

    Markdown supported.
    Copy, paste, or drag & drop images and files (max 100 MB per file, 100 MB total per post)
  • User Avatar
    0
    maliming created
    Support Team Fullstack Developer

    hi

    How can I map user which is authenticated by external sso and our admin api, we have to match the users with email and set currentuser for permission management.

    Im not understand very well, You can add some related code in your simple project.

    Markdown supported.
    Copy, paste, or drag & drop images and files (max 100 MB per file, 100 MB total per post)
  • User Avatar
    0
    shijo created

    Hi, this is basically the users who are authenticated from external SSO are not our application users, only the similarity is the email address. After token validation, I have to check if the user exists in our system with the email id, if the user does not exist with that email create a user with a specific role and then set the current user. My question is how can I execute these user checks and creation logic immediately after token validation?

    Markdown supported.
    Copy, paste, or drag & drop images and files (max 100 MB per file, 100 MB total per post)
  • User Avatar
    0
    shijo created

    Hi, I found a way to execute code after token validation. Added a JWTBearerEvent. How can I access users' data in TokenValidated, I tried to access using IdentityUserAppService but throwing the exception ABP Unauthorized in await userManager.FindByEmailAsync(this.UserEmail);

    options.EventsType = typeof(UserValidation);

    public class UserValidation : JwtBearerEvents
        {
            private string UserEmail { get; set; }
            private string UserName { get; set; }
            public UserValidation()
            {
                
            }
            public override async Task TokenValidated(TokenValidatedContext context)
            {
                try
                {
                    var userManager = context.HttpContext.RequestServices.GetRequiredService<IdentityUserAppService>();
    
                    ClaimsPrincipal userPrincipal = context.Principal;
    
                    if (userPrincipal.HasClaim(c => c.Type == "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/emailaddress"))
                    {
                        this.UserEmail = userPrincipal.Claims.First(c => c.Type == "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/emailaddress").Value;
                    }
                    
                    var checkUser = await userManager.FindByEmailAsync(this.UserEmail);
                    if (checkUser == null)
                    {
                        var newUser = new IdentityUserCreateDto
                        {
                            Email = this.UserEmail,
                            UserName = this.UserEmail,
                        };
    
                        var result = await userManager.CreateAsync(newUser);
    
                        // Assign Roles
                        if (result!=null)
                        {
                            return;
                        }
                        else
                        {
                            throw new Exception("User Not added");
                        }
                    }
                }
                catch (Exception)
                {
                    throw;
                }
            }
        }
    

    Markdown supported.
    Copy, paste, or drag & drop images and files (max 100 MB per file, 100 MB total per post)
  • User Avatar
    0
    maliming created
    Support Team Fullstack Developer

    hi

    I guess on the JwtBearerEvents method the authentication has not finished.

    You can call the app service after app.UseAuthentication

    Markdown supported.
    Copy, paste, or drag & drop images and files (max 100 MB per file, 100 MB total per post)
  • User Avatar
    0
    shijo created

    hi

    I guess on the JwtBearerEvents method the authentication has not finished.

    You can call the app service after app.UseAuthentication

    I am looking to impersonate a user after token validation, I did this but user unauthorised exception coming, After fetching the user I want to sign in with that user in order to access APIs, where should I exactly place the code to impersonate user after validation?

    public override async Task TokenValidated(TokenValidatedContext context)
            {
                try
                {
                    ClaimsPrincipal userPrincipal = context.Principal;
    
                    if (userPrincipal.HasClaim(c => c.Type == "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/emailaddress"))
                    {
                        this.UserEmail = userPrincipal.Claims.First(c => c.Type == "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/emailaddress").Value;
                    }
                    var checkUser = await UserManager.FindByEmailAsync(this.UserEmail);
                    if (checkUser == null)
                    {
                        checkUser = new Volo.Abp.Identity.IdentityUser(Guid.NewGuid(), this.UserEmail, this.UserEmail, _currentTenant.Id);
    
                        var result = await UserManager.CreateAsync(checkUser);
    
                        // Assign Roles
                        if (result != null)
                        {
                            return;
                        }
                        else
                        {
                            throw new Exception("User Not added");
                        }
                    }
                    else
                    {
                        var newPrincipal = new ClaimsPrincipal(
                                            new ClaimsIdentity(
                                                new Claim[]
                                                {
                                                        new Claim(AbpClaimTypes.UserId, checkUser.Id.ToString()),
                                                        new Claim(AbpClaimTypes.TenantId, checkUser.TenantId.ToString()),
                                                        new Claim(AbpClaimTypes.UserName, checkUser.Email),
                                                        new Claim(AbpClaimTypes.Role, "admin")
                                                }
                                            )
                                         );
                        _currentPrincipalAccessor.Change(newPrincipal);
                    }
                }
                catch (Exception)
                {
                    throw;
                }
            }
    
    Markdown supported.
    Copy, paste, or drag & drop images and files (max 100 MB per file, 100 MB total per post)
  • User Avatar
    0
    maliming created
    Support Team Fullstack Developer

    hi

    Can you share a simple project to reproduce the above exception?

    liming.ma@volosoft.com

    Markdown supported.
    Copy, paste, or drag & drop images and files (max 100 MB per file, 100 MB total per post)
  • User Avatar
    0
    shijo created

    hi

    Can you share a simple project to reproduce the above exception?

    liming.ma@volosoft.com

    Hi,

    I have shared sample code here, can you check

    Markdown supported.
    Copy, paste, or drag & drop images and files (max 100 MB per file, 100 MB total per post)
  • User Avatar
    0
    maliming created
    Support Team Fullstack Developer

    hi

    I downloaded the code. Any steps?

    Markdown supported.
    Copy, paste, or drag & drop images and files (max 100 MB per file, 100 MB total per post)
  • User Avatar
    0
    shijo created

    hi

    I downloaded the code. Any steps?

    You can see there, I used 2 JWTbearer, One is Internal, and the other is external,

    1. You have to create an external sso
    2. Create User in external SSO, email exp:** test@test.com**
    3. In the shared project create a new tenant and create a user for that tenant with same email id ** test@test.com**
    4. Create a sample API like getAuthors retrun some data
    5. Create a Client App and Authenticate user with that external SSO
    6. After getting the token Call getAuthor API with that token ( tenant you can hardcoded)
    7. Return author data For me this is giving UnAuthorised exception because of user not loggin in
    Markdown supported.
    Copy, paste, or drag & drop images and files (max 100 MB per file, 100 MB total per post)
  • User Avatar
    0
    maliming created
    Support Team Fullstack Developer

    hi

    You have to create an external sso

    I don't have any external sso. can share a test one?

    I have to reproduce your exception on my locally.

    Markdown supported.
    Copy, paste, or drag & drop images and files (max 100 MB per file, 100 MB total per post)
  • User Avatar
    0
    maliming created
    Support Team Fullstack Developer

    hi

    _currentPrincipalAccessor.Change(newPrincipal); will not work. It only works on using scope.

    eg:

    using(_currentPrincipalAccessor.Change(newPrincipal))
    {
        //working...
    }
    
    Markdown supported.
    Copy, paste, or drag & drop images and files (max 100 MB per file, 100 MB total per post)
  • User Avatar
    0
    maliming created
    Support Team Fullstack Developer

    After getting the token Call getAuthor API with that token ( tenant you can hardcoded) Return author data For me this is giving UnAuthorised exception because of user not loggin in

    Call getAuthor API of TestApp.HttpApi.Host or TestApp.AuthServer?

    Markdown supported.
    Copy, paste, or drag & drop images and files (max 100 MB per file, 100 MB total per post)
  • User Avatar
    0
    maliming created
    Support Team Fullstack Developer

    If you Call getAuthor API of TestApp.HttpApi.Host and get UnAuthorised

    You can try to use context.HttpContext.User = newPrincipal; to replace the _currentPrincipalAccessor.Change(newPrincipal);

    Markdown supported.
    Copy, paste, or drag & drop images and files (max 100 MB per file, 100 MB total per post)
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.8.0-preview. Updated on September 16, 2026, 07:12
1
ABP Assistant
🔐 You need to be logged in to use the chatbot. Please log in first.