Aracılığıyla paylaş


Kimlik Doğrulama ve Yetkilendirme Kullanarak Uygulamaların Güvenliğini Sağlama

Microsoft tarafından

PDF’yi İndir

Bu, ASP.NET MVC 1 kullanarak küçük ama eksiksiz bir web uygulaması oluşturmayı gösteren ücretsiz bir "NerdDinner" uygulaması öğreticisinin 9. adımıdır.

9. adım, NerdDinner uygulamamızın güvenliğini sağlamak için kimlik doğrulaması ve yetkilendirme eklemeyi gösterir; böylece kullanıcıların yeni akşam yemekleri oluşturmak için siteye kaydolması ve oturum açması gerekir ve bunu daha sonra yalnızca akşam yemeği düzenleyen kullanıcı düzenleyebilir.

ASP.NET MVC 3 kullanıyorsanız , MVC 3 veya MVC Music Store ile Çalışmaya Başlama öğreticilerini izlemenizi öneririz.

NerdDinner 9. Adım: Kimlik Doğrulaması ve Yetkilendirme

Şu anda NerdDinner uygulamamız siteyi ziyaret eden herkese herhangi bir akşam yemeğinin ayrıntılarını oluşturma ve düzenleme olanağı verir. Bunu değiştirerek kullanıcıların yeni akşam yemekleri oluşturmak için siteye kaydolması ve oturum açması ve yalnızca akşam yemeği barındıran kullanıcının daha sonra düzenleyebilmesi için bir kısıtlama ekleyelim.

Bunu etkinleştirmek için uygulamamızın güvenliğini sağlamak için kimlik doğrulaması ve yetkilendirme kullanacağız.

Kimlik Doğrulama ve Yetkilendirmeyi Anlama

Kimlik doğrulaması , uygulamaya erişen bir istemcinin kimliğini tanımlama ve doğrulama işlemidir. Daha basit bir ifadeyle, son kullanıcının bir web sitesini ziyaret ettiğinde "kim" olduğunu belirlemekle ilgili. ASP.NET tarayıcı kullanıcılarının kimliğini doğrulamanın birden çok yolunu destekler. İnternet web uygulamaları için kullanılan en yaygın kimlik doğrulama yaklaşımı "Forms Kimlik Doğrulaması" olarak adlandırılır. Forms Kimlik Doğrulaması, bir geliştiricinin kendi uygulaması içinde bir HTML oturum açma formu yazmasına ve ardından son kullanıcının bir veritabanı veya başka bir parola kimlik bilgisi deposuna gönderdiği kullanıcı adını/parolayı doğrulamasını sağlar. Kullanıcı adı/parola bileşimi doğruysa, geliştirici daha sonra ASP.NET kullanıcıyı gelecekteki isteklerde tanımlamak için şifrelenmiş bir HTTP tanımlama bilgisi vermesini isteyebilir. NerdDinner uygulamamızla form kimlik doğrulamayı kullanacağız.

Yetkilendirme , kimliği doğrulanmış bir kullanıcının belirli bir URL'ye/kaynağa erişme iznine sahip olup olmadığını belirleme veya bazı eylemler gerçekleştirme işlemidir. Örneğin, NerdDinner uygulamamızda yalnızca oturum açmış kullanıcıların /Dinners/Create URL'sine erişip yeni Akşam Yemekleri oluşturabilmesini sağlamak istiyoruz. Ayrıca, yalnızca akşam yemeğini barındıran kullanıcının düzenleyebilmesi için yetkilendirme mantığı eklemek ve diğer tüm kullanıcılara düzenleme erişimini reddetmek istiyoruz.

Forms Kimlik Doğrulaması ve AccountController

ASP.NET MVC için varsayılan Visual Studio proje şablonu, yeni ASP.NET MVC uygulamaları oluşturulduğunda form kimlik doğrulamasını otomatik olarak etkinleştirir. Ayrıca projeye otomatik olarak önceden oluşturulmuş bir hesap oturum açma sayfası uygulaması ekler ve bu da site içinde güvenliği tümleştirmeyi gerçekten kolaylaştırır.

Varsayılan Site.ana ana sayfası, siteye erişen kullanıcının kimliği doğrulanmadığında sitenin sağ üst köşesinde bir "Oturum Aç" bağlantısı görüntüler:

nerd Dinner Host a Dinner sayfasının ekran görüntüsü. Sağ üst köşede Oturum Aç seçeneği vurgulanır.

"Oturum Aç" bağlantısına tıklanması bir kullanıcıyı /Account/LogOn URL'sine götürür:

İnek Akşam Yemeği Oturum Açma sayfasının ekran görüntüsü.

Kaydolmamış olan ziyaretçiler bunu "Kaydol" bağlantısına tıklayarak yapabilir. Bu bağlantı onları /Account/Register URL'sine götürür ve hesap ayrıntılarını girmelerine izin verir:

İnek Yemeği Yeni Hesap Oluştur sayfasının ekran görüntüsü.

"Kaydet" düğmesine tıklanması, ASP.NET Üyelik sisteminde yeni bir kullanıcı oluşturur ve form kimlik doğrulamasını kullanarak kullanıcının kimliğini sitede doğrular.

Kullanıcı oturum açtığında, Site.master sayfanın sağ üst kısmını değiştirerek "Hoş Geldiniz [kullanıcıadı]!" iletisi verir ve "Oturum Aç" yerine "Oturumu Kapat" bağlantısını işler. "Oturumu Kapat" bağlantısına tıklanması kullanıcının oturumunu kapatır:

nerd Dinner Host a Dinner form sayfasının ekran görüntüsü. Sağ üst köşede Hoş Geldiniz ve Oturumu Kapat düğmeleri vurgulanır.

Yukarıdaki oturum açma, oturum kapatma ve kayıt işlevi, projeyi oluştururken Visual Studio tarafından projemize eklenen AccountController sınıfı içinde uygulanır. AccountController kullanıcı arabirimi, \Views\Account dizinindeki görünüm şablonları kullanılarak uygulanır:

İnek Yemeği gezinti ağacının ekran görüntüsü. Hesap Denetleyicisi nokta c s vurgulanmış. Hesap Klasörü ve menü öğeleri de vurgulanır.

AccountController sınıfı, şifrelenmiş kimlik doğrulama tanımlama bilgileri vermek için ASP.NET Forms Kimlik Doğrulama sistemini ve kullanıcı adlarını/parolaları depolamak ve doğrulamak için ASP.NET Üyelik API'sini kullanır. ASP.NET Üyelik API'si genişletilebilir ve tüm parola kimlik bilgileri depolarının kullanılmasını sağlar. ASP.NET bir SQL veritabanında veya Active Directory'de kullanıcı adını/parolaları depolayan yerleşik üyelik sağlayıcısı uygulamalarıyla birlikte gösterilir.

NerdDinner uygulamamızın kullanması gereken üyelik sağlayıcısını, projenin kökündeki "web.config" dosyasını açıp içindeki üyelik> bölümünü arayarak <yapılandırabiliriz. Proje oluşturulduğunda eklenen varsayılan web.config SQL üyelik sağlayıcısını kaydeder ve veritabanı konumunu belirtmek için "ApplicationServices" adlı bir bağlantı dizesi kullanacak şekilde yapılandırılır.

Varsayılan "ApplicationServices" bağlantı dizesi (web.config dosyasının <connectionStrings> bölümünde belirtilir) SQL Express kullanacak şekilde yapılandırılır. "ASPNETDB" adlı bir SQL Express veritabanına işaret eder. MDF", uygulamanın "App_Data" dizini altında. Uygulama içinde Üyelik API'sini ilk kez kullandığınızda bu veritabanı yoksa, ASP.NET veritabanını otomatik olarak oluşturur ve içinde uygun üyelik veritabanı şemasını sağlar:

İnek Yemeği gezinti ağacının ekran görüntüsü. Uygulama Verileri genişletilir ve A S P NET D B nokta M D F seçilir.

SQL Express kullanmak yerine tam bir SQL Server örneği kullanmak (veya uzak bir veritabanına bağlanmak) istediysek tek yapmamız gereken web.config dosyasındaki "ApplicationServices" bağlantı dizesini güncelleştirmek ve işaretlendiği veritabanına uygun üyelik şemasının eklendiğinden emin olmaktır. Bir veritabanına üyelik ve diğer ASP.NET uygulama hizmetleri için uygun şemayı eklemek üzere \Windows\Microsoft.NET\Framework\v2.0.50727\ dizininde "aspnet_regsql.exe" yardımcı programını çalıştırabilirsiniz.

[Authorize] filtresini kullanarak /Dinners/Create URL'sini yetkilendirme

NerdDinner uygulaması için güvenli bir kimlik doğrulaması ve hesap yönetimi uygulamasını etkinleştirmek için herhangi bir kod yazmamız gerekmedi. Kullanıcılar uygulamamıza yeni hesaplar kaydedebilir ve sitede oturum açabilir/oturumu kapatabilir.

Artık uygulamaya yetkilendirme mantığı ekleyebilir ve site içinde yapabileceklerini ve yapamadıklarını denetlemek için ziyaretçilerin kimlik doğrulama durumunu ve kullanıcı adını kullanabiliriz. DinnersController sınıfımızın "Oluştur" eylem yöntemlerine yetkilendirme mantığı ekleyerek başlayalım. Özel olarak, /Dinners/Create URL'sine erişen kullanıcıların oturum açmasını zorunlu kılarız. Oturum açmamışlarsa oturum açabilmeleri için bunları oturum açma sayfasına yönlendireceğiz.

Bu mantığı uygulamak oldukça kolaydır. Tek yapmamız gereken Create eylem yöntemlerimize bir [Authorize] filtre özniteliği eklemektir:

//
// GET: /Dinners/Create

[Authorize]
public ActionResult Create() {
   ...
} 

//
// POST: /Dinners/Create

[AcceptVerbs(HttpVerbs.Post), Authorize]
public ActionResult Create(Dinner dinnerToCreate) {
   ...
}

ASP.NET MVC, eylem yöntemlerine bildirim temelli olarak uygulanabilen yeniden kullanılabilir mantık uygulamak için kullanılabilecek "eylem filtreleri" oluşturma özelliğini destekler. [Yetkilendir] filtresi, ASP.NET MVC tarafından sağlanan yerleşik eylem filtrelerinden biridir ve bir geliştiricinin eylem yöntemlerine ve denetleyici sınıflarına yetkilendirme kurallarını bildirimli olarak uygulamasını sağlar.

[Authorize] filtresi, herhangi bir parametre olmadan uygulandığında (yukarıda olduğu gibi) eylem yöntemi isteğinde bulunan kullanıcının oturum açması gerektiğini zorlar ve aksi takdirde tarayıcıyı otomatik olarak oturum açma URL'sine yönlendirir. Bu yeniden yönlendirme yapılırken başlangıçta istenen URL bir querystring bağımsız değişkeni olarak geçirilir (örneğin: /Account/LogOn? ReturnUrl=%2fDinners%2fCreate). Ardından AccountController, oturum açtıktan sonra kullanıcıyı başlangıçta istenen URL'ye yeniden yönlendirir.

[Yetkilendir] filtresi isteğe bağlı olarak, kullanıcının hem oturum açmasını hem de izin verilen kullanıcıların veya izin verilen bir güvenlik rolünün üyesinin listesinin içinde oturum açmasını gerektirmek için kullanılabilecek bir "Kullanıcılar" veya "Roller" özelliği belirtme özelliğini destekler. Örneğin, aşağıdaki kod yalnızca "scottgu" ve "billg" olmak üzere iki belirli kullanıcının /Dinners/Create URL'sine erişmesine izin verir:

[Authorize(Users="scottgu,billg")]
public ActionResult Create() {
    ...
}

Belirli kullanıcı adlarını koda eklemek oldukça bakımsız olma eğilimindedir. Daha iyi bir yaklaşım, kodun denetleyebilmesi için daha üst düzey "roller" tanımlamak ve ardından bir veritabanı veya Active Directory sistemi kullanarak kullanıcıları role eşlemektir (gerçek kullanıcı eşleme listesinin kod dışında depolanmasını sağlar). ASP.NET, bu kullanıcı/rol eşlemesini gerçekleştirmeye yardımcı olabilecek yerleşik rol yönetimi API'sinin yanı sıra yerleşik rol sağlayıcıları (SQL ve Active Directory için olanlar dahil) içerir. Daha sonra kodu yalnızca belirli bir "yönetici" rolündeki kullanıcıların /Dinners/Create URL'sine erişmesine izin verecek şekilde güncelleştirebiliriz:

[Authorize(Roles="admin")]
public ActionResult Create() {
   ...
}

Akşam Yemeği Oluştururken User.Identity.Name özelliğini kullanma

Denetleyici temel sınıfında kullanıma sunulan User.Identity.Name özelliğini kullanarak bir isteğin şu anda oturum açmış olan kullanıcısının kullanıcı adını akleyebilirsiniz.

Daha önce Create() eylem yöntemimizin HTTP-POST sürümünü uyguladığımızda Akşam Yemeğinin "HostedBy" özelliğini statik bir dizeye sabit kodlamıştık. Artık bu kodu User.Identity.Name özelliğini kullanacak şekilde güncelleştirebilir ve Akşam Yemeği oluşturan konak için otomatik olarak bir RSVP ekleyebiliriz:

//
// POST: /Dinners/Create

[AcceptVerbs(HttpVerbs.Post), Authorize]
public ActionResult Create(Dinner dinner) {

    if (ModelState.IsValid) {
    
        try {
            dinner.HostedBy = User.Identity.Name;

            RSVP rsvp = new RSVP();
            rsvp.AttendeeName = User.Identity.Name;
            dinner.RSVPs.Add(rsvp);

            dinnerRepository.Add(dinner);
            dinnerRepository.Save();

            return RedirectToAction("Details", new { id=dinner.DinnerID });
        }
        catch {
            ModelState.AddModelErrors(dinner.GetRuleViolations());
        }
    }

    return View(new DinnerFormViewModel(dinner));
}

Create() yöntemine [Authorize] özniteliğini eklediğimizden ASP.NET MVC, eylem yönteminin yalnızca /Dinners/Create URL'sini ziyaret eden kullanıcının sitede oturum açması durumunda yürütülmesini sağlar. Bu nedenle, User.Identity.Name özellik değeri her zaman geçerli bir kullanıcı adı içerir.

Akşam Yemeklerini Düzenlerken User.Identity.Name özelliğini kullanma

Şimdi kullanıcıları kısıtlayan bazı yetkilendirme mantığı ekleyerek yalnızca kendi barındırdıkları akşam yemeğinin özelliklerini düzenleyebilmelerini sağlayın.

Bu konuda yardımcı olmak için önce Dinner nesnemize bir "IsHostedBy(kullanıcıadı)" yardımcı yöntemi ekleyeceğiz (daha önce oluşturduğumuz Dinner.cs kısmi sınıfı içinde). Bu yardımcı yöntem, sağlanan kullanıcı adının Dinner HostedBy özelliğiyle eşleşip eşleşmediğine bağlı olarak true veya false döndürür ve bunların büyük/küçük harfe duyarsız dize karşılaştırmasını gerçekleştirmek için gereken mantığı kapsüller:

public partial class Dinner {

    public bool IsHostedBy(string userName) {
        return HostedBy.Equals(userName, StringComparison.InvariantCultureIgnoreCase);
    }
}

Ardından DinnersController sınıfımız içindeki Edit() eylem yöntemlerine bir [Authorize] özniteliği ekleyeceğiz. Bu, kullanıcıların /Dinners/Edit/[id] URL'si istemek için oturum açmasını sağlar.

Ardından, oturum açmış kullanıcının Dinner konağıyla eşleşip eşleşmediğini doğrulamak için Dinner.IsHostedBy(kullanıcı adı) yardımcı yöntemini kullanan Edit yöntemlerimize kod ekleyebiliriz. Kullanıcı konak değilse bir "InvalidOwner" görünümü görüntüleyip isteği sonlandıracağız. Bunu yapmak için kod aşağıdaki gibi görünür:

//
// GET: /Dinners/Edit/5

[Authorize]
public ActionResult Edit(int id) {

    Dinner dinner = dinnerRepository.GetDinner(id);

    if (!dinner.IsHostedBy(User.Identity.Name))
        return View("InvalidOwner");

    return View(new DinnerFormViewModel(dinner));
}

//
// POST: /Dinners/Edit/5

[AcceptVerbs(HttpVerbs.Post), Authorize]
public ActionResult Edit(int id, FormCollection collection) {

    Dinner dinner = dinnerRepository.GetDinner(id);

    if (!dinner.IsHostedBy(User.Identity.Name))
        return View("InvalidOwner");

    try {
        UpdateModel(dinner);

        dinnerRepository.Save();

        return RedirectToAction("Details", new {id = dinner.DinnerID});
    }
    catch {
        ModelState.AddModelErrors(dinnerToEdit.GetRuleViolations());

        return View(new DinnerFormViewModel(dinner));
    }
}

Ardından \Views\Dinners dizinine sağ tıklayıp Ekle-Görünüm> menü komutunu seçerek yeni bir "InvalidOwner" görünümü oluşturabiliriz. Bunu aşağıdaki hata iletisiyle dolduracağız:

<asp:Content ID="Title" ContentPlaceHolderID="TitleContent" runat="server">
    You Don't Own This Dinner
</asp:Content>

<asp:Content ID="Main" ContentPlaceHolderID="MainContent" runat="server">

    <h2>Error Accessing Dinner</h2>

    <p>Sorry - but only the host of a Dinner can edit or delete it.</p>

</asp:Content>

Artık bir kullanıcı sahip olmadığı bir akşam yemeğini düzenlemeye çalıştığında bir hata iletisi alır:

İnek Yemeği web sayfasındaki Hata İletisi'nin ekran görüntüsü.

Aynı adımları denetleyicimiz içindeki Delete() eylem yöntemleri için tekrarlayarak Akşam Yemeklerini silme iznini de kilitleyebilir ve bir Akşam Yemeğinin yalnızca konağı tarafından silinebilmesini sağlayabiliriz.

Details URL'mizden DinnersController sınıfımızın Düzenle ve Sil eylem yöntemine bağlanıyoruz:

İnek Yemeği sayfasının ekran görüntüsü. Düzenle ve Sil düğmeleri en altta daire içine alınıyor. Ayrıntılar U R L en üstte daire içine alınır.

Şu anda, ayrıntılar URL'sinin ziyaretçinin akşam yemeğinin ev sahibi olup olmamasına bakılmaksızın Düzenle ve Sil eylem bağlantılarını gösteriyoruz. Bağlantıların yalnızca ziyaret eden kullanıcı akşam yemeğinin sahibi olduğunda görüntülenmesi için bunu değiştirelim.

DinnersController içindeki Details() eylem yöntemi bir Dinner nesnesi alır ve bunu model nesnesi olarak görünüm şablonumuza geçirir:

//
// GET: /Dinners/Details/5

public ActionResult Details(int id) {

    Dinner dinner = dinnerRepository.GetDinner(id);

    if (dinner == null)
        return View("NotFound");

    return View(dinner);
}

Görünüm şablonumuzu, aşağıdaki gibi Dinner.IsHostedBy() yardımcı yöntemini kullanarak Düzenle ve Sil bağlantılarını koşullu olarak gösterecek/gizleyecek şekilde güncelleştirebiliriz:

<% if (Model.IsHostedBy(Context.User.Identity.Name)) { %>

   <%= Html.ActionLink("Edit Dinner", "Edit", new { id=Model.DinnerID }) %> |
   <%= Html.ActionLink("Delete Dinner", "Delete", new {id=Model.DinnerID}) %>    

<% } %>

Sonraki Adımlar

Şimdi kimliği doğrulanmış kullanıcıların AJAX kullanarak akşam yemeklerinde YANıT vermelerini nasıl etkinleştirebileceğimize bakalım.