Open Closed

I need to access AppService from RabbitMQ receiver. But I am getting exception on Authorize attribute #4264


User avatar
0
alexander.nikonov created
  • ABP Framework version: v5.1.2
  • UI type: Angular
  • DB provider: EF Core
  • Identity Server Separated (Angular)

What is correct way to authorize RabbitMQ user so that I could invoke AppService methods from RabbitMQ receiver or sender? In the meantime both CurrentTenant and CurrentUser are null. Please write the example of the code.


7 Answer(s)
  • User Avatar
    0
    maliming created
    Support Team Fullstack Developer

    hi

    Are you a tiered project or a monolithic project?

    AppService should not be called in scenarios such as background jobs. You can consider calling domain services.

  • User Avatar
    0
    alexander.nikonov created

    I have a separate IdentityServer.

    One of the projects has RabbitMQ receiver, where all other projects send the data too. This receiver needs to insert data into DB based on the received RabbitMQ input and it uses INotificationAppService in the same project to do that. See the code below.

    When I do not use Authorization attribute - it of course works OK. But I want to make it work secure - i.e. if I do not use typical request authorization (since there is no request in question here) RabbitMQ needs to be trusted somehow inside AppService.

    So what are your proposals again - even if you mean not to use AppService at all here? Could you please write a couple of code lines to describe the idea?

    public override async Task<object> Received(BasicDeliverEventArgs @event)
    {
        var notificationCacheRabbitMqEto = @event.ToDataObject<NotificationRabbitMqEto>();
    
        var hubContext = _serviceProvider.GetService<IHubContext<NotificationHub>>();
    
        using (var scope = _serviceProvider.CreateScope())
        {
            try
            {
                var notificationAppService = scope.ServiceProvider.GetRequiredService<INotificationAppService>();
                var newNotification = await notificationAppService.CreateAsync(new NotificationCreateDto
                {
                    TenantId = notificationCacheRabbitMqEto.TenantId,
                    Login = notificationCacheRabbitMqEto.Login,
                    Level = (int)notificationCacheRabbitMqEto.Level,
                    Title = notificationCacheRabbitMqEto.Title,
                    Details = notificationCacheRabbitMqEto.Details,
                    IsActive = true,
                    IsImportant = notificationCacheRabbitMqEto.IsImportant,
                    CreatorName = GetTrimmedCreatorName(notificationCacheRabbitMqEto.Login), //Like so?
                    LastModifierName = GetTrimmedCreatorName(notificationCacheRabbitMqEto.Login) //Like so?
                });
    
                await hubContext.Clients.Group(notificationCacheRabbitMqEto.Login).SendAsync("notificationReceived", newNotification);
            }
            catch (Exception ex)
            {
                Log.Error(ex.Message);
            }
        }
    
        return Task.FromResult<object>(null);
    }
        
    [RemoteService(IsEnabled = false)]
    //[Authorize]
    public class NotificationAppService : INotificationAppService
    {
        private readonly IServiceProvider _serviceProvider;
        private readonly INotificationRepository _notificationRepository;
        private readonly IStringLocalizer<CommonUIResource> _stringLocalizer;
        private readonly IUnitOfWorkManager _unitOfWorkManager;
        private readonly IObjectMapper _objectMapper;
    
        public NotificationAppService
        (
            IServiceProvider serviceProvider,
            INotificationRepository notificationRepository,
            IStringLocalizer<CommonUIResource> stringLocalizer,
            IUnitOfWorkManager unitOfWorkManager,
            IObjectMapper objectMapper
        )
        {
            _serviceProvider = serviceProvider;
            _notificationRepository = notificationRepository;
            _stringLocalizer = stringLocalizer;
            _unitOfWorkManager = unitOfWorkManager;
            _objectMapper = objectMapper;
        }
        ...
    }
    
    public interface INotificationAppService : IApplicationService, ITransientDependency {
        ...
    }
    
  • User Avatar
    0
    maliming created
    Support Team Fullstack Developer

    It's hard to handle things like authentication and authorization in methods.

    You can inject repository(https://docs.abp.io/en/abp/latest/Repositories) to insert in the Received method, or domain services that use repository (https://docs.abp.io/en/abp/latest/Domain-Services)

  • User Avatar
    0
    alexander.nikonov created

    Even if I use DomainService or Repository directly - how will it differ from using IApplicationService in the way I used it in terms of trust? I really need kind of pass "trust" from Received method into AppService (or other level) method where I would act on behalf of this user which usually is an authenticated ICurrentUser if used from frontend application. What I have at my disposal is just this user's Id and Tenant inside Received method.

  • User Avatar
    0
    maliming created
    Support Team Fullstack Developer

    ApplicationService is mainly designed for UI, and it also exposes http endpoints. So there is an trust problem.

    You don't have this problem if you use domain services in your code.

  • User Avatar
    0
    alexander.nikonov created

    Or, I can keep using AppService - with RemoteService(IsEnabled = false)] as mentioned in my code, right? I do not expose NotificationAppService outside. In such case there's no difference between using it or converting it to DomainService, as far as I understand. I even don't inherit ApplicationService class...

  • User Avatar
    0
    maliming created
    Support Team Fullstack Developer

    hi

    You can move the business code into a service, and then use this service in the application service and Received method.

Made with ❤️ on ABP v8.2.0-preview Updated on March 25, 2024, 15:11