Asp.net-Mvc
使用成員資格提供程序的 ASP.NET MVC 4 Web API 身份驗證
我有一個使用 Web API 的 ASP.NET MVC 4 項目。在控制器上,我已使用 [Authorize] 屬性將類設置為需要授權。對於身份驗證,我使用 ASP.NET Membership Provider 並將我的 Web.Config 設置為使用“表單”身份驗證。這是我卡住的地方:
一切都很好,直到我完成了對 API 的測試,我想用 [Authorize] 屬性保護控制器,這樣我就可以開始在我的會員提供者中測試對使用者的身份驗證。因此,我啟動了 Fiddler 並進行了相同的呼叫,添加了 Authorization:Basic 屬性以及來自我的會員提供者的使用者名:密碼,如下所示:
我得到的響應是 401 未授權,在“Auth”下我得到“沒有 WWW-Authenticate Header is present”。然後我意識到 API 正在尋找一個 SHA1 編碼的密鑰。所以我從搜尋中啟動了一個 SHA1 生成器,並為我的 username:password 獲取了一個雜湊,並像這樣更新我的請求標頭:
這也不起作用,我得到相同的結果。此外,我顯然需要某種“共享密鑰”來與伺服器一起使用來解碼我的使用者名/密碼。
所以我的問題:
- 如何從伺服器獲取此密鑰(或者在這種情況下,虛擬 IIS 在 VS 2012 上執行)。
- 如何使用它在 Fiddler 中使用來自 ASP.NET 成員資格提供程序的使用者名/密碼進行經過身份驗證的呼叫。
- 我將如何在我的客戶端應用程序中使用它來進行相同的呼叫(C# WPF 應用程序)。
- 在我的 HTTP 呼叫上與 SSL 結合使用時,這是最佳實踐嗎?如果不是,那是什麼?
提前致謝!
您可以使用SSL 的基本身份驗證。在伺服器端,我們可以編寫一個自定義委託處理程序,它將通過查詢我們註冊的成員資格提供程序來驗證憑據,如果有效,則檢索角色並設置目前主體:
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); } }然後我們在下面註冊這個處理程序
Application_Start:GlobalConfiguration.Configuration.MessageHandlers.Add( new BasicAuthenticationMessageHandler() );現在我們可以有一個 Api 控制器,該控制器將使用 [Authorize] 屬性進行修飾,以確保只有經過身份驗證的使用者才能訪問其操作:
[Authorize] public class ValuesController : ApiController { public string Get() { return string.Format("Hello {0}", User.Identity.Name); } }好的,現在讓我們看一個範例客戶端:
using System; using System.Net; using System.Net.Http; using System.Net.Http.Headers; using System.Text; class Program { static void Main() { // since for testing purposes I am using IIS Express // with an invalid SSL certificate I need to desactivate // the check for this certificate. ServicePointManager.ServerCertificateValidationCallback += (sender, certificate, chain, sslPolicyErrors) => true; using (var client = new HttpClient()) { var buffer = Encoding.ASCII.GetBytes("john:secret"); var authHeader = new AuthenticationHeaderValue("Basic", Convert.ToBase64String(buffer)); client.DefaultRequestHeaders.Authorization = authHeader; var task = client.GetAsync("https://localhost:44300/api/values"); if (task.Result.StatusCode == HttpStatusCode.Unauthorized) { Console.WriteLine("wrong credentials"); } else { task.Result.EnsureSuccessStatusCode(); Console.WriteLine(task.Result.Content.ReadAsAsync<string>().Result); } } } }

