Sharing authentication methods across API and web app

apiasp.netauthentication

I'm wanting to share an authentication implementation across a web application, and web API. The web application will be ASP.NET (mostly MVC 4), the API will be mostly ASP.NET WEB API, though I anticipate it will also have a few custom modules or handlers.

I want to:

  1. Share as much authentication implementation between the app and API as possible.
  2. Have the web application behave like forms authentication (attractive log-in page, logout option, redirect to / from login page when a request requires authentication / authorisation).
  3. Have API callers use something closer to standard HTTP (401 – Unauthorized, not 302 – Redirect).
  4. Provide client and server side logout mechanisms that don't require a change of password (so HTTP basic is out, since clients typically cache their credentials).

The way I'm thinking of implementing this is using plain old ASP.NET forms authentication for the web application, and pushing another module into the stack (much like MADAM – Mixed Authentication Disposition ASP.NET Module). This module will look for some HTTP header (implementation specific) which indicates "caller is API".

If the header "caller is API" is set, then the service will respond differently than standard ASP.NET forms authentication, it will:

  1. 401 instead of 302 on a request lacking authentication.
  2. Look for username + pass in a custom "Login" HTTP header, and return a FormsAuthentication ticket in a custom "FormsAuth" header.
  3. Look for FormsAuthentication ticket in a custom "FormsAuth" header.

My question(s) are:

  1. Is there a framework for ASP.NET that already covers this scenario?
  2. Are there any glaring holes in this proposed implementation? My primary fear is a security risk that I can't see, but I'm similarly concerned that there may be something about such an implementation that will make it overly restrictive or clumsy to work with.

Best Answer

I don't quite understand what it is you actually want to share.

I'd assume you won't find a framework cause what you want to do is not that hard to solve.

1) A third party application is -only- going to touch your general purpose API. It uses API authentication only (through forms authentication, api key usage, take your picking).

2) Your own application through user actions will redirect to login page and such and have it's own picking of authentication (form authentication probably). This is about stuff the user can potentially enter through the address bar of the webbrowser. If your application happens to use your general purposed API under the hood you are not going to redirect the user to your login page on ajax calls. Your application should handle/prevent this for the user. A user is not going to make API calls through his/her browser's address bar.

So for your application to be able to use your general purpose API, the general purpose API would only need to support the same authentication scheme (form authentication). Or your application would have to fetch the user's api key or something to use after the user logged in.

You can easily create an Authorize attribute in MVC that will checks multiple options, first for an api-key, then for a forms authentication based cookie token. If it finds nothing your general purpose API should or needs to throw 401s only.

Your application would pick them up from ajax call failures and could decide to move the user over to the login page.