2

When I'm in charge, I typically model services separate from endpoints. For example: Company.Project.Domain.dll has all of the logic required to complete the services for that domain. In order to access it you either reference that library or, if I'm exposing the services through an endpoint, you can hit Company.Project.Endpoint at the URL: api.wutevz.com/blog/Message/

I mention the above because I have (seemingly unfortunately, but maybe I'm the wrong one) seen the majority of services/domains created directly inside an endpoint project (like WCF or Web API). And knowing my setup is key to my question. Also, if separating the logic from the endpoint is weird, feel free to chime in. While I think separating them is correct, I'm jaded from many years of consulting and seeing them joined.

The question, if my methodology is sound, is: Where should Authentication Live in the backend? This is unrelated to other questions asking if it should be in the backend vs the client. My question is: On the Endpoints, or on the Services?

So my Web API has this Endpoint:

[HttpPost]
//[AuthenticatePlz]
public HttpResponseMessage Message([FromBody] string contents){
    _service.AddMessage(contents);
}

And some domain service has the method that does the real biz:

//[AuthenticatePlz]
public void AddMessage(string contents) {
    // probably do some content checks or something and save the message
}

Don't get too hung up on whether Aspects are being used, or some Owin middleware, or Line 1 of the method is an Auth call, or some other horrible implementation. The goal is: Should the interception point, where Authentication is required, live on the Endpoint or the service method?

2 Answers 2

1

Ideally authentication should happen neither in the end point nor the service. A module in IIS or a proxy server would be best, or a plugin to the application framework. If you must intermingle the two I would put the authentication in the end point. A "service" object should assume you have permissions to use it so it retains maximum reusability.

Really the end point should also assume you have permission to operate on it. Something higher up in the stack should prevent your end point object from executing if authentication fails. This way changes in permissions or authentication schemes don't require changes to your end point or service layer.

1
  • What do you mean by higher in the stack? To me that means the application. I can't rely on any application (other than my own) to authentication prior to calling a public-facing endpoint. At the same time, if I push authentication all the way back to the persistence (or data-access layer), I'm waiting an awful long time to fail a request due to authentication. So given the choice between Service, and Endpoint which exposes the Service, it seems like you're saying Endpoint. Could you expand and/or edit your answer with more detail?
    – Suamere
    Jul 15, 2015 at 12:56
1

If I'm not mistaken, ASP.NET Web Api handles authentication using the IPrincipal interface.

A principal object represents the security context of the user on whose behalf the code is running, including that user's identity (IIdentity) and any roles to which they belong.

This object is basically a set of Claims which defines and describes the current user. That is, its username, email, and even roles.

Wether you're using a middleware or not, these claims have to be set so the authentication can be integrated in the IIS pipeline.

In a web service example like yours, these claims are commonly decoded from an authentication token. This token is sent along the user request, and therefore should be handled at an endpoint level (Controller).

Your domain service should not have to inspect the current request context, nor it has to know it's being called from a web service, or a desktop client.

2
  • I definitely agree that the domain service should not have to inspect the context. Or, for that matter, even have a reference to system.net/web, those are for communication layers. And since sending credentials/claims to the endpoint is a requirement, using an IPrincipal is a great tool in Web API for that. Though even with this knowledge, we could very well say that the endpoint can pass principal data (not object) into a service call, which is responsible for authenticating the token/credentials, etc. But it seems like you're saying don't do that. Can you expand on why for completeness?
    – Suamere
    Jul 15, 2015 at 13:04
  • @Suamere You could indeed pass your already decoded IPrincipal object to your service, and that will allow your service to examine the current authenticated user, but is it necessary? Your service should not be aware of the context, it should be as much as modular as possible. Your application (or the service's client) should provide the necessary security. But, as always, that's my opinion and that doesn't mean you're breaking any rules if you do that Jul 15, 2015 at 13:40

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.