Cross platform authentication using ASP.NET Web API

asp.net MvcRestasp.net Web-Api

asp.net Mvc Problem Overview


How do I even begin coding authentication using ASP.NET Web API so it is cross-platform to support desktop, mobile and web? I'd read of some methods of doing RESTful authentication, such as using tokens in the header.

Are there any example projects out there that utilizes this method?

Questions:

  1. If not how do I fix the [Authorize] attribute to read the token?
  2. How do I generate this token? I dont think i can use formsauthentication because that uses cookies.
  3. How do I handle the actual authorization, do the client send raw password and username then I generate the token or is there some other way?
  4. How do I handle when my website is using it? I heard this is handled differently than when an app is using it, such as getting the domain and authorizing it.

asp.net Mvc Solutions


Solution 1 - asp.net Mvc

I think tokens would be a solid way to go. Forms authentication is based on cookies for the web. Not the most idea situation for all non browser clients though.

What I'd suggest is creating a custom AuthorizationFilterAttribute and overriding the OnAuthorization method. In that method, you could check for the existence of a token that you've issued to the client after they've supplied valid credentials. You can use this attribute on any method or controller you want validated. Here's a sample you might reference

 public class AuthorizeTokenAttribute : AuthorizationFilterAttribute 
{      
    public override void OnAuthorization(HttpActionContext actionContext)
    {
        if (actionContext != null)
        {                
                if (!AuthorizeRequest(actionContext.ControllerContext.Request))
                {
                    actionContext.Response = new HttpResponseMessage(HttpStatusCode.Unauthorized) { RequestMessage = actionContext.ControllerContext.Request }; 
                }
                return;
        }
    }

    private bool AuthorizeRequest(System.Net.Http.HttpRequestMessage request)
    {
        bool authorized = false;
        if (request.Headers.Contains(Constants.TOKEN_HEADER))
        {               
            var tokenValue = request.Headers.GetValues("TOKEN_HEADER");
            if (tokenValue.Count() == 1) {
                var value = tokenValue.FirstOrDefault();               
               //Token validation logic here
               //set authorized variable accordingly
            }                
        }
        return authorized;
    } }

TOKEN_HEADER is just a string representing an HTTP header that the client should pass back for authenticated requests.

So let's walk through it

  1. Client requests secure data
  2. Client is not authorized, return a response with an Unauthorized status code
  3. Client sends credentials to authenticate, which should be secured via HTTPS
  4. Once validated, client receives a token via an HTTP header, or whatever works for you
  5. Client tries requesting secure data again, this time attached the token to the request
  6. The AuthorizeTokenAttribute will validate the token and allow the action to execute.

Also, check this post by John Petersen. Making your ASP.NET Web API’s secure

Solution 2 - asp.net Mvc

There are lots of ways to authenticate users for a REST service. Using tokens is possible but just using Basic Authentication is even simpler and about as standard and cross platform as you can go.

Don't confuse authorization with authentication. The [Authorize] attribute is all about authorization but only after a user has been authenticated using some other mechanism. Authorization is completely useless without doing proper authentication first.

The best resource to check is Dominick Baier who is an expert on the subject.

Solution 3 - asp.net Mvc

I use a very simple approach:

  1. define an access profile with its unique accessId and accessKey (e.g. MD5 hashed GUID value)
  2. store such access profile in database
  3. every request (GET/POST/etc.) must supply accessId, queryHash (MD5 hash value represents the query) and signature (MD5 hash value of queryHash + accessKey). Of course the client needs keep the accessKey in a secure place!!!
  4. server gets the request will check the accessId and the signature using the same calculation algorithm to reject or grant the access (authenticate)
  5. further authorization can be done on request type basis utilizing the access profile

the service with this approach using the new ASP.NET MVC web API can serve whatever type of client: browser/javascript and native(desktop or mobile) etc.

Solution 4 - asp.net Mvc

U can use ActionFilterAttribute and override the OnActionExecuting method. Later on register this filter in global.cs to apply this filter for all the actions like this in Application Start method

var config = GlobalConfiguration.Configuration; config.Filters.Add(new CustomAuthAttribute ());

{ namespace Customss { Public class CustomAuthAttribute : ActionFilterAttribute

{

    public override void OnActionExecuting(HttpActionContext actionContext)
    {
        // To inforce HTTPS if desired , else comment out the code
        if (!String.Equals(actionContext.Request.RequestUri.Scheme, "https", StringComparison.OrdinalIgnoreCase))
        {
            actionContext.Response = new HttpResponseMessage(System.Net.HttpStatusCode.BadRequest)
            {
                Content = new StringContent("HTTPS Required")
            };
            return;
        }

       // get toekn from the header

        var userToken = actionContext.Request.Headers.GetValues("UserToken");
         // Customer Logic to check the validity of the token.
        // U can have some DB logic to check , custom STS behind or some loca cache used to compare the values

       
    }

     
}

} }

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionShawn McleanView Question on Stackoverflow
Solution 1 - asp.net MvccecilphillipView Answer on Stackoverflow
Solution 2 - asp.net MvcMauriceView Answer on Stackoverflow
Solution 3 - asp.net Mvcuser1344426View Answer on Stackoverflow
Solution 4 - asp.net MvcMianView Answer on Stackoverflow