Web API: Security: Basic Authentication
原文地址: http://msdn.microsoft.com/en-us/magazine/dn201748.aspx
Custom HttpModule code:
using System; using System.Collections.Generic; using System.Linq; using System.Net.Http.Headers; using System.Security.Principal; using System.Text; using System.Threading; using System.Web; namespace Test.MVC { public class CustomAuthModel: IHttpModule, IDisposable { public void Init(HttpApplication context) { context.AuthenticateRequest += AuthenticateRequests; context.EndRequest += TriggerCredentials; } private void TriggerCredentials(object sender, EventArgs e) { HttpResponse resp = HttpContext.Current.Response; if (resp.StatusCode == 401) { resp.Headers.Add("WWW-Authenticate", @"Basic realm='PHVIS'"); } } private void AuthenticateRequests(object sender, EventArgs e) { string authHeader = HttpContext.Current.Request.Headers["Authorization"]; if(authHeader!=null) { AuthenticationHeaderValue authHeaderValue = AuthenticationHeaderValue.Parse(authHeader); if(authHeaderValue.Parameter!=null) { byte[] unencode = Convert.FromBase64String(authHeaderValue.Parameter); string usePw = Encoding.GetEncoding("iso-8859-1").GetString(unencode); string[] creds = usePw.Split(':'); if (creds[0] == "Name" && creds[1] == "pw") { GenericIdentity gi = new GenericIdentity(creds[0]); string [] roles= new string[]{"Admin","Manager"}; Thread.CurrentPrincipal = new GenericPrincipal(gi, roles); HttpContext.Current.User = Thread.CurrentPrincipal; } } } } public void Dispose() { } } }
Web Config
<modules> <add name="CustomAuthModel" type="Test.MVC.CustomAuthModel, Test.MVC"/> </modules>
Web API code:
using System.Data; using System.Data.Entity; using System.Data.Entity.Infrastructure; using System.Linq; using System.Net; using System.Net.Http; using System.Web.Http; using System.Web.Http.Description; using Test.EntityFramework.Models; namespace Test.MVC.Controllers { public class TestController : ApiController { private TestDBContext db = new TestDBContext(); // GET api/Test [Authorize] public IQueryable<Test.EntityFramework.Models.Test> GetTests() { if (User.Identity.IsAuthenticated == true) { } return db.Tests; } } }
Client code:
public static async Task TestSecurity() { using (HttpClientHandler clientHandler = new HttpClientHandler()) { clientHandler.Credentials = new NetworkCredential("Name", "pw"); using (HttpClient client = new HttpClient(clientHandler)) { client.BaseAddress = new Uri("http://localhost:55165/"); client.DefaultRequestHeaders.Accept.Clear(); client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json")); HttpResponseMessage response = await client.GetAsync("api/test"); // Blocking call // Get if (response.IsSuccessStatusCode) { // Parse the response body. Blocking! var products = await response.Content.ReadAsAsync<IEnumerable<Test.EntityFramework.Models.Test>>(); foreach (var p in products) { Console.WriteLine("{0}\t{1};", p.ID, p.Title); } } else { Console.WriteLine("{0} ({1})", (int)response.StatusCode, response.ReasonPhrase); } } } }