0
  • I have users stored in our own custom database.
  • I have developed a ASP .NET Web 2 API
  • I do NOT have an existing Web site and clients are not using a browser (so cannot use Forms Authentication)
  • I need to use the existing users so cannot use ASP .NET's Identity which uses it's own tables?

How can I best add authentication to my API? I would like to take advantage of existing infrastructure such as the Authorize attribute.

(This question: User Authentication in ASP.NET Web API does not answer my question because the only two ways it proposes for authentication are Forms Authentication and Windows Integrated Authentication - neither of which I can use).

4
  • You can set Authorize on web-api based on any condition, but how do u intend to preserve the authentication if u have no browser, a cookie or ouath token needs to be sent so the api know's the request is legit and authrized ? Commented Jul 24, 2014 at 1:00
  • I have no browser but it is HTTP so I can include tokens in the headers, even if I were not using HTTP I could include it my requests. Commented Jul 24, 2014 at 1:04
  • easier to include the cookie it's send in the header, unless u know how to configure Ouath ? but with no browser hmmm ouath might be your only option Commented Jul 24, 2014 at 1:10
  • Use // do some condition check then set FormsAuthentication.SetAuthCookie(userAccount, true); // set to false if you do no want to create a persistent cookie, if you include the cookie in your header it should work Commented Jul 24, 2014 at 1:15

1 Answer 1

1

I like to have custom authentication mechanisms in a message handler. Since I don't know the requirements regarding level of security it is impossible to say what kind of mechanism you should use. If you are using SSL then basic authentication could be enough.

A simple handler for basic authentication with custom user store can look like this:

public class BasicAuthMessageHandler : DelegatingHandler
{
    private const string ResponseHeader = "WWW-Authenticate";
    private const string ResponseHeaderValue = "Basic";

    protected override System.Threading.Tasks.Task<HttpResponseMessage> SendAsync(
        HttpRequestMessage request,
        CancellationToken cancellationToken)
    {
        AuthenticationHeaderValue authValue = request.Headers.Authorization;
        if (authValue != null && !String.IsNullOrWhiteSpace(authValue.Parameter))
        {
            Credentials parsedCredentials = ParseAuthorizationHeader(authValue.Parameter);
            if (parsedCredentials != null)
            {
                //Here check the provided credentials against your custom user store
                if(parsedCredentials.Username == "Username" && parsedCredentials.Password == "Pass") 
                {
                    Thread.CurrentPrincipal = new GenericPrincipal(new GenericIdentity(parsedCredentials.Username), null);
                }
            }
        }
        return base.SendAsync(request, cancellationToken)
           .ContinueWith(task =>
           {
               var response = task.Result;
               if (response.StatusCode == HttpStatusCode.Unauthorized
                   && !response.Headers.Contains(ResponseHeader))
               {
                   response.Headers.Add(ResponseHeader, ResponseHeaderValue);
               }
               return response;
           });
    }

    private Credentials ParseAuthorizationHeader(string authHeader)
    {
        string[] credentials = Encoding.ASCII.GetString(Convert
                                                        .FromBase64String(authHeader))
                                                        .Split(
                                                        new[] { ':' });
        return new Credentials()
                   {
                       Username = credentials[0],
                       Password = credentials[1],
                   };
    }
}

public class Credentials
{
    public string Username {get;set;}
    public string Password {get;set;}
}

You then apply the message handler in your global app configuration

protected void Application_Start()
    {
        GlobalConfiguration.Configuration.MessageHandlers
          .Add(new BasicAuthMessageHandler());
    }

Note that the provided sample is just an example.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

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

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.