Activities of "enisn"

Hi,

You can define permissions to your clients without requiring an account token.

https://abp.io/docs/latest/framework/fundamentals/authorization#permission-value-providers

ABP has ClientPermissionValueProvider implementation by default and you can give permissions to specific client. ClientId will be retrieved from AbpClaimTypes.ClientId claim.

Or, if you wish you can have a custom implementation:

public class SystemAdminPermissionValueProvider : PermissionValueProvider, ITransientDependency
{
    public SystemAdminPermissionValueProvider(IPermissionStore permissionStore)
        : base(permissionStore)
    {
    }

    public override string Name => "SystemAdmin";

    public async override Task<PermissionGrantResult>
           CheckAsync(PermissionValueCheckContext context)
    {
        // Anything you want to check
        if (context.Principal?.FindFirst("User_Type")?.Value == "SystemAdmin")
        {
            return PermissionGrantResult.Granted;
        }

        return PermissionGrantResult.Undefined;
    }
}

-or-

If permissions and claims is not good at your case, you can check IntegrationServices. Integration services are built for inter-service communication and cannot be consumed from clients.You can check the documentation about more information and use-cases: https://abp.io/docs/latest/framework/api-development/integration-services

Hello @k-s-c,

Thanks for reaching out and providing such a clear description of your setup and the issue you're facing. This "Unauthorized" error in a tiered application with an API Gateway is a classic scenario, and we can definitely help you debug it.

Based on your description, the problem lies in the authentication flow between your Public Gateway and your Host API, specifically concerning JWT token validation when requests are proxied from HTTPS to HTTP.

Let's break down the potential causes and how to diagnose them:

1. RequireHttpsMetadata = false (Revisit this carefully!)

You've correctly identified RequireHttpsMetadata = false on the JwtBearerOptions as a potential fix for the Host API. This setting is crucial when your IdentityServer (which is your Host API in this case, acting as the token issuer) issues tokens with an iss (issuer) claim that is an HTTPS URL, but the token is then validated by an API (your Host API, when accessed via the gateway) that receives the request over HTTP.

Action:

  • Verify the iss claim: Inspect a JWT token issued by your Host API (you can get one from the working Swagger UI on the Host API, or by logging in from your MVC app). What is the value of the iss claim? If it's https://your-gateway-domain/, and your Host API is receiving requests over http://localhost:port/, then RequireHttpsMetadata = false is indeed necessary on the Host API's AddJwtBearer configuration.

  • Double-check placement: Ensure RequireHttpsMetadata = false is applied correctly within the ConfigureServices method of your Host API:

    C#

    context.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
        .AddJwtBearer(options =>
        {
            options.Authority = "https://your-gateway-domain/"; // Or your Host API's public URL if it's directly accessible for discovery
            options.RequireHttpsMetadata = false; // &lt;-- This is the key
            options.Audience = &quot;YourProjectName_Host&quot;; // Or the audience of your Host API
        });
    

    Note: options.Authority should point to the public URL where the IdentityServer discovery document can be found, which would typically be your Public Gateway's HTTPS URL.

2. Audience Mismatch

Both the Public Gateway (if it validates) and the Host API must be configured to accept the correct audience (aud claim) in the JWT token. The audience for your Host API is typically its own unique identifier (e.g., &quot;YourProjectName_Host&quot;).

Action:

  • Check OpenIddict configuration: In your Host API's PreConfigureServices, where you configure OpenIddict (ABP's default IdentityServer), ensure the client configuration for your Web MVC app (and any other clients) requests the correct scope/audience:

    C#

    PreConfigure&lt;OpenIddictBuilder&gt;(builder =>
    {
        builder.AddValidation(options =>
        {
            options.AddAudiences("YourApplicationName");
            options.UseLocalServer();
            options.UseAspNetCore();
        });
    });
    
  • Check client applications: Verify that your Web MVC application (or any client obtaining a token) is requesting the "YourProjectName_Host" scope.

  • Check appsettings.json in the DbMigrator: ABP layered template has data seeding logic with DbMigrator. Make sure your credentials is correct in the appsettings.json inside YourProjectName.DbMigrator folder and then execute DbMigrator once when your credentials ready to publish. ⚠️ The production database should be properly migrated

  • Check OpenIddictDataSeedContributor if any change requiremens: In the Domain project you'll see OpenIddict\OpenIddictDataSeedContributor.cs file that seeds all the openiddict configuration to the database. Check there and make sure all of your clients are added there.

3. Swagger UI and Token Injection

When using Swagger UI on the Public Gateway, the "Authorize" button injects the bearer token. The issue here might be how Swagger on the Gateway handles this, or if the token it's using is somehow different or malformed when forwarded.

Action:

  • Inspect Network Calls: Using your browser's developer tools (F12), go to the Network tab on the Swagger UI page of your Public Gateway.
    • Check the request headers: When you try to execute an endpoint, look at the Authorization header. Is the bearer token present? Is it the correct token?
    • Check the response: What is the exact response from the gateway? Is it a 401 directly from the gateway, or is it a 401 relayed from the Host API? This distinction is critical for debugging. If the gateway sends 401, the token validation failed at the gateway. If the Host API sends 401, the token validation failed at the Host API after the gateway forwarded it.

4. Logging (Your Best Friend!)

Enable detailed logging on both your Public Gateway and your Host API. Look for logs related to authentication, JWT validation, and authorization.

Action:

  • Configure Serilog (or default logging): Ensure appsettings.json has sufficient logging levels:JSON

    "Serilog": {
      "MinimumLevel": {
        "Default": "Information",
        "Override": {
          "Microsoft": "Warning",
          "System": "Warning",
          "OpenIddict": "Debug", // Very useful for token validation issues
          "Microsoft.AspNetCore.Authentication": "Debug", // Also very useful
          "Volo.Abp": "Information"
        }
      }
    }
    
  • Examine logs: Look for messages like "token validation failed," "issuer not found," "invalid audience," or "signature validation failed."

Troubleshooting Steps (Order of operations I'd recommend):

  1. Isolate the Host API: Can you directly call an authenticated endpoint on your Host API (bypassing the Public Gateway) with a valid token obtained from the Host API's own Swagger or by logging in? If this works, the Host API's authentication is correct in isolation.
  2. Inspect Token from Gateway Swagger: Get a token via the Public Gateway's Swagger "Authorize" button. Paste this token into jwt.io.
    • What are the iss (issuer), aud (audience), and exp (expiration) claims?
    • Are the scopes correct?
  3. Network Trace: Use tools like Fiddler, Wireshark, or the browser's developer tools to trace the exact HTTP requests and responses between the Gateway and the Host API. This will show you exactly what headers are being sent (including Authorization).

Example Scenario and Solution:

Often, the problem is that the Host API is configured to expect Authority = "https://public-gateway-domain/" (because that's where the discovery document is publicly available), but it's receiving requests over HTTP internally (from the gateway). In this case, RequireHttpsMetadata = false is critical on the Host API's JwtBearerOptions.

Let me know the results of these checks, especially the network tab analysis and any relevant log messages. With more details, we can narrow down the exact cause.

Best regards,

ABP Client-proxies use IHttpClientFactory to create HttpClient objects and it uses RemoteServiceName to create HttpClient for each of your remote service.

https://github.com/abpframework/abp/blob/9a43b9c9dfbc8b883c58a7acdb9c21619aa48dfc/framework/src/Volo.Abp.Http.Client/Volo/Abp/Http/Client/ClientProxying/ClientProxyBase.cs#L124

So you can easily use freshly defined a new HttpClient for your service:

context.Services.AddHttpClient("YourService") // Administrator, Identity etc.
    .ConfigureHttpClient(client =>
    {
        client.BaseAddress = new Uri("https://api.example.com/");
        client.Timeout = TimeSpan.FromMinutes(2);
    });

This defines a new HttpClient instead trying to configure existing one, you can have all control on the HttpClient in this way

The error shows the permission isn't granted for the current request / current authenticated user. A couple of reasons can cause this issue:

  1. The user really don't have the permission.

  2. The cookie/token might be obsolete or created by another authentication server or application itself, you can try to clear cookies and everything and authenticate again from scratch.

  3. If you deployment is distributed, you can also try clearing Redis cache, since permissions are cached in Redis in distributed solutions. The cached data might be wrong, outdated or corrupted.

Hi,

You have to create client-proxies into HttpApi.Client project:

Otherwise, you replace the original ApplicationService implementation and it cannot work. Whenever you need to consume by using client-proxies, you'll need to use HttpApi.Client and Application.Contracts project reference and use interfaces of your AppServices. Whenever you inject that interface, it'll use ClientProxy if the project has HttpApi.Client reference.

Hi,

We cannot know what is the exact reason of this behaviour.

Can you enable debug logs to check detailed logs to determine what is happenning exactly by following this steps:

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

I think this is a similar case:

https://abp.io/support/questions/8325/How-to-increase-http-client-timeout

Can you try increasing YARP timeout from your Gateway, since gateway doesn't use ABP's client-proxy, it's a standalone proxy implementation by dotnet

Whenever you create a new project there'll be already a file for that purpose with an example:

  • For Module extension:

  • And Entity extension: (if you choosed EntityFrameworkCore)


You can uncomment that examnples and ready to go, there'll be no other changes. If you configured any EntityExtension, you'll need to create a database migration.

If you are not familiar with CLI commands you can do it in ABP Studio UI:

And that's it you'll see the new migration:

  • Run .DbMigrator project

  • Run .Web project

Hi,

Can you try running it on a different port by modifying appsettings.json with the following steps: https://abp.io/qa/questions/8189/3a15f274-2ef1-f039-e08c-32c2e6f25853

Answer

Hi,

When I run swagger it gives me this error:

Thanks.

Do you use a gateway or directly calling the service?

Also please check logs of the application it provide information about the problem. You can share with us the logs

Showing 41 to 50 of 779 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 October 30, 2025, 06:33