You can use basic authentication with SSL. On the server side, we could write a custom delegation handler that will verify credentials by requesting a registered memebership provider, and if valid, get the roles and set the current principal:
public class BasicAuthenticationMessageHandler : DelegatingHandler { protected override Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken) { var authHeader = request.Headers.Authorization; if (authHeader == null) { return base.SendAsync(request, cancellationToken); } if (authHeader.Scheme != "Basic") { return base.SendAsync(request, cancellationToken); } var encodedUserPass = authHeader.Parameter.Trim(); var userPass = Encoding.ASCII.GetString(Convert.FromBase64String(encodedUserPass)); var parts = userPass.Split(":".ToCharArray()); var username = parts[0]; var password = parts[1]; if (!Membership.ValidateUser(username, password)) { return base.SendAsync(request, cancellationToken); } var identity = new GenericIdentity(username, "Basic"); string[] roles = Roles.Provider.GetRolesForUser(username); var principal = new GenericPrincipal(identity, roles); Thread.CurrentPrincipal = principal; if (HttpContext.Current != null) { HttpContext.Current.User = principal; } return base.SendAsync(request, cancellationToken); } }
Then we register this handler in Application_Start :
GlobalConfiguration.Configuration.MessageHandlers.Add( new BasicAuthenticationMessageHandler() );
Now we can have an Api controller, which will be decorated with the [Authorize] attribute to ensure that only authenticated users can access their actions:
[Authorize] public class ValuesController : ApiController { public string Get() { return string.Format("Hello {0}", User.Identity.Name); } }
Ok, now let's look at a client example:
using System; using System.Net; using System.Net.Http; using System.Net.Http.Headers; using System.Text; class Program { static void Main() {
Darin Dimitrov Jul 18 '12 at 7:29 2012-07-18 07:29
source share