Open Closed

Authorization Problem in Different Projects and Single Auth Server #10258


User avatar
0
omer_yel created

Hi, I have N-Tiered project which have UI, API Host and Auth (MainProject). So I have a another N-Tiered project just has Api Host there isn't UI and Auth(ChildProject). I configured appsettings of ChildProject for Auth into MainProject. I use Authorized attribute with Policy not role or scheme name. I Authorized via swagger or postman and I request an endpoint of ChildProject with got token. But I get 401 error in everytime. I tried show my projects relations like follow image.

I want to authorized via MainProject Auth Server and want to use Policy like [Authorize(xxxWebAPIPermissions.WCFService.Default)] in ChildProject endpoints. Can I do that?

NOTE: I authorized with admin user so it has all permissions include that use in end points of Childproject policy permission.


3 Answer(s)
  • User Avatar
    0
    AI-Bot created
    Support Team ABP Agent
    1. Yes, you can do this
      You can absolutely have:
    • One Auth Server (MainProject)
    • Multiple API Hosts (MainProject API Host + ChildProject API Host)
    • Use [Authorize(ChildProjectPermissions.Something)] on ChildProject endpoints

    …as long as both API hosts validate the same access token correctly and the permissions are defined/seeded consistently.

    Your 401 means the ChildProject is not accepting the token (authentication fails) before it even reaches the ABP permission system.


    1. Configure ChildProject to trust MainProject Auth Server

    In ChildProject.HttpApi.Host:

    appsettings.json

    "AuthServer": {
      "Authority": "https://MAIN-PROJECT-AUTH-URL",   // MainProject Auth server URL
      "RequireHttpsMetadata": "false",                // true in production with HTTPS
      "SwaggerClientId": "ChildProject_Swagger"       // optional, for swagger auth
    },
    "Jwt": {
      "Authority": "https://MAIN-PROJECT-AUTH-URL",
      "Audience": "ChildProject"                      // see step 3
    }
    

    (or follow the same AuthServer section structure you already use in MainProject HttpApi.Host, just changing the Audience if needed.)

    HttpApiHostModule – ConfigureServices

    public override void ConfigureServices(ServiceConfigurationContext context)
    {
        var configuration = context.Services.GetRequiredService<IConfiguration>();
    
        ConfigureAuthentication(context, configuration);
    }
    
    private void ConfigureAuthentication(ServiceConfigurationContext context, IConfiguration configuration)
    {
        context.Services.AddAuthentication("Bearer")
            .AddJwtBearer("Bearer", options =>
            {
                options.Authority = configuration["AuthServer:Authority"];
                options.RequireHttpsMetadata = 
                    Convert.ToBoolean(configuration["AuthServer:RequireHttpsMetadata"]);
    
                options.Audience = "ChildProject"; // must match the audience of the token
                // (temporarily you can disable audience validation to test)
                // options.TokenValidationParameters.ValidateAudience = false;
            });
    }
    

    Startup pipeline (OnApplicationInitialization)

    Make sure the middleware order includes both authentication and authorization:

    public override void OnApplicationInitialization(ApplicationInitializationContext context)
    {
        var app = context.GetApplicationBuilder();
    
        app.UseCorrelationId();
        app.UseRouting();
        app.UseCors();
    
        app.UseAuthentication();     // BEFORE multi-tenancy & authorization
        app.UseAbpRequestLocalization();
        app.UseMultiTenancy();
        app.UseAuthorization();
    
        app.UseSwagger();
        app.UseAbpSwaggerUI(options => { ... });
    
        app.UseAuditing();
        app.UseConfiguredEndpoints();
    }
    

    If UseAuthentication() is missing or in wrong order, you will also constantly get 401.


    1. Make sure the token is valid for ChildProject

    The token you get from MainProject must be accepted by ChildProject:

    • In MainProject Auth Server (OpenIddict data seed / identity seed contributor), you must define an API scope / resource that represents ChildProject, for example "ChildProject".

    • Add that scope to the client that obtains the token (Angular, Swagger, Postman client, etc.).

    • When you request a token, request that scope:

      • For Swagger/OpenID: include ChildProject in the scopes.
      • For Postman: scope=... ChildProject.
    • The resulting token must either:

      • Contain aud = "ChildProject", and you set options.Audience = "ChildProject", or
      • You set ValidateAudience = false (for testing only) so that any token from the same authority is accepted.

    If the aud in the token doesn’t match what ChildProject expects, you will see 401 from the JWT middleware, even though the same token works on the MainProject API Host.


    1. Share permission definitions between Main and Child projects

    To be able to use:

    [Authorize(xxxWebAPIPermissions.WCFService.Default)]
    public class MyChildController : AbpController
    {
        ...
    }
    

    do the following:

    1. Permission definition provider
      Put your xxxWebAPIPermissions and the corresponding PermissionDefinitionProvider in a shared application contracts project that is referenced by:

      • MainProject Auth Server (so permissions can be assigned to roles/users)
      • MainProject API Host
      • ChildProject API Host
    2. Module dependency

      In ChildProjectApplicationContractsModule (or HttpApi module), depend on the module that contains the permission provider:

    [DependsOn(
           typeof(AbpAuthorizationAbstractionsModule),
           typeof(MySharedPermissionsModule) // where your PermissionDefinitionProvider lives
       )]
       public class ChildProjectApplicationContractsModule : AbpModule
       {
       }
    
    1. Seed permissions in MainProject (as you already do).
      As long as the user has that permission (directly or via role), ABP’s permission checker in ChildProject will read it (claims + database) and authorize the policy.

    If authentication is correct and the user really has the permission, then failing [Authorize(…)] would give 403 Forbidden, not 401.
    Since you get 401, it’s almost certainly token validation (authentication) in ChildProject, not the permission policy itself.


    1. Quick checklist

    On ChildProject HttpApi.Host:

    • [ ] UseAuthentication() is present and before UseAuthorization().
    • [ ] AddAuthentication().AddJwtBearer() is configured to use MainProject AuthServer Authority.
    • [ ] Audience and token’s aud (or ValidateAudience = false) are aligned.
    • [ ] Tokens requested include the ChildProject scope/audience.
    • [ ] Permission definitions project is shared and referenced.
    • [ ] Same database (you already have) so user, role, permission data are visible.

    Once these are done, you can:

    1. Get token from MainProject Auth Server.
    2. Call ChildProject endpoints with Authorization: Bearer <token>.
    3. [Authorize(xxxWebAPIPermissions.WCFService.Default)] will work as expected.

    This response was generated by AI. If it didn’t solve your problem, feel free to post a new answer — our support team will jump in to help you soon.

  • User Avatar
    0
    omer_yel created

    Above answer isn't enough for me and it doesn't solve my problem. Please redirect a person.

  • User Avatar
    0
    maliming created
    Support Team Fullstack Developer

    hi

    Can you share the module code and debug logs of Child Project (API Host)?

    liming.ma@volosoft.com

    See https://abp.io/support/questions/8622/How-to-enable-Debug-logs-for-troubleshoot-problems

    Thanks.

Learn More, Pay Less
33% OFF
All Trainings!
Get Your Deal
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 25, 2025, 06:16
1
ABP Assistant
🔐 You need to be logged in to use the chatbot. Please log in first.