CQRS and authentication

2,102 views
Skip to first unread message

Attila Farkas

unread,
May 5, 2011, 7:33:01 AM5/5/11
to DDD/CQRS
Hi all,

i know, that authentication isn't a part of my domain.
But I want to profit from cqrs infrastructure. How do you deal with
authentication? Do you have separate service or do you (in some way)
reuse CQRS infra?

0. vistitor have to register to become a customer
1. i want to authenticate visitor
2. i want to track failed and success logons
3. i want to lock user account after 5 failed logons for one hour

One solution:
0. There is Cutomer Aggregate and UserAccount aggregate (I have 2
different Bounded contexts?)
1. I Check login + password against read model from client (againts
UserAccountsView)
2. if send RegisterSuccessLogon or RegisterFailedLogon command
3. I generate additional UserLockedEvent (I have whole history in my
UserAccount Aggregate including logon attempts) and update UserAccount
aggregate
4. I will capture UserLockedEvent in event handler and set locked flag
in the user In UserAccountsView

bad idea? Please, give me an advice! :-)



Peter Podoski

unread,
May 5, 2011, 8:03:51 AM5/5/11
to ddd...@googlegroups.com
Hi,

I usually treat the authentication aspect of my application as it were a completely seperate service. Just consider the situation if you once need to move to some OpenID solution or in an enterprise environment to a Windows Authentication solution. What benefits would you get then from this UserAccount aggregate and its history? How would you change your model then and will it be worth keeping those informations as "domain events"?

So I say that there could be value in an authentication service implemented in "the CQRS way", but totally decoupled from your business domain. However, if you need to analyze your site traffic and user activities at a higher level in order to give more relevant informations and offers to the customers then it should be really in its own (but again, separated) domain. Does it have any business value to track the user's account as an aggregate root without any noticable logic? Your aggregate could grow pretty big if you keep all logon attempts in a list only to "lock it out if there are too many failed logons in an hour". (I know, you can optimize the snapshotting to throw away old attempts.) But it is really not that complex. 

Regards,
Peter

Nuno Lopes

unread,
May 5, 2011, 9:48:00 AM5/5/11
to ddd...@googlegroups.com
pipes and filters: http://eaipatterns.com/PipesAndFilters.html

Cheers,

Nuno
PS: This seams to be also similar to Monads in Haskell : http://www.haskell.org/haskellwiki/Monad in the functional paradigm. I'm not yet sure of this, just some random thought.

Attila Farkas

unread,
May 5, 2011, 10:07:45 AM5/5/11
to DDD/CQRS
Thank you Peter,

I had just same thoughts before i posted my question.

Scenario. I have internet web app with forms authentication and own
user mgmt(i'm sure that it won't be win integrated and it won't be
open id).
I'm not looking for beauty, but an usefull compromise. I want to
reause(yes, I agree that is not always good idea) part or whole infra
to have scalable solution but to avoid unnecesary maintance.

"What benefits would you get then from this UserAccount aggregate and
its history?"

Yes, none. Maybe i want display all logon attempts to customer that
can check for possible "stolen" login. But still I miss some important
state modification or some complex logic as you mentioned.(only that
lock)

So...
a) I can fire an Event(FailedLogon,SuccessLogon,AccountLocked) (which
is not a core domain event) from client and use the Event Handler
infrastructure. I will skip command model. I can add later handler
that notifies user on each AccountLocked event. I like this idea as
compromise for now. It's appropriate form of CQRS for what i need to
achieve. Or isn't it?

b) I can still use my UserAccount Aggregate approach, but I will not
save the events...Yes this smells more than a)

Ramin

unread,
May 5, 2011, 12:24:24 PM5/5/11
to DDD/CQRS
> Your aggregate could grow pretty big if you keep all logon attempts in
> a list only to "lock it out if there are too many failed logons in an hour"

The Aggregate wouldn't need to hold onto the list of all logon
attempts. It would only need the timestamp of the first logon-failure
(if there is one) and the number of failures since.

The rest of the logon attempts can be held in the read model.

Ramin

Ramin

unread,
May 5, 2011, 12:26:30 PM5/5/11
to DDD/CQRS
> The rest of the logon attempts can be held in the read model.

Sorry, that should read: The complete list of the logon attempts can
be held in the read model.

Ramin

Attila Farkas

unread,
May 5, 2011, 3:23:17 PM5/5/11
to DDD/CQRS
Thank you Ramin!

Yes, maybe this is the answer - I really don't need event sourcing in
this secondary bounded context. Tracking "state of logon attempts" in
userAccount aggregate is perfectly OK I think.
But what will be the commands?
RecordFailedLogon and RecordSucessLogon after checking login+password
in controller via readmodel?
> > > > bad idea? Please, give me an advice! :-)- Skryť citovaný text -
>
> - Zobraziť citovaný text -

@yreynhout

unread,
May 5, 2011, 6:31:23 PM5/5/11
to DDD/CQRS
Could you elaborate on how this is "Core Domain"? If not, you're
stealing from your employer. OTOH, if this is you toying around with
CQRS, then ignore my last remark and the ones that follow.
I'll say it again, authentication is orthogonal to your domain (unless
you're building a system specifically for user management/
authentication/authorization). As developers we need to evolve and
stop implementing "Generic Domains" for which off the shelve solutions
are so omnipresent and in such great variety.
On another note, if I have to register to become a customer I consider
that a fail, unless it's part of a checkout process, in which case
I'll turn a blind eye.
You seem to go through great lengths to lock me out as a customer,
probably because you suspect I'm not the real customer but some lame
hacker that has nothing better to do than hacking your site,
performing a little dictionary attack. If I was a real hacker I'd be
attacking your read side, not your write side, especially if that's
where you keep your usernames and passwords (hashed at least, I hope).
Not trying to bash you here, but I've just seen one too many of these
'lets implement our own user management' posts and as such had to
ventilate my frustration. Feel free to ignore this entirely :)

Ramin

unread,
May 6, 2011, 6:58:56 AM5/6/11
to DDD/CQRS
Sounds reasonable, I guess (not an expert, maybe others have more to
say). The userAccount could then publish LogonFailureRecorded and
LogonSuccessRecorded events, which can be subscribed to by the read
side to display all login attempts to the user.

By the way, by saying that "the userAccount doesn't need to hold on to
the list of all logon attempts" it is not being said that no-one holds
on to them and you don't use event sourcing. The recorded logon
attempts can still be published and sourced, the projection of them in
the userAccount (write model) just doesn't need to hold onto the
entire list of them.

Ramin
> > > > > bad idea? Please, give me an advice! :-)- Skry» citovaný text -
>
> > - Zobrazi» citovaný text -

Attila Farkas

unread,
May 8, 2011, 6:58:13 AM5/8/11
to DDD/CQRS

@yreynhout
You are right in all the ways. I'm just playing. I told in first post
that this isn't a core domain.

What about a web site, where is a Core Domain but the "custom" user
management too? Imagine e.g. a web site where customers register,
confirm registration, they have some demo access, they can pay for
full access, they can forget password ... do you think this is a
generic domain?
The paradox is, that I have only little problems when impl. core
domain(after subscribing view to domain events only few left). I have
problems with "secondary" domain, where is possibility to profit from
CQRS infrastructure, but there are also ohter spec. requirements. So,
discussion sometimes helps me to ensure, that the way I think about
problem is not good.

Yes, hash + salt. But dictotionary attack = attacking my readside.
Sure, there are more sophisticated/clever ways how to implement the
lock, but this was just lightweight sample.

I'm trying to involve new technologies and approaches in my
playground. There is number of ways, how to apply or profit from CQRS.
I test some of them on real scenarions(real domains I already
experienced) to be able to make valuable decisions for my employer in
the future. (but we "use" CQRS for more than 2 years but in very
naiver?, pragmatical? way according to project requirement and
infrastructure setup which is mostly a shared muscular RDBMS storage.
Readside: views + some lightweight dataaccess to profit from that iron
without cache or anything. Write side NH and old fashion remote fasade
+ very compromise domain model. E.g. it removed complexity from "DM",
removed common risks like deep object graph that programmers often
belittled, ability to involve juniors(read side), profit from muscular
RDBMS on read side but side byt side profit from ORM in write side.)
But now, we start to get projects where vert. scalability is
necessary.

So I like all the "myth busting" job(esp. Udi + Greg), that CQRS
community is doing. Lot of things that was said number of us felt for
years as a problem, but no one was so brave ;-) to tell it loudly and
suggest some none "mainstream silver bullet" solution. So I'm still
not looking for silver bullet for anything. This is a lesson I learned
during 12+ years doing enterprise solutions. I need to get CQRS into
context and practise. As an architect I still code lot (at home), to
have experience with what I preach :-D So I gave "stupid" questions. I
don't expect theory, preach, I expect you share your practice - e.g.
"Yes, I faced the same problem. Requirements for this problem were
specific and this form of CQRS was not applicable for this part of
solution. I involved different approach than for the rest of the
solution. And it was ...". To be able to recognize edge cases where
not to apply some pattern is equally important like to know that
pattern. That's one of the reasons I like e.g. Martin Folwer so
much :-)

Sorry for longer post
Reply all
Reply to author
Forward
0 new messages