Authentication in the interactor?

803 views
Skip to first unread message

Jeroen De Dauw

unread,
Feb 28, 2016, 5:57:16 AM2/28/16
to Clean Code Discussion
I'm creating an application that by and large conforms to the Clean Architecture [0], and thus has an Interactor per usecase. In this application, several usecases that do write actions require an authentication token to be provided. It's clear that authentication belongs in the application layer and should be kept out of the model. It could be put in the interactors. Doing so makes me uneasy though, which might be unfounded. Alternatively the authentication could be put right before the call to the interactor. Where do you think it belongs and why?

To be clear, I'm asking about the position of where the authentication code is invoked, not where to put the implementation itself. (I intend to put that in an application-level service.)

In case you're curious, this is the application I'm working on [1], with interactors (named usecases in this codebase) defined at [2] and invoked at [3].

[0] https://blog.8thlight.com/uncle-bob/2012/08/13/the-clean-architecture.html
[1] https://github.com/wmde/FundraisingFrontend
[2] https://github.com/wmde/FundraisingFrontend/tree/master/src/UseCases
[3] https://github.com/wmde/FundraisingFrontend/blob/master/app/routes.php

Péter Böszörményi

unread,
Feb 28, 2016, 6:27:13 AM2/28/16
to clean-code...@googlegroups.com
Tipically we use proxies/interceptors for that. Usually, when the client
(ui code, batch code, etc), calls the use case, it doesn't have a direct
reference for the user case implementation, but for some proxy. Here you
can add additional functionality, like transaction handling, remoting,
security, etc. So, the call chain something like this:

client->proxy->security interceptor->use case.

Other posibbility to use a decorator:

client->security decorator->use case.

I think the decorator here is a better choice. You can put the decorator
in front of your use case in the $ffFactory.
> --
> The only way to go fast is to go well.
> ---
> You received this message because you are subscribed to the Google
> Groups "Clean Code Discussion" group.
> To unsubscribe from this group and stop receiving emails from it, send
> an email to clean-code-discu...@googlegroups.com
> <mailto:clean-code-discu...@googlegroups.com>.
> To post to this group, send email to
> clean-code...@googlegroups.com
> <mailto:clean-code...@googlegroups.com>.
> Visit this group at https://groups.google.com/group/clean-code-discussion.

--
Best Regards,
Péter Böszörményi

Jeroen De Dauw

unread,
Feb 28, 2016, 12:46:30 PM2/28/16
to Clean Code Discussion
Thanks for the suggestion Péter. I had not thought about using a decorator or proxy, and would like to explore the benefits this approach provides a bit more.

The most obvious difference I see with calling an authentication service before calling the interactor is that with the decorator approach, the authentication token needs to be part of the request model, and the "authentication failed" state needs to be part of the response model. That also means the "core" interactor gets handed an authentication token it does not know how to deal with. Unless you inject the token into the decorator via its constructor, which then leaves the question of how to represent the failure state in the reponse model.

Either way, what do I gain by using the deocrator approach as opposed to handling authentication outside of the interactor all together?

Péter Böszörményi

unread,
Feb 28, 2016, 1:29:07 PM2/28/16
to clean-code...@googlegroups.com
Try to separete the two apsects of your coude. One is the business, and
one is the security.

Bind the authentication token to the HTTP request, the decorator will
take the token from there. If the authentication fail, throw an
exception, that can you handle in the web layer, and you can show some
friendly message to the user.

Incoming HTTP request -> some sort of filter bind the auth token to the
request, then delegates the call to the application -> controller do
it's business, and eventually call the use case -> the security
decorator takes the auth token from the HTTP request, and do the
neccesary cheks. If everthing ok, delegates the call to the UC, if not,
throw a security exception.

If you afraid of depending directly to the HTTP request, then you can
create a AuthTokenHoler interface, and use that. And in a configuration,
or during the bootstrap, you can create an object that implement the
interface using the HTTP request, or the session.

Łukasz Duda

unread,
Feb 28, 2016, 2:05:18 PM2/28/16
to Clean Code Discussion
And what if you decide to use application without HTTP? Your security depends on HTTP request.

https://groups.google.com/forum/#!searchin/clean-code-discussion/security$20application$20concern/clean-code-discussion/wHzmboOEHzo/3bO-r_dXpbAJ
In my opinion it's part of the use case. If you're not authorized to perform an action, application shows message.
I implemented it in base use case, called AuthorizedUseCase, which uses authentication service and then authorizes transaction. If the use case needs user's identity and authorization, I derive from AuthorizedUseCase, otherwise not.
I know, I know, prefer delegation instead of inheritance, but it works fine :-)

Péter Böszörményi

unread,
Feb 28, 2016, 2:39:04 PM2/28/16
to clean-code...@googlegroups.com
I recommend to reread my last paragraph.
> > an email to clean-code-discu...@googlegroups.com
> <javascript:>
> > <mailto:clean-code-discu...@googlegroups.com
> <javascript:>>.
> > To post to this group, send email to
> > clean-code...@googlegroups.com <javascript:>
> > <mailto:clean-code...@googlegroups.com <javascript:>>.
> <https://groups.google.com/group/clean-code-discussion>.
>
> --
> Best Regards,
> Péter Böszörményi
>
> --
> The only way to go fast is to go well.
> ---
> You received this message because you are subscribed to the Google
> Groups "Clean Code Discussion" group.
> To unsubscribe from this group and stop receiving emails from it, send
> an email to clean-code-discu...@googlegroups.com
> <mailto:clean-code-discu...@googlegroups.com>.

Péter Böszörményi

unread,
Feb 28, 2016, 2:54:00 PM2/28/16
to clean-code...@googlegroups.com
Ah, my last email was might be a little bit rude, sorry for that. If you
hide the implementation behind the interfae, you can switch to other
approaches, for example store the authorization information in web
session, or store in a singleton class in a gui application. What you
need to do is that you have to provide the proper AuthTokenHolder
implementation, and obviously, you have to propagate the auth token
somewhere where your application accept the request from the user. This,
I beleive, will be always technoloy dependent.

If you put your security related code right into the business code, the
two different type of code will be tangled, eventually it will be a
nightmare to maintain.

On 28/02/16 20:05, Łukasz Duda wrote:
> <javascript:>>.
> > To post to this group, send email to
> > clean-code...@googlegroups.com <javascript:>
> > <mailto:clean-code...@googlegroups.com <javascript:>>.
> <https://groups.google.com/group/clean-code-discussion>.
>
> --
> Best Regards,
> Péter Böszörményi
>
> --
> The only way to go fast is to go well.
> ---
> You received this message because you are subscribed to the Google
> Groups "Clean Code Discussion" group.
> To unsubscribe from this group and stop receiving emails from it, send
> an email to clean-code-discu...@googlegroups.com
> <mailto:clean-code-discu...@googlegroups.com>.

Łukasz Duda

unread,
Feb 28, 2016, 3:49:23 PM2/28/16
to Clean Code Discussion
Well, in my solution authentication is also behind interface. I switched authentication mechanism after one year and few implemented applications and it wasn't nightmare. In my opinion the part of security that doesn't have to depend on technology is authorisation.
AuthTokenHolder suggests token implementation of authentication. I can imagine authentication without token.
Authentication indeed often has to deal with technology. Could you show us example of your two solutions, the one with proxy and another one with decorator?
>      > an email to clean-code-discussion+unsub...@googlegroups.com
>     <javascript:>
>      > <mailto:clean-code-discussion+unsub...@googlegroups.com
>     <javascript:>>.
>      > To post to this group, send email to
>      > clean-code...@googlegroups.com <javascript:>
>      > <mailto:clean-code...@googlegroups.com <javascript:>>.
>      > Visit this group at
>     https://groups.google.com/group/clean-code-discussion
>     <https://groups.google.com/group/clean-code-discussion>.
>
>     --
>     Best Regards,
>     Péter Böszörményi
>
> --
> The only way to go fast is to go well.
> ---
> You received this message because you are subscribed to the Google
> Groups "Clean Code Discussion" group.
> To unsubscribe from this group and stop receiving emails from it, send

Péter Böszörményi

unread,
Feb 29, 2016, 4:08:17 PM2/29/16
to clean-code...@googlegroups.com
I don't know what the AuthTokenHolder is. I just used the terminology
that was in the first email. And sorry, but I have no time to write such
example.
> clean-code-discu...@googlegroups.com <javascript:>
> > <javascript:>
> > > <mailto:clean-code-discu...@googlegroups.com
> <javascript:>
> > <javascript:>>.
> > > To post to this group, send email to
> > > clean-code...@googlegroups.com <javascript:>
> > > <mailto:clean-code...@googlegroups.com <javascript:>>.
> > > Visit this group at
> > https://groups.google.com/group/clean-code-discussion
> <https://groups.google.com/group/clean-code-discussion>
> > <https://groups.google.com/group/clean-code-discussion
> <https://groups.google.com/group/clean-code-discussion>>.
> >
> > --
> > Best Regards,
> > Péter Böszörményi
> >
> > --
> > The only way to go fast is to go well.
> > ---
> > You received this message because you are subscribed to the Google
> > Groups "Clean Code Discussion" group.
> > To unsubscribe from this group and stop receiving emails from it,
> send
> > an email to clean-code-discu...@googlegroups.com
> <javascript:>
> > <mailto:clean-code-discu...@googlegroups.com
> <javascript:>>.
> > To post to this group, send email to
> > clean-code...@googlegroups.com <javascript:>
> > <mailto:clean-code...@googlegroups.com <javascript:>>.
> > Visit this group at
> https://groups.google.com/group/clean-code-discussion
> <https://groups.google.com/group/clean-code-discussion>.
>
> --
> Best Regards,
> Péter Böszörményi
>
> --
> The only way to go fast is to go well.
> ---
> You received this message because you are subscribed to the Google
> Groups "Clean Code Discussion" group.
> To unsubscribe from this group and stop receiving emails from it, send
> an email to clean-code-discu...@googlegroups.com
> <mailto:clean-code-discu...@googlegroups.com>.
Reply all
Reply to author
Forward
0 new messages