43

Web API'sini kullanarak bir ASP.NET MVC 4 Project'im var. Denetleyicide [Authorize] özniteliğini kullanarak yetkilendirmeyi zorunlu kılmak için sınıfı ayarlamıştım. Kimlik Doğrulama için ASP.NET Üyelik Sağlayıcısı'nı kullanıyorum ve Web formumda "Formlar" Kimlik Doğrulaması kullanacak şekilde ayarlamam var. İşte burada takılıyorum:ASP.NET MVC 4 Üyelik Sağlayıcısı ile Web API Kimlik Doğrulaması

Her şey, API'yi test ederek yaptığım noktaya kadar çalışıyor ve denetleyiciyi [Authorize] özniteliğiyle güvenceye almak istiyorum. Üyelik Sağlayıcısı. Bu yüzden Fiddler kadar yangın ve yetkilendirmesi ekleyerek aynı çağrıyı yapın: şöyle my üyelik sağlayıcısından şifre:

enter image description here

ben 401 izinsiz ve "Auth" altına almak yanıtı adı ile beraber Temel özellik "WWW-Authenticate Header mevcut değil" alıyorum. Sonra, API'nın SHA1 şifreli bir anahtar aradığını anlıyorum. Bu yüzden bir aramadan bir SHA1 jeneratörü çalıştırıp İsmimin için bir karma olsun: şifre ve şöyle benim iste Başlığını güncelleme:

enter image description here

Bu da işe yaramazsa ve ben aynı sonuçlar elde ederler. Ayrıca, kullanıcı adı/şifremi çözmek için sunucuyla birlikte kullanacağım açıkça bir çeşit "paylaşımlı gizli anahtar" a ihtiyacım var.

Yani benim sorular: Ben sunucudan bu anahtarı alırım Nasıl

  1. (veya bu durumda Sanal IIS VS 2012 akıp).
  2. Bunu, bir ASP.NET Üyelik Sağlayıcısından kullanıcı adları/parolalar kullanarak Fiddler'da Kimlik Doğrulanmış aramalar yapmak için nasıl kullanırım?
  3. Aynı çağrıları yapmak için istemci uygulamasında bunu nasıl kullanırım (C# WPF Uygulaması).
  4. HTTP çağrılarımda SSL ile birleştirildiğinde bu en iyi pratik mi? Eğer değilse ne var?

Şimdiden teşekkürler!

cevap

67

basic authentication'u SSL ile kullanabilirsiniz. Sunucu tarafında biz kayıtlı memebership sağlayıcı sorgulayarak kimlik bilgilerini doğrular özel delegating işleyicisi yazabilirsiniz ve geçerliyse, şu anki müdürü rolleri almak ve ayarlayın:

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); 
    } 
} 

Biz o zaman bu işleyici kayıt Application_Start yılında:

[Authorize] 
public class ValuesController : ApiController 
{ 
    public string Get() 
    { 
     return string.Format("Hello {0}", User.Identity.Name); 
    } 
} 
: Artık

GlobalConfiguration.Configuration.MessageHandlers.Add(
    new BasicAuthenticationMessageHandler() 
); 

biz sadece doğrulanmış kullanıcılar kendi eylemlerini erişebilmesini sağlamak için bağlıyor [yetkilendirme] ile dekore edilecek bir Api denetleyicisi olabilir

Pekala, şimdi en örnek bir istemci bakalım:

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); 
      } 
     } 
    } 
} 
+0

Teşekkür Darin, bu ihtiyacım olan şey tam da! – CodeAbundance

+0

'User.Identity.Name 'denetleyici yönteminde benim için boş' User.Identity.IsAuthenticated'' false '. Hata ayıklayıcısında 'Thread.CurrentPrincipal', ileti işleyicisindeki doğru kullanıcı adı ve rolleri olan ana makineye ayarlandığını görebiliyorum. Ayrıca '[Yetkilendirme (Roller = ...)] 'özniteliğine saygı duyulur: Yanlış rolleri olan bir kullanıcıyı kullanırsam İzinsiz yanıt alır ve denetleyici yöntemine ulaşamam. Ancak 'User.Identity', mesaj işleyicide belirttiğim değere sahip değil. Neyin yanlış olabileceğine dair bir fikrin var mı? – Slauma

+0

@Slauma, Bunu yeniden oluşturamıyorum. Belki de, problemin nasıl yeniden üretileceğini adım adım açıklayan yeni bir konu başlatabilirsiniz (tabii ki boş bir projeden başlayarak). –