Basic Authentication in ASP.Net MVC Web API

ASP.NET Web API is a great tool to create lightweight, HTTP services that reach a broad range of clients, including all browsers and mobile platforms.

In most of scenarios we need authentication to restrict services . There are two ways to restrict it

– Forms authentication
– Windows authentication

Forms authentication is a mechanism that works well in interactive web applications, but Windows authentication is not widely used. Now days services are invoked from the browser using jquery or javascripts for mobile platforms because application are widely used on mobile devices.

HTTP authentication is part of the standard protocol and can be easily handled by client and mobile platforms. To implement Basic authentication in ASP.NET Web API by extending AuthorizeAttribute. But its sometimes not working well, Another a custom message handler by deriving from DelegateHandler class.

Below is the code sample which is deriving from DelegateHandler class and working well.

Code Block:
[csharp]
public class BasicAuthMessageHandler : DelegatingHandler
{
private const string BasicAuthResponseHeader = “WWW-Authenticate”;
private const string BasicAuthResponseHeaderValue = “Basic”;

public IProvidePrincipal PrincipalProvider = new DummyPrincipalProvider();

public BasicAuthMessageHandler(HttpConfiguration httpConfiguration)
{
InnerHandler = new HttpControllerDispatcher(httpConfiguration);
}

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)
{
IPrincipal myPrincipal = PrincipalProvider.CreatePrincipal(parsedCredentials.Username, parsedCredentials.Password);
Thread.CurrentPrincipal = myPrincipal;
HttpContext.Current.User = myPrincipal;
}
}
return base.SendAsync(request, cancellationToken)
.ContinueWith(task =>
{
var response = task.Result;
if (response.StatusCode == HttpStatusCode.Unauthorized
&& !response.Headers.Contains(BasicAuthResponseHeader))
{
response.Headers.Add(BasicAuthResponseHeader
, BasicAuthResponseHeaderValue);
}

if (response.StatusCode == HttpStatusCode.Unauthorized)
{
var content = new StringContent(“Invalid Credentials”);
response.Content = content;
response.StatusCode = System.Net.HttpStatusCode.Unauthorized;
}
return response;
});
}

private Credentials ParseAuthorizationHeader(string authHeader)
{
string[] credentials = Encoding.ASCII.GetString(Convert
.FromBase64String(authHeader))
.Split(
new[] { ‘:’ });
if (credentials.Length != 2 || string.IsNullOrEmpty(credentials[0])
|| string.IsNullOrEmpty(credentials[1])) return null;
return new Credentials()
{
Username = credentials[0],
Password = credentials[1],
};
}
}
[/csharp]

[csharp]
public interface IProvidePrincipal
{
IPrincipal CreatePrincipal(string username, string password);
}
[/csharp]

[csharp]
public class Credentials
{
public string Username { get; set; }
public string Password { get; set; }
}
[/csharp]

[csharp]
public class DummyPrincipalProvider : IProvidePrincipal
{
public IPrincipal CreatePrincipal(string username, string password)
{
//check user using any membership provider Websecurity/Membership
if (!WebSecurity.Login(username, password, persistCookie: false))
{
return null;
}
var identity = new GenericIdentity(username);
IPrincipal principal = new GenericPrincipal(identity, Roles.GetRolesForUser(username));
return principal;
}
}
[/csharp]
WebApiConfig:

[csharp]
config.Routes.MapHttpRoute(
name: “DefaultApi”,
routeTemplate: “api/{controller}/{action}/{id}”,
defaults: new { id = RouteParameter.Optional },
constraints: null,
handler: new BasicAuthMessageHandler(GlobalConfiguration.Configuration)
[/csharp]
Controller:

[csharp]
[Authorize]
public class ValuesController : ApiController
{
// GET api/values
public IEnumerable<string> Get()
{
return new string[] { “first”, “second” };
}
}
[/csharp]

Client:
[csharp]
using (HttpClient client = new HttpClient())
{
client.BaseAddress = new Uri(“http://example.com”);
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue(“Authorization”, Convert.ToBase64String(Encoding.ASCII.GetBytes(String.Format(“{0}:{1}”, userName, password))));
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue(“application/json”));
var Response =await client.GetAsync(“api/accounts/validateuser”);
}
[/csharp]

 

 


Posted

in

, , ,

by