Open Closed

Best practice backgroud job in a microservices environment #7261


User avatar
0
andmattia created

We work on a mircroservice applicaction.

I have a function on service 2 (for sending message) that can be use from UI (user can send message) or via backgroud job (every x mins check if I've message to send).

If I try to send message via UI my user is valid and I can pass the token from service 1 -> service 2 but when I try to run it on background job it doesn't work. So it works correctly because background is different process/thread so it don't have an authenticated context.

My question wich is the correct configuration for allow my service 1 work for users and jobs? Is it possibile or I need to move my job in a different service?


3 Answer(s)
  • User Avatar
    0
    liangshiwei created
    Support Team Fullstack Developer

    Hi,

    You can change the current user context. For example:

    public class MyBackgroundJob : AsyncBackgroundJob<MyBackgroundJobArgs>
    {
        private readonly ICurrentPrincipalAccessor _principalAccessor;
        private readonly IdentityUserManager _identityUserManager;
    
        public MyBackgroundJob(ICurrentPrincipalAccessor principalAccessor, IdentityUserManager identityUserManager)
        {
            _principalAccessor = principalAccessor;
            _identityUserManager = identityUserManager;
        }
    
        public override async Task ExecuteAsync(MyBackgroundJobArgs args)
        {
            // get messages....
            var messages = ....;
            using (_principalAccessor.Change(await CreateUserClaimsPrincipalFromMessagesAsync(messages)))
            {
                //send messages here...
            }
        }
    
        private async Task<ClaimsPrincipal> CreateUserClaimsPrincipalFromMessagesAsync(messages...)
        {
            var user = await  _identityUserManager.FindByNameAsync(messages.UserName);
            var roles = await _identityUserManager.GetRolesAsync(user);
            var claims = new List<Claim>
            {
                new Claim(AbpClaimTypes.UserId, user.Id.ToString()),
                new Claim(AbpClaimTypes.UserName, user.UserName),
                new Claim(AbpClaimTypes.Email,user.Email),
                new Claim(AbpClaimTypes.TenantId,user.TenantId?.ToString()),
            };
            claims.AddRange(roles.Select(x => new Claim(AbpClaimTypes.Role, x)));
            return new ClaimsPrincipal(new ClaimsIdentity(claims));
        }
    }
    
  • User Avatar
    0
    andmattia created

    Hi

    great suggestion to solve this case.

    But generally speaking which is the best practice to execute operation via backgroud job in a microservice env?

    In my case my service has complete different db so it doesn't access to abpUser / abpRole table

  • User Avatar
    0
    liangshiwei created
    Support Team Fullstack Developer

    In my case my service has complete different db so it doesn't access to abpUser / abpRole table

    you may need this https://docs.abp.io/en/commercial/latest/startup-templates/microservice/interservice-communication

Made with ❤️ on ABP v9.1.0-preview. Updated on December 13, 2024, 06:09