Open Closed

Inter-App Communication with Authentication #9370


User avatar
0
berly created

Hello ABP Team,

In our project, we have two independent ASP.NET Core applications built with the ABP Framework: APP1 and APP2.

We successfully set up inter-application communication using ABP dynamic HTTP client proxies and REST APIs exposed by Marylease. The communication is functional and relies on a shared contract project (APP2.Application.Contracts), without any authentication for now.

🎯 Goal We would like to secure this communication by enabling OAuth2 authentication using the Client Credentials flow, but without enforcing any permission or role checks on APP1's side.

The main objective is simply to ensure that only the APP1 client is authorized to call APP2 services, without implementing full ABP permission management.

public class APP1ApplicationModule : AbpModule
{
    public override void ConfigureServices(ServiceConfigurationContext context)
    {
        Configure<AbpAutoMapperOptions>(options => { options.AddMaps<APP1ApplicationModule>(); });
        context.Services.AddHttpClientProxies(
            typeof(IHelloMaryleaseAppService)
                .Assembly, 
            "APP2"
        );
    }
}

5 Answer(s)
  • User Avatar
    0
    enisn created
    Support Team .NET Developer

    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

  • User Avatar
    0
    berly created

    Here's how APP1 currently accesses APP2's remote service, and we'd like to maintain this simplicity:

    // In APP1 (Client - Blazor Server)
    public class MyLocalApp1Service : App1ServiceBase, IMyLocalApp1Service
    {
        private readonly IApp2RemoteService _app2RemoteServiceProxy; // Interface from APP2.Application.Contracts
    
        public MyLocalApp1Service(IApp2RemoteService app2RemoteServiceProxy) // Proxy injection
        {
            _app2RemoteServiceProxy = app2RemoteServiceProxy;
        }
    
        public async Task<ResultDto> CallApp2ServiceAsync()
        {
            // We want authentication to be handled automatically here
            var resultFromApp2 = await _app2RemoteServiceProxy.SomeMethodOnApp2Async();
            // ... process result ...
            return resultFromApp2;
        }
    }
    

    Our main question is:

    How can we configure APP1 (the client) to authenticate automatically (obtain and use a token via Client Credentials) when using dynamic HTTP client proxies (like IApp2RemoteService in the example), without APP1's application code (like MyLocalApp1Service) having to explicitly manage the authentication process? Is there a specific configuration or "handler" in ABP's HTTP client pipeline that enables this transparently for the caller?

    We've reviewed the documentation and previous discussions regarding ClientPermissionValueProvider for the authorization part on APP2, which is clear. However, we're specifically looking for guidance on the APP1 client-side configuration to ensure that injecting and calling the remote service interface handles authentication "under the hood."

    We are not planning to use Integration Services at this time, as some APIs will be shared and need to remain standard, visible, and authenticated REST APIs.

    Could you please point us to the recommended configuration or an example illustrating this transparent handling of Client Credentials authentication for dynamic HTTP client proxies?

    We are willing to share our current functional repository, which includes a docker-compose.yml setup for launching the environment (two ABP Blazor Server projects with APP1 referencing APP2's Application.Contracts layer), if that would help. A small Proof of Concept (POC) demonstrating a remote call similar to what we've achieved, but with very basic authentication added, would be incredibly helpful.

    Thankscontinuity for your assistance.

    Best regards,

    Vivien

  • User Avatar
    0
    enisn created
    Support Team .NET Developer

    Hi,

    My suggestion will be to use Integration Service by default but it seems you already have your endpoints, and you'll consume your existing endpoints and you won't create a new services for those operations.

    Here is how you can approach:

    • When you create a new project with including tests, you'll see an application named YourProjectName.HttpApi.Client.ConsoleTestApp under tests folder. You can check that implementation. It's configured to authenticate itself automatically with a user and it uses token on each request sent over application services. You see credentials for this client in appsettings.json:

    It directly inject client-proxy implementation of an app service interface and consumes APIs like it's admin user (or which user you define in the appsettings.json)

    This might help. Can you check this logic. If your solution doesn't have this application, you can try creating it with the latest version of ABP to check this test application

  • User Avatar
    0
    berly created

    Thank you very much — it works perfectly now! I had mistakenly referenced the Application.Contracts project instead of the HttpApi.Client one.

    Here is the configuration I currently have:

    It uses the admin user account (which I don’t think is the best approach).

    "IdentityClients": {
      "Marylease": {
        "GrantType": "password",
        "ClientId": "APP2_App",
        "UserName": "admin",
        "UserPassword": "1q2w3E*",
        "Authority": "https://localhost:44335",
        "Scope": "APP2"
      }
    }
    

    So my question is: what would be the best practice in this case?

  • User Avatar
    0
    enisn created
    Support Team .NET Developer

    Hi,

    Service Account Authentication

    The best practice for server-to-server communication mostly depends on security, scalability, and maintainability requirements. Instead of using the default admin user you can use separate users and specific permissions for your each application. So you can easily track in audit logs and separately manage their permissions etc. You can use dedicated account for each service.

    Instead of using an admin user account, it's recommended to use OAuth 2.0 Client Credentials Flow, where the server authenticates itself using a client ID and secret rather than a user’s credentials. Since ABP does not implement OpenID flows itself and uses OpenIddict open source library, you can check its own documentation from here: https://documentation.openiddict.com/guides/choosing-the-right-flow.html

    Integration Services

    The current approach is not anti-pattern or a bad-practise, but as an alternative we recommend using Integration Service in ABP Framework but it'll bring some extra development cost, you'll create similar integration services for all of your application services. Against this development cost, you can consume your existing app services as an user from your other servers.

    ApiKey Authentication

    There is another alternative approach which is Api-Key approach. This is widely used in the web, but ABP doesn't have a built-in api-key management system, you can use hard-coded API-keys and validate them in a middleware. But this brings much more development cost since ABP doesn't help you on this topic.

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 v9.3.0-preview. Updated on June 13, 2025, 11:37