Hi everyone, I’m looking for a solution on authorization a user based on current state of an aggregate. I found this topic Security and Serialization in Axon - #9 by Allard. According to Mr.Allard suggestion, it’s best practice to use interceptor to intercept a request before dispatch to the aggregate. In my scenario, I need to have state of an aggregate to check whether a user has access or being the owner of an aggregate/object. my code may looks like this.
public class TopicAggregate {
private String ownerId;
@CommandHandler
public void handle(DeleteTopicCommand command) {
if (!ownerId.equals(command.getUserId())) {
throw new AccessDeniedException();
}
}
}
using interceptor I won’t be able to have access to the state of an aggregate. one thing that I can think of is that to rely on query model and implement interceptor like this.
public class AuthorizationDispatchInterceptor implements MessageHandlerInterceptor<CommandMessage<?>> {
private TopicRepository topicRepository;
@Override
public Object handle(UnitOfWork<? extends CommandMessage<?>> unitOfWork, InterceptorChain interceptorChain) throws Exception {
CommandMessage<?> command = unitOfWork.getMessage();
String userId = Optional.ofNullable(command.getMetaData().get("userId"))
.map(uId -> (String) uId)
.orElseThrow(IllegalCommandException::new);
String ownerId = topicRepository.findById(command..getMetaData().get("topicId"));
if (ownerId.equals(userId)) {
return interceptorChain.proceed();
}
throw new AccessDeniedException();
}
}
but that’s definitely bad practice right? since there’s the eventual consistency thing. I don’t want to put authorization logic in my aggregate either since it should be handle in separate layer. so what’s the best practice to solve this problem