ASP.NET Web API'sında Kullanıcı Kimlik Doğrulaması


150

Bu konu benim için inanılmaz derecede kafa karıştırıcıydı. Ben HTTP uygulamalarında bir çaylak değilim ama bir yerden JSON verilerini tüketen bir iPhone istemcisi geliştirmem gerekiyor. MS'den Web API'sini seçtim çünkü yeterince kolay görünüyordu, ancak kullanıcıları doğrulamak söz konusu olduğunda işler oldukça sinir bozucu oluyor.

Nasıl birkaç saat Googling sonra Authorizebenim ApiControlleryöntemler üzerinde özniteliği kullanarak aşağı giriş ekranından bir kullanıcı doğrulamak için nasıl açık bir örnek bulmak mümkün değildi şaşırdım .

Bu bir soru değil, bunun tam olarak nasıl yapılacağına dair bir örnek talebi. Aşağıdaki sayfalara baktım:

Bunlar, yetkisiz isteklerin nasıl ele alınacağını açıklasa da, bunlar LoginControllerkullanıcı kimlik bilgilerini istemek ve doğrulamak için a veya benzeri bir şeyi açıkça göstermez .

Güzel, basit bir örnek yazmak veya beni doğru yöne yönlendirmek isteyen herkes lütfen?

Teşekkürler.


1
Aynı soruya bu tür bir cevap verdim: stackoverflow.com/questions/11775594/…
cuongle

Asp.net ile Web Api için, sadece bir mvc uygulaması gibi çerez ve form kimlik doğrulama modülünü kullanabilirsiniz (isterseniz). Böylece web api kodunuzda, kullanıcının oturum açıp açmadığını görmek için müdürü kontrol edebilirsiniz, örneğin (öncekiyle aynı).
Elliot


Birçok kişinin asp.net/web-api/overview/security/… makalesini okumanızı şiddetle tavsiye ederim .
Youngjae

Yanıtlar:


176

Nasıl bir kullanıcı doğrulamak için giriş ekranından birkaç saat Googling sonra benim ApiController yöntemleri üzerinde Authorize özniteliğini kullanmaya kadar nasıl doğru bir örnek bulmak mümkün değildi şaşırdım.

Çünkü bu iki kavram hakkında kafanız karışıyor:

  • Kimlik doğrulama, sistemlerin kullanıcılarını güvenli bir şekilde tanımlayabilecekleri mekanizmadır. Kimlik doğrulama sistemleri şu sorulara cevap verir:

    • Kullanıcı kim?
    • Kullanıcı gerçekten kendisini temsil ettiği kişi mi?
  • Yetkilendirme, bir sistemin, kimliği doğrulanmış belirli bir kullanıcının sistem tarafından denetlenen güvenli kaynaklara erişim düzeyini belirlemesi için gerekli olan mekanizmadır. Örneğin, bir veritabanı yönetim sistemi, belirli kişilere bir veritabanından bilgi alma, ancak datbase'de depolanan verileri değiştirme yeteneğine sahip olmamakla birlikte diğer kişilere veri değiştirme yeteneği kazandıracak şekilde tasarlanabilir. Yetkilendirme sistemleri şu sorulara cevaplar sağlar:

    • X kullanıcısı R kaynağına erişme yetkisine sahip mi?
    • X kullanıcısı P işlemini yapmaya yetkili mi?
    • X kullanıcısı, R kaynağında P işlemini gerçekleştirme yetkisine sahip mi?

AuthorizeMVC nitelik örneğin, erişim kurallarını uygulamak için kullanılır:

 [System.Web.Http.Authorize(Roles = "Admin, Super User")]
 public ActionResult AdministratorsOnly()
 {
     return View();
 }

Yukarıdaki kural sadece sağlayacak kullanıcıların Yönetici ve Süper Kullanıcı rolleri yöntemi erişmek için

Bu kurallar, locationöğe kullanılarak web.config dosyasında da ayarlanabilir . Misal:

  <location path="Home/AdministratorsOnly">
    <system.web>
      <authorization>
        <allow roles="Administrators"/>
        <deny users="*"/>
      </authorization>
    </system.web>
  </location>

Ancak, bu yetkilendirme kuralları yürütülmeden önce , geçerli web sitesinde kimliğiniz doğrulanmalıdır .

Bunlar, yetkisiz isteklerin nasıl ele alınacağını açıklasa da, bunlar bir LoginController gibi bir şey göstermez veya kullanıcı kimlik bilgilerini istemek ve doğrulamak için böyle bir şey göstermez.

Buradan sorunu ikiye ayırabiliriz:

  • Aynı Web uygulamasında Web API hizmetlerini kullanırken kullanıcıların kimliğini doğrulama

    Bu en basit yaklaşım olacaktır, çünkü ASP.Net'teki Kimlik Doğrulamaya güvenirsiniz.

    Bu basit bir örnek:

    Web.config

    <authentication mode="Forms">
      <forms
        protection="All"
        slidingExpiration="true"
        loginUrl="account/login"
        cookieless="UseCookies"
        enableCrossAppRedirects="false"
        name="cookieName"
      />
    </authentication>

    Kullanıcılar hesaba / giriş yoluna yönlendirilecek, orada kullanıcı kimlik bilgilerini istemek için özel kontroller yapacak ve ardından aşağıdakileri kullanarak kimlik doğrulama çerezini ayarlayacaksınız:

        if (ModelState.IsValid)
        {
            if (Membership.ValidateUser(model.UserName, model.Password))
            {
                FormsAuthentication.SetAuthCookie(model.UserName, model.RememberMe);
                return RedirectToAction("Index", "Home");
            }
            else
            {
                ModelState.AddModelError("", "The user name or password provided is incorrect.");
            }
        }
    
        // If we got this far, something failed, redisplay form
        return View(model);
  • Platformlar arası kimlik doğrulama

    Bu durum, yalnızca Web uygulaması içinde Web API hizmetlerini açığa çıkarırken , hizmetleri tüketen başka bir istemciniz olur, istemci başka bir Web uygulaması veya herhangi bir .Net uygulaması olabilir (Win Formlar, WPF, konsol, Windows hizmeti, vb)

    Örneğin, Web API hizmetini aynı ağ etki alanındaki başka bir web uygulamasından (intranet içinde) tüketeceğinizi varsayalım, bu durumda ASP.Net tarafından sağlanan Windows kimlik doğrulamasına güvenebilirsiniz.

    <authentication mode="Windows" />

    Hizmetleriniz İnternet'te görünürse, kimliği doğrulanmış belirteçleri her Web API hizmetine geçirmeniz gerekir.

    Daha fazla bilgi için aşağıdaki makalelere yağmalayın:


3
Vaov! Ben buna cevap diyorum. Sonuç olarak. Aşağıdakileri yapmayı planlıyorum: 1. HTTPS üzerinden kullanıcı adı ve parolayı alan ve oturum açma sonucunu ve belirteci döndüren bir Oturum açma yöntemiyle bir hesap denetleyicisi oluşturun. 2. İstemci belirteci depolar ve web sunucusu tarafından onaylanan istekte üstbilgi (artık HTTPS yok) gönderir. Bu iyi bir yaklaşım mı? O zaman son şüphe token kurcalama ve süresinin nasıl kontrol edileceğidir. Mümkün mü?
Luis Aguilar

6
@Jupaol Birçok Web API geliştiricisi için konuştuğumu düşünüyorum, bir web sitem yok ve istemciler bir tarayıcı kullanmadıkları için Form Kimlik Doğrulaması kullanamıyorum, ayrıca kullanıcılar herhangi bir cihazda dünyanın herhangi bir yerinde olabileceğinden Entegre kimlik doğrulaması kullanamıyorum ( dolayısıyla Web API'sı), ne kullanmalıyım?
markmnl

21
Bu cevabın neden bu kadar çok oy aldığını anlamıyorum. ASP.NET Web API hakkında değil, ASP.NET MVC hakkında.
Bastien Vandamme

3
B413'ün yorumunu tekrarlamak ve bu sorunun özellikle Web API'sı istediğini belirtmek istiyorum
Julien

6
Bu, SO'da en çok oylanan 'yanlış' cevap mı? Cevap aslında bir mvc web uygulamasından çok farklı web api hakkında konuşmuyor! @ B413 gibi Tamamen şok oldum!
stt106

15

Bir kullanıcı adı ve parola ile yetkilendirme çerezi olmadan kimlik doğrulaması yapmak istiyorsanız , MVC4 Yetkilendirme özniteliği kutunun dışında çalışmayacaktır. Ancak, temel kimlik doğrulama başlıklarını kabul etmek için denetleyicinize aşağıdaki yardımcı yöntemi ekleyebilirsiniz. Kumandanızın yöntemlerinin başından çağırın.

void EnsureAuthenticated(string role)
{
    string[] parts = UTF8Encoding.UTF8.GetString(Convert.FromBase64String(Request.Headers.Authorization.Parameter)).Split(':');
    if (parts.Length != 2 || !Membership.ValidateUser(parts[0], parts[1]))
        throw new HttpResponseException(Request.CreateErrorResponse(HttpStatusCode.Unauthorized, "No account with that username and password"));
    if (role != null && !Roles.IsUserInRole(parts[0], role))
        throw new HttpResponseException(Request.CreateErrorResponse(HttpStatusCode.Unauthorized, "An administrator account is required"));
}

İstemci tarafından, bu yardımcı HttpClientkimlik doğrulama başlığı yerinde bir a oluşturur :

static HttpClient CreateBasicAuthenticationHttpClient(string userName, string password)
{
    var client = new HttpClient();
    client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Basic", Convert.ToBase64String(UTF8Encoding.UTF8.GetBytes(userName + ':' + password)));
    return client;
}

Sadece başlıkta kimlik bilgilerini geçmek için endüstri standardını kullanmanın basit bir yolunu aradığımı yorumlamak istedim. Bu örnek, hem sunucu hem de istemci tarafında temel bilgileri gösterdi ve tüm ihtiyacım oldu.
da_jokker

9

Bir MVC5 / Web API projesi üzerinde çalışıyorum ve Web Api yöntemleri için yetki alabilmek gerekiyordu. Dizin görünümüm ilk yüklendiğinde, otomatik olarak oluşturulduğuna inandığım 'jeton' Web API yöntemine bir çağrı yaparım.

Jetonu almak için istemci tarafı kodu (CoffeeScript):

getAuthenticationToken = (username, password) ->
    dataToSend = "username=" + username + "&password=" + password
    dataToSend += "&grant_type=password"
    $.post("/token", dataToSend).success saveAccessToken

Başarılı olursa, kimlik doğrulama jetonunu yerel olarak kaydeden aşağıdakiler çağrılır:

saveAccessToken = (response) ->
    window.authenticationToken = response.access_token

Sonra [Yetkilendir] etiketi olan bir Web API yöntemine Ajax çağrısı yapmak gerekirse, ben sadece Ajax çağrım için aşağıdaki başlığı ekleyin:

{ "Authorization": "Bearer " + window.authenticationToken }

Nereden response.access_tokengeliyor. U c # kodundan mı ayarlıyorsunuz?
shashwat

'Response' nesnesi 'token' yöntemi ile döndürülür.
ProfNimrod

Rollere bakmadım. Bu yaklaşım size yalnızca bir erişim belirteci verir, böylece [Yetkilendir] etiketi ile dekore edilmiş WebApi yöntemlerini çağırabilirsiniz. Bu yöntemlerden herhangi birini çağırdığınızda, rolleri kontrol edebilirsiniz. stackoverflow.com/questions/19689570/mvc-5-check-user-role yardımcı olabilir.
ProfNimrod

Ve bu çözümde kullanıcılarınızı nerede doğrularsınız?
Craig Brett

/ Jeton uç noktası, herhangi bir yeni Web API projesi için otomatik olarak oluşturulur. Bunun arkasındaki kod, kullanıcının kimliğinin doğrulandığı yerdir. Mevcut bir MVC projesine bir Web API denetleyicisi eklediyseniz biraz daha karmaşıktır.
ProfNimrod
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.