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?
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
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"
);
}
}
Hi, I didn't have Yarn installed, once the installation was done I recovered all the libs.
I just sent it to you, did you receive it?
I tried but I didn't get any new libs
Here is the file : { "version": "1.0.0", "name": "my-app", "private": true, "dependencies": { "@volo/language-management": "~9.0.0", "@volo/file-management": "~9.0.0", "@volo/chat": "~9.0.0", "@volo/account": "~9.0.0", "@volo/abp.aspnetcore.mvc.ui.theme.leptonx": "~4.0.0", "@volo/aspnetcore.components.server.leptonxtheme": "~4.0.0" } }
I didn't do anything specific, I created the project via the abp studio CLI.
[10:42:08 ERR] An unhandled exception has occurred while executing the request.
Volo.Abp.AbpException: Could not find file '/libs/bootstrap/css/bootstrap.css'
at Volo.Abp.AspNetCore.Mvc.UI.Bundling.BundlerBase.GetFileInfo(IBundlerContext context, String file)
at Volo.Abp.AspNetCore.Mvc.UI.Bundling.BundlerBase.GetAndMinifyFileContent(IBundlerContext context, String fileName)
at Volo.Abp.AspNetCore.Mvc.UI.Bundling.BundlerBase.GetFileContentConsideringMinification(IBundlerContext context, String fileName)
at Volo.Abp.AspNetCore.Mvc.UI.Bundling.BundlerBase.AddFileToBundle(IBundlerContext context, StringBuilder bundleContentBuilder, String fileName)
at Volo.Abp.AspNetCore.Mvc.UI.Bundling.BundlerBase.Bundle(IBundlerContext context)
at Volo.Abp.AspNetCore.Mvc.UI.Bundling.BundleManager.<>c__DisplayClass17_0.<AddToBundleCache>b__0()
at System.Collections.Generic.AbpDictionaryExtensions.<>c__DisplayClass7_0`2.<GetOrAdd>b__0(TKey k)
at System.Collections.Concurrent.ConcurrentDictionary`2.GetOrAdd(TKey key, Func`2 valueFactory)
at System.Collections.Generic.AbpDictionaryExtensions.GetOrAdd[TKey,TValue](ConcurrentDictionary`2 dictionary, TKey key, Func`1 factory)
at Volo.Abp.AspNetCore.Mvc.UI.Bundling.BundleCache.GetOrAdd(String bundleName, Func`1 factory)
at Volo.Abp.AspNetCore.Mvc.UI.Bundling.BundleManager.AddToBundleCache(String bundleName, IBundler bundler, List`1 bundleFiles)
at Volo.Abp.AspNetCore.Mvc.UI.Bundling.BundleManager.GetBundleFilesAsync(BundleConfigurationCollection bundles, String bundleName, IBundler bundler)
at Volo.Abp.AspNetCore.Mvc.UI.Bundling.BundleManager.GetStyleBundleFilesAsync(String bundleName)
at Volo.Abp.AspNetCore.Mvc.UI.Bundling.TagHelpers.AbpTagHelperStyleService.GetBundleFilesAsync(String bundleName)
at Volo.Abp.AspNetCore.Mvc.UI.Bundling.TagHelpers.AbpTagHelperResourceService.ProcessAsync(ViewContext viewContext, TagHelper tagHelper, TagHelperContext context, TagHelperOutput output, List`1 bundleItems, String bundleName)
at Volo.Abp.AspNetCore.Mvc.UI.Bundling.TagHelpers.AbpBundleTagHelperService`2.ProcessAsync(TagHelperContext context, TagHelperOutput output)
at Microsoft.AspNetCore.Razor.Runtime.TagHelpers.TagHelperRunner.<RunAsync>g__Awaited|0_0(Task task, TagHelperExecutionContext executionContext, Int32 i, Int32 count)
at Manuloc.AccuseReceptionCommande.Blazor.Pages.Pages__Host.<ExecuteAsync>b__18_0()
at Microsoft.AspNetCore.Razor.Runtime.TagHelpers.TagHelperExecutionContext.SetOutputContentAsync()
at Manuloc.AccuseReceptionCommande.Blazor.Pages.Pages__Host.ExecuteAsync() in /src/src/Manuloc.AccuseReceptionCommande.Blazor/Pages/_Host.cshtml:line 9
at Microsoft.AspNetCore.Mvc.Razor.RazorView.RenderPageCoreAsync(IRazorPage page, ViewContext context)
at Microsoft.AspNetCore.Mvc.Razor.RazorView.RenderPageAsync(IRazorPage page, ViewContext context, Boolean invokeViewStarts)
at Microsoft.AspNetCore.Mvc.Razor.RazorView.RenderAsync(ViewContext context)
at Microsoft.AspNetCore.Mvc.ViewFeatures.ViewExecutor.ExecuteAsync(ViewContext viewContext, String contentType, Nullable`1 statusCode)
at Microsoft.AspNetCore.Mvc.ViewFeatures.ViewExecutor.ExecuteAsync(ViewContext viewContext, String contentType, Nullable`1 statusCode)
at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeNextResultFilterAsync>g__Awaited|30_0[TFilter,TFilterAsync](ResourceInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted)
at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.Rethrow(ResultExecutedContextSealed context)
at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.ResultNext[TFilter,TFilterAsync](State& next, Scope& scope, Object& state, Boolean& isCompleted)
at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.InvokeResultFilters()
--- End of stack trace from previous location ---
at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeNextResourceFilter>g__Awaited|25_0(ResourceInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted)
at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.Rethrow(ResourceExecutedContextSealed context)
at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.Next(State& next, Scope& scope, Object& state, Boolean& isCompleted)
at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.InvokeFilterPipelineAsync()
--- End of stack trace from previous location ---
at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeAsync>g__Logged|17_1(ResourceInvoker invoker)
at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeAsync>g__Logged|17_1(ResourceInvoker invoker)
at Microsoft.AspNetCore.Routing.EndpointMiddleware.<Invoke>g__AwaitRequestTask|7_0(Endpoint endpoint, Task requestTask, ILogger logger)
at Volo.Abp.AspNetCore.Serilog.AbpSerilogMiddleware.InvokeAsync(HttpContext context, RequestDelegate next)
at Microsoft.AspNetCore.Builder.UseMiddlewareExtensions.InterfaceMiddlewareBinder.<>c__DisplayClass2_0.<<CreateMiddleware>b__0>d.MoveNext()
--- End of stack trace from previous location ---
at Volo.Abp.AspNetCore.Auditing.AbpAuditingMiddleware.InvokeAsync(HttpContext context, RequestDelegate next)
at Volo.Abp.AspNetCore.Auditing.AbpAuditingMiddleware.InvokeAsync(HttpContext context, RequestDelegate next)
at Microsoft.AspNetCore.Builder.UseMiddlewareExtensions.InterfaceMiddlewareBinder.<>c__DisplayClass2_0.<<CreateMiddleware>b__0>d.MoveNext()
--- End of stack trace from previous location ---
at Swashbuckle.AspNetCore.SwaggerUI.SwaggerUIMiddleware.Invoke(HttpContext httpContext)
at Swashbuckle.AspNetCore.Swagger.SwaggerMiddleware.Invoke(HttpContext httpContext, ISwaggerProvider swaggerProvider)
at Microsoft.AspNetCore.Authorization.AuthorizationMiddleware.Invoke(HttpContext context)
at Volo.Abp.AspNetCore.Security.Claims.AbpDynamicClaimsMiddleware.InvokeAsync(HttpContext context, RequestDelegate next)
at Microsoft.AspNetCore.Builder.UseMiddlewareExtensions.InterfaceMiddlewareBinder.<>c__DisplayClass2_0.<<CreateMiddleware>b__0>d.MoveNext()
--- End of stack trace from previous location ---
at Volo.Abp.AspNetCore.Uow.AbpUnitOfWorkMiddleware.InvokeAsync(HttpContext context, RequestDelegate next)
at Microsoft.AspNetCore.Builder.UseMiddlewareExtensions.InterfaceMiddlewareBinder.<>c__DisplayClass2_0.<<CreateMiddleware>b__0>d.MoveNext()
--- End of stack trace from previous location ---
at Volo.Abp.AspNetCore.ExceptionHandling.AbpExceptionHandlingMiddleware.InvokeAsync(HttpContext context, RequestDelegate next)
at Volo.Abp.AspNetCore.ExceptionHandling.AbpExceptionHandlingMiddleware.InvokeAsync(HttpContext context, RequestDelegate next)
at Microsoft.AspNetCore.Builder.UseMiddlewareExtensions.InterfaceMiddlewareBinder.<>c__DisplayClass2_0.<<CreateMiddleware>b__0>d.MoveNext()
--- End of stack trace from previous location ---
at Volo.Abp.AspNetCore.MultiTenancy.MultiTenancyMiddleware.InvokeAsync(HttpContext context, RequestDelegate next)
at Microsoft.AspNetCore.Builder.UseMiddlewareExtensions.InterfaceMiddlewareBinder.<>c__DisplayClass2_0.<<CreateMiddleware>b__0>d.MoveNext()
--- End of stack trace from previous location ---
at Microsoft.AspNetCore.Builder.ApplicationBuilderAbpOpenIddictMiddlewareExtension.<>c__DisplayClass0_0.<<UseAbpOpenIddictValidation>b__0>d.MoveNext()
--- End of stack trace from previous location ---
at Microsoft.AspNetCore.Authentication.AuthenticationMiddleware.Invoke(HttpContext context)
at Volo.Abp.AspNetCore.Security.AbpSecurityHeadersMiddleware.InvokeAsync(HttpContext context, RequestDelegate next)
at Microsoft.AspNetCore.Builder.UseMiddlewareExtensions.InterfaceMiddlewareBinder.<>c__DisplayClass2_0.<<CreateMiddleware>b__0>d.MoveNext()
--- End of stack trace from previous location ---
at Volo.Abp.Studio.Client.AspNetCore.AbpStudioMiddleware.InvokeAsync(HttpContext context, RequestDelegate next)
at Volo.Abp.Studio.Client.AspNetCore.AbpStudioMiddleware.InvokeAsync(HttpContext context, RequestDelegate next)
at Volo.Abp.Studio.Client.AspNetCore.AbpStudioMiddleware.InvokeAsync(HttpContext context, RequestDelegate next)
at Microsoft.AspNetCore.Builder.UseMiddlewareExtensions.InterfaceMiddlewareBinder.<>c__DisplayClass2_0.<<CreateMiddleware>b__0>d.MoveNext()
--- End of stack trace from previous location ---
at Volo.Abp.AspNetCore.Tracing.AbpCorrelationIdMiddleware.InvokeAsync(HttpContext context, RequestDelegate next)
at Microsoft.AspNetCore.Builder.UseMiddlewareExtensions.InterfaceMiddlewareBinder.<>c__DisplayClass2_0.<<CreateMiddleware>b__0>d.MoveNext()
--- End of stack trace from previous location ---
at Microsoft.AspNetCore.Diagnostics.ExceptionHandlerMiddlewareImpl.<Invoke>g__Awaited|10_0(ExceptionHandlerMiddlewareImpl middleware, HttpContext context, Task task)
I don't find the file in Project.Blazor\wwwroot\libs
When I compare with my old projects I am missing a lot of files in the LIB folder.
I did the abp install lib command correctly