Hi,
We are trying to set up an “audit logging” system which works as follows. As part of the business logic, the application can write specific log data to a queue, which will be passed on to a real message queue (IMessageService). We then have a dedicated Service that handles messages from the queue, does some further processing, and writes the result to the database.
However, we are also in the process of applying a modular architecture to our application. Each module exposes its contract via ServiceStack DTOs, and can be accessed either directly via HTTP, or by other modules via the in-process Gateway.
The problem is now that processing the audit logs may require data from another module, but that module currently always requires authentication (because the services are marked with [Authenticate]). One simple solution is to pass the session in the queue message (as described here: Messaging API), but that’s not really correct, because the service that processes the messages shouldn’t have the same restrictions/permissions as the user that triggered the message.
Here is some minimal example code:
public class AuditLogMessage
{
public required int UserId { get; set; }
public required AuditLog Data { get; set; }
}
// Somewhere in the app...
_messageProducer.Publish(new AuditLogMessage {...});
public class AuditLogMessageService : Service
{
public async Task Any(AuditLogMessage request)
{
// Fetch some extra info about the user
var user = await Gateway.SendAsync(new GetUser { Id = request.UserId });
// ...
}
}
[Authenticate(Provider = "credentials")]
public class UserService : Service
{
[RequiredPermission("UserGet")]
public async Task<object> Get(GetUser request)
{
// ...
}
}
In summary, AuditLogMessageService needs some way to call other modules, while bypassing the usual authentication. Are there any best practices for this?