Handling command/query "out-of-band" data (user ID, IP, etc)

992 views
Skip to first unread message

Jonny Svärling

unread,
Jan 9, 2011, 6:02:13 PM1/9/11
to DDD/CQRS
Hi everyone!

In a command handler (or when executing a query), how do you get hold
of information such as the ID and IP address of the user that sent the
command/query? This information could be used for authorization,
auditing, etc. Do you put it inside every command/query or use some
other method, perhaps not related to CQRS at all, to carry this
information on to command handlers etc?

In my current project, we do not put it in the commands/queries
themselves. Instead we put it in a Command/QueryContext object that is
available to command/query handlers. The context keeps the user id, IP
and other "out-of-band" data. It is stored on the thread the handler
is running on but could also be passed as a parameter to the handler I
guess. For example, our web application use an in-process command bus
that gets the current user from the HttpContext.Current.User.Identity
and the client IP and puts it into the context. We also have a web
service that gets this information using other means (SOAP-headers,
WCF OperationContext etc) but sets the context in the same way. The
command handler does not need to know how it ended up there. Does this
sound reasonable?

I'm wondering because I've not seen any talk or examples that about
something like what I just described or any kind of command/query
message *headers* even though there is a lot of talk and examples of
command/query messages. Have I been looking in the wrong places or is
this stuff is completely orthogonal to CQRS?

How do you guys handle out-of-band data in your CQRS applications? How
do you handle authentication/authorization in command/query handlers?

Neil Robbins

unread,
Jan 9, 2011, 10:48:38 PM1/9/11
to ddd...@googlegroups.com

On my command side I wrap my actual command object up with this metadata as I typically want to persist it (eg for audit & future analysis) as well as have it available when I process it. My query side tends to be very thin (MVC + DAOs running queries synchronously) so I find context as you've described very satisfactory. If recording of queries was required (eg for audit/analysis) then I'd probably still do it this way, but treat that as a crosscutting concern which would fire off an asynchronous 'AuditQueryRequest' command, but I've yet to have to do this.

Rinat Abdullin

unread,
Jan 10, 2011, 1:12:31 AM1/10/11
to ddd...@googlegroups.com
In my case client (UI side) is usually Web. Authentication happens in there, authenticated user ID is explicitly passed into the command. UI generally ensures, that the user can't do what he is not allowed, but authorization is really enforced by the server. The latter ensures that the user has access to the resource and operation according to the rules (i.e. any admin or user from an account that owns an integration, can start it).

Similar situation is with the queries. In basic case, authentication is handled by the UI side and that's it. Authorization is implicitly enforced by "one view per user role" separation. If enforced authorization rules are needed (only in a few *really* specific places), then sync view queries are replaced by explicit async ExecuteQueryCommand.

Re out-of-band-data. I've been using message headers for persisting this information. But since it's not strongly typed (and is a mess to access in Views on replays), I'm tempted to put them into clear structures inside messages (esp after adding simple and clear DSL for message contracts).

Best regards,
Rinat


2011/1/10 Jonny Svärling <jonny.s...@gmail.com>

@seagile

unread,
Jan 10, 2011, 4:50:15 PM1/10/11
to DDD/CQRS
The "context" approach is the way of the WCF, which is not very test-
friendly. I am interested in how other people handle this. Either
modelling it explicitly over and over again (or code-generating it),
or providing some generic construct to wrap each command with (example
below).

ICommandHandler<TCommand> {
void Handle(Envelope<TCommand> envelope);

Rinat Abdullin

unread,
Jan 11, 2011, 1:23:10 AM1/11/11
to ddd...@googlegroups.com
BTW, another alternative is to simply pass envelope info as a second argument.

Andreas Öhlund

unread,
Jan 11, 2011, 2:32:08 AM1/11/11
to ddd...@googlegroups.com
And and a third option would be to register some kind of "IProvideContextForTheCurrentCommand" in the beginning of the pipeline. Then interested handlers can just take a dependency if they want access to the "out of band" data.

Cheers,

Andreas

http://andreasohlund.blogspot.com
http://twitter.com/andreasohlund





Date: Tue, 11 Jan 2011 11:23:10 +0500
Subject: Re: [DDD/CQRS] Re: Handling command/query "out-of-band" data (user ID, IP, etc)
From: rinat.a...@gmail.com
To: ddd...@googlegroups.com

Tom Janssens

unread,
Jan 11, 2011, 4:21:25 AM1/11/11
to DDD/CQRS
I use a combination of the mentioned approaches.

I combine CQRS with an (controller/passive view)-like architecture,
where the controller's method call parameters are filled by a
convention-based automapper.

SRP is king here, the Command-side controller simply translates input
values in commands,sends them to the bus, and then redirects to the
query-side controller

I do not test the input resource mapping explicitly, but I use BDD-
style top down testing, where I can switch the input resource type(web/
winforms/json/xml/...).
Once you have a mapping available, you can easily reuse it everywhere
(let's say from a textbox to a date for example).

This has proven to be an easily extendable architecture..

On 10 jan, 00:02, Jonny Svärling <jonny.svarl...@gmail.com> wrote:

Jonny Svärling

unread,
Jan 13, 2011, 5:31:50 PM1/13/11
to DDD/CQRS
Ok, so most of you seem to be using an envelope wrapping the command.

As long as the data in this envelope is provided by the command
handling pipeline (not the command sender) it reckon it is more or
less the same thing as the context thingy I described. The difference
is that the envelope wraps the command while the context is provided
side-by-side. (Or are any of you in some way explicitly creating the
envelope in the command sender, e.g., a MVC-controller?)

A context is nice because because you don't have to look at it/go
through it to access the command. Most of the out-of-band data, e.g.
the user's IP address, is not interesting to look at in most command
handlers anyway. The envelope on the other hand keeps everything
together in a nice way.

So sending an envelope as a second parameter should conceptually be
the same as sending context as a second parameter (?).

On the query side I'm currently using standard methods (query
interfaces) which seem to be the most common approach, e.g:

public SomeThingDTO GetSomeThing(Guid thingId)
{
...use QueryContext.Current.UserId, e.g., to do authorization

....if ok, get something...
}

Of course, the context could also be sent as a parameter, although it
does not look as nice and clutters the interface imho. Enforcing
authorization through the "one view per user role" is interesting but
I'm not sure it would work in my case where the authorization is quite
complex (there would be too many views).

Envelopes won't work here since there is nothing to wrap unless a
handler-based approach with query messages is used instead, analogous
to command handlers and command messages. Anyone doing this? (Neil,
were you using context on the query side because of this or for some
other reason?)

I realize most of this is really not-so-implementation details and
mostly a matter of taste - but it is still interesting to hear how you
do it - it helps to to minimize development friction!

@seagile

unread,
Jan 14, 2011, 3:50:10 AM1/14/11
to DDD/CQRS
The problem with ambient objects is that the code does not communicate
its intent very well, nor is it very testable. It's better to be
explicit. If you were to develop this in a TDD (stressing design here)
fashion, you would naturally come to the envelope or second parameter
approach. Examples of the pain of ambient objects are
HttpContext.Current, Transaction.Current, OperationContext.Current :-)

I'm using a handler-based approach for queries in my search bounded
context, because it goes beyond a simple ad-hoc viewmodel query.

Jonny Svärling

unread,
Jan 14, 2011, 6:24:02 AM1/14/11
to DDD/CQRS
We mostly have integration tests right now (most unit tests are in the
domain model) and there I haven't had any real problems testing with a
fake context. But I agree that it is better to send the data as a
envelope/context parameter to the handler, especially if handlers is
used for queries since then the same principle could be used there as
well.

How queries are handled will of course be very different depending on
how complex they are and if they need to more dynamic than just
reading of some persistent data store, but I'll definitately consider
switching to an handler based solution.

Thanks for the input!
Reply all
Reply to author
Forward
0 new messages