Asp.net-Mvc

使用成員資格提供程序的 ASP.NET MVC 4 Web API 身份驗證

  • July 18, 2012

我有一個使用 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 獲取了一個雜湊,並像這樣更新我的請求標頭:

在此處輸入圖像描述

這也不起作用,我得到相同的結果。此外,我顯然需要某種“共享密鑰”來與伺服器一起使用來解碼我的使用者名/密碼。

所以我的問題:

  1. 如何從伺服器獲取此密鑰(或者在這種情況下,虛擬 IIS 在 VS 2012 上執行)。
  2. 如何使用它在 Fiddler 中使用來自 ASP.NET 成員資格提供程序的使用者名/密碼進行經過身份驗證的呼叫。
  3. 我將如何在我的客戶端應用程序中使用它來進行相同的呼叫(C# WPF 應用程序)。
  4. 在我的 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);
           }
       }
   }
}

引用自:https://stackoverflow.com/questions/11535075