Hi
I have issue with distributed event handlers. I am using monoltih deloyment with RabbitMQ enabled. If event handler tryes to call application service, which have authorization attribute enabled, then it gets AbpAuthorizationException.
How this issue can be resolved in ABP?
- ABP Framework version: v4.3rc1
- UI type: Angular
- DB provider: EF Core
- Tiered (MVC) or Identity Server Separated (Angular): yes
- Exception message and stack trace:
- Steps to reproduce the issue:
12 Answer(s)
- 
    0hi Don't call application service in event handler. You can call the domain service that without the Authorization.
- 
    0hi Don't call application service in event handler. You can call the domain service that without the Authorization.I can not move Application Service logic into Domain Service because endpoint is implemented by another Module. Event Handler in module A pulls some data from module B using its endpoint 
- 
    0Can you share some code of your event handler? 
- 
    0Sure. There is simple example of BackgroundJob in my module public class UserStatBackgroundJob : IAsyncBackgroundJob<Object> { private readonly IUserLookupService<AppUser> _userLookupService; public UserStatBackgroundJob(IUserLookupService<AppUser> userLookupService) { _userLookupService = userLookupService; } public async Task ExecuteAsync(Object args) { long userCount = await _userLookupService.GetCountAsync(); //usage of userCount } }
- 
    0hi @Denis You can check the Dynamic-CSharp-API-Clients, It has built-in authentication.https://docs.abp.io/en/abp/latest/API/Dynamic-CSharp-API-Clients https://github.com/abpframework/abp/blob/dev/framework/src/Volo.Abp.IdentityModel/Volo/Abp/IdentityModel/IdentityModelAuthenticationService.cs#L22 https://github.com/abpframework/abp/blob/dev/framework/src/Volo.Abp.Http.Client.IdentityModel/Volo/Abp/Http/Client/IdentityModel/IdentityModelRemoteServiceHttpClientAuthenticator.cs#L21 https://github.com/abpframework/abp/blob/dev/framework/src/Volo.Abp.Http.Client.IdentityModel.Web/Volo/Abp/Http/Client/IdentityModel/Web/HttpContextIdentityModelRemoteServiceHttpClientAuthenticator.cs#L45 https://github.com/abpframework/abp/blob/dev/templates/app/aspnet-core/test/MyCompanyName.MyProjectName.HttpApi.Client.ConsoleTestApp/appsettings.json#L7 https://github.com/abpframework/abp/blob/dev/templates/app/aspnet-core/test/MyCompanyName.MyProjectName.HttpApi.Client.ConsoleTestApp/ClientDemoService.cs#L19 
- 
    0Hi @maliming Can you please explain, how I can do authorization in event handler? I mean that I need to reach the same result as on endpoint execution. Before endpoint executed there is middleware doing authorization. I would like to make that in scope of event handlers 
- 
    0hi As you can see. There is a console app. that call the IProfileAppServicewhich requires authentication and authorization,It will use the identity server to get the token, and then call the web api corresponding to IProfileAppService.https://github.com/abpframework/abp/blob/dev/templates/app/aspnet-core/test/MyCompanyName.MyProjectName.HttpApi.Client.ConsoleTestApp/appsettings.json#L7 You can call application services in a similar way in your event handler or background job/work. 
- 
    0Hi Sorriy, but I could not find what you wrote about on page provided by link. Can you please send link to source of project you talking about? Also I would want to give more details about by question. I would like to not bind to http client proxy implementation of application services, so calls will be done via HTTP always for any deployment: monolith or microservices. I want to keep event handlers without changes, but also implement Attribute for authentication and authorization, at same way as that done in middleware which is called before endpoint execution. This Attribute will use JWT token provided in app configuration. Execution authorization will be done before event handler call, in the way as it is done in ABP middleware before endpoint execution, so all application services in monolith will be called directly in runtime, as that would be done by another application service during endpoint execution. In short - I want CurrentUser and CurrentTenant will be provided before event handler execution 
- 
    0Sorriy, but I could not find what you wrote about on page provided by link. Can you please send link to source of project you talking about? If you create an app project, you will find a HttpApi.Client.ConsoleTestAppproject, which will call the application service that requires authorization. It is done automatically in theConsoleTestAppproject. You can think of it as event handler or background job/work.In a monolithic application, it will directly use application services, and in tiered or microservices, it will automatically call web api. In short - I want CurrentUser and CurrentTenant will be provided before event handler execution I don't fully understand, can you share some code? 
- 
    0Sure. The same as in endpoint. CurrentUser is materizled from JWT token which passed to event data or in appsettings public class UserStatBackgroundJob : IAsyncBackgroundJob<Object> { private readonly IUserLookupService<AppUser> _userLookupService; ICurrentUser _currentUser; <<-------- public UserStatBackgroundJob(IUserLookupService<AppUser> userLookupService, ICurrentUser currentUser) { _userLookupService = userLookupService; _currentUser = currentUser <<------- } public async Task ExecuteAsync(Object args) { long userCount = await _userLookupService.GetCountAsync(); var userName = currentUser.Name; <<--------- //usage of userCount } }
- 
    0hi I think you can change the tenant, but change the user is currently impossible. using (CurrentTenant.Change(tenantId)) { long userCount = await _userLookupService.GetCountAsync(); }
- 
    0This question has been automatically marked as stale because it has not had recent activity. 
 
                                