ASP.NET Web API 'sinde kimlik doğrulama ve yetkilendirmeAuthentication and Authorization in ASP.NET Web API

, Mike te sonby Mike Wasson

Bir Web API 'SI oluşturdunuz, ancak şimdi ona erişimi denetlemek istiyorsunuz.You've created a web API, but now you want to control access to it. Bu makale dizisinde, yetkisiz kullanıcılardan bir Web API 'sinin güvenliğini sağlamaya yönelik bazı seçeneklere bakacağız.In this series of articles, we'll look at some options for securing a web API from unauthorized users. Bu seri, hem kimlik doğrulamasını hem de yetkilendirmeyi kapsar.This series will cover both authentication and authorization.

  • Kimlik doğrulaması , kullanıcının kimliğini öğrenmektir.Authentication is knowing the identity of the user. Örneğin, Gamze Kullanıcı adı ve parolasıyla oturum açar ve sunucu çiğdem kimlik doğrulaması için parolayı kullanır.For example, Alice logs in with her username and password, and the server uses the password to authenticate Alice.
  • Yetkilendirme , bir kullanıcının bir eylem gerçekleştirmesine izin verilip verilmediği konusunda karar verebilir.Authorization is deciding whether a user is allowed to perform an action. Örneğin, Gamze 'nin bir kaynağı almak için izni vardır ancak kaynağı oluşturmamalıdır.For example, Alice has permission to get a resource but not create a resource.

Serideki ilk makale, ASP.NET Web API 'sinde kimlik doğrulamaya ve yetkilendirmeye genel bir bakış sunar.The first article in the series gives a general overview of authentication and authorization in ASP.NET Web API. Diğer konular, Web API 'SI için ortak kimlik doğrulama senaryolarını anlatmaktadır.Other topics describe common authentication scenarios for Web API.

Note

Bu seriyi inceleyen ve değerli geri bildirimleri sağlayan kişiler için teşekkürler: Rick Anderson, Levi Broderick, Barry Dorrans, Tom Dykstra, Hongmei Ge, David Matson, Daniel Roth, Tim Teebken.Thanks to the people who reviewed this series and provided valuable feedback: Rick Anderson, Levi Broderick, Barry Dorrans, Tom Dykstra, Hongmei Ge, David Matson, Daniel Roth, Tim Teebken.

Kimlik DoğrulamasıAuthentication

Web API 'SI, kimlik doğrulamasının konakta gerçekleştiğini varsayar.Web API assumes that authentication happens in the host. Web barındırma için, ana bilgisayar IIS 'dir ve kimlik doğrulaması için HTTP modüllerini kullanır.For web-hosting, the host is IIS, which uses HTTP modules for authentication. Projenizi IIS veya ASP.NET 'te yerleşik olarak bulunan kimlik doğrulama modüllerinden birini kullanacak şekilde yapılandırabilir veya özel kimlik doğrulaması gerçekleştirmek için kendi HTTP modülünüzü yazabilirsiniz.You can configure your project to use any of the authentication modules built in to IIS or ASP.NET, or write your own HTTP module to perform custom authentication.

Ana bilgisayar kullanıcının kimliğini doğruladığında, kodun çalıştığı güvenlik bağlamını temsil eden bir IPrincipal nesnesi olan bir sorumluoluşturur.When the host authenticates the user, it creates a principal, which is an IPrincipal object that represents the security context under which code is running. Ana bilgisayar, iş parçacığının. CurrentPrincipalöğesini ayarlayarak sorumluyu geçerli iş parçacığına iliştirir.The host attaches the principal to the current thread by setting Thread.CurrentPrincipal. Asıl öğe, kullanıcıyla ilgili bilgiler içeren ilişkili bir kimlik nesnesi içerir.The principal contains an associated Identity object that contains information about the user. Kullanıcının kimliği doğrulandıysa, Identity. IsAuthenticated özelliği truedeğerini döndürür.If the user is authenticated, the Identity.IsAuthenticated property returns true. Anonim istekler için, IsAuthenticated , falsedöndürür.For anonymous requests, IsAuthenticated returns false. Sorumlular hakkında daha fazla bilgi için bkz. rol tabanlı güvenlik.For more information about principals, see Role-Based Security.

Kimlik doğrulaması için HTTP Ileti IşleyicileriHTTP Message Handlers for Authentication

Kimlik doğrulaması için konağın kullanılması yerine, kimlik doğrulama mantığını bir http ileti işleyicisinekoyabilirsiniz.Instead of using the host for authentication, you can put authentication logic into an HTTP message handler. Bu durumda, ileti işleyicisi HTTP isteğini inceler ve sorumluyu ayarlar.In that case, the message handler examines the HTTP request and sets the principal.

Kimlik doğrulaması için ileti işleyicilerini ne zaman kullanmalısınız?When should you use message handlers for authentication? Aşağıda bazı dengeler verilmiştir:Here are some tradeoffs:

  • HTTP modülü, ASP.NET ardışık düzeni üzerinden geçen tüm istekleri görür.An HTTP module sees all requests that go through the ASP.NET pipeline. İleti işleyicisi yalnızca Web API 'sine yönlendirilen istekleri görür.A message handler only sees requests that are routed to Web API.
  • Belirli bir rotaya bir kimlik doğrulama düzeni uygulamanıza olanak sağlayan yönlendirme başına ileti işleyicileri ayarlayabilirsiniz.You can set per-route message handlers, which lets you apply an authentication scheme to a specific route.
  • HTTP modülleri IIS 'e özeldir.HTTP modules are specific to IIS. İleti işleyicileri ana bilgisayar belirsiz olduğundan, hem Web barındırma hem de kendiliğinden barındırma ile kullanılabilir.Message handlers are host-agnostic, so they can be used with both web-hosting and self-hosting.
  • HTTP modülleri, IIS günlüğe kaydetme, denetleme vb. için de yer alır.HTTP modules participate in IIS logging, auditing, and so on.
  • HTTP modülleri, ardışık düzende daha önce çalışır.HTTP modules run earlier in the pipeline. Kimlik doğrulamasını bir ileti işleyicisinde işletin, bu, işleyici çalışana kadar küme almaz.If you handle authentication in a message handler, the principal does not get set until the handler runs. Ayrıca, yanıt ileti işleyiciden ayrıldığında, sorumlu önceki sorumluya geri döner.Moreover, the principal reverts back to the previous principal when the response leaves the message handler.

Genellikle, kendi kendine barındırmayı desteklemeniz gerekmiyorsa, HTTP modülü daha iyi bir seçenektir.Generally, if you don't need to support self-hosting, an HTTP module is a better option. Kendi kendine barındırmayı desteklemeniz gerekiyorsa bir ileti işleyicisini düşünün.If you need to support self-hosting, consider a message handler.

Sorumluyu ayarlamaSetting the Principal

Uygulamanız herhangi bir özel kimlik doğrulama mantığı gerçekleştirirse, sorumluyu iki yerde ayarlamanız gerekir:If your application performs any custom authentication logic, you must set the principal on two places:

  • Thread. CurrentPrincipal.Thread.CurrentPrincipal. Bu özellik, .NET 'teki iş parçacığının sorumlusunu ayarlamaya yönelik standart bir yoldur.This property is the standard way to set the thread's principal in .NET.
  • HttpContext. Current. User.HttpContext.Current.User. Bu özellik ASP.NET 'e özgüdür.This property is specific to ASP.NET.

Aşağıdaki kod, sorumlunun nasıl ayarlanacağını göstermektedir:The following code shows how to set the principal:

private void SetPrincipal(IPrincipal principal)
{
    Thread.CurrentPrincipal = principal;
    if (HttpContext.Current != null)
    {
        HttpContext.Current.User = principal;
    }
}

Web barındırma için, sorumluyu her iki yerde de ayarlamanız gerekir; Aksi takdirde güvenlik bağlamı tutarsız hale gelebilir.For web-hosting, you must set the principal in both places; otherwise the security context may become inconsistent. Ancak, kendi kendine barındırma için HttpContext. Current null.For self-hosting, however, HttpContext.Current is null. Kodunuzun konağın belirsiz olduğundan emin olmak için, gösterildiği gibi HttpContext. Currentöğesine atamadan önce null değerini denetleyin.To ensure your code is host-agnostic, therefore, check for null before assigning to HttpContext.Current, as shown.

YetkilendirmeAuthorization

Yetkilendirme, daha sonra işlem hattında denetleyiciye yaklaşarak gerçekleşir.Authorization happens later in the pipeline, closer to the controller. Bu, kaynaklara erişim izni verdiğinizde daha ayrıntılı seçimler yapmanızı sağlar.That lets you make more granular choices when you grant access to resources.

  • Yetkilendirme filtreleri , denetleyici eyleminden önce çalışır.Authorization filters run before the controller action. İstek yetkilendirilmezse, filtre bir hata yanıtı döndürür ve eylem çağrılmaz.If the request is not authorized, the filter returns an error response, and the action is not invoked.
  • Bir denetleyici eylemi içinde, Apicontroller. User özelliğinden geçerli sorumluyu alabilirsiniz.Within a controller action, you can get the current principal from the ApiController.User property. Örneğin, bir kaynak listesini Kullanıcı adına göre filtreleyerek yalnızca o kullanıcıya ait olan kaynakları geri alabilirsiniz.For example, you might filter a list of resources based on the user name, returning only those resources that belong to that user.

[Yetkilendir] özniteliğini kullanmaUsing the [Authorize] Attribute

Web API 'SI, AuthorizeAttributeyerleşik bir yetkilendirme filtresi sağlar.Web API provides a built-in authorization filter, AuthorizeAttribute. Bu filtre, kullanıcının kimliğinin doğrulandığını denetler.This filter checks whether the user is authenticated. Aksi takdirde, eylemi çağırmadan HTTP durum kodu 401 (yetkilendirilmemiş) döndürür.If not, it returns HTTP status code 401 (Unauthorized), without invoking the action.

Filtreyi denetleyici düzeyinde küresel olarak veya tek tek eylemler düzeyinde uygulayabilirsiniz.You can apply the filter globally, at the controller level, or at the level of individual actions.

Küresel: her Web API denetleyicisine erişimi kısıtlamak için, genel filtre listesine AuthorizeAttribute filtresini ekleyin:Globally: To restrict access for every Web API controller, add the AuthorizeAttribute filter to the global filter list:

public static void Register(HttpConfiguration config)
{
    config.Filters.Add(new AuthorizeAttribute());
}

Denetleyici: belirli bir denetleyicinin erişimini kısıtlamak için, filtreyi denetleyiciye bir öznitelik olarak ekleyin:Controller: To restrict access for a specific controller, add the filter as an attribute to the controller:

// Require authorization for all actions on the controller.
[Authorize]
public class ValuesController : ApiController
{
    public HttpResponseMessage Get(int id) { ... }
    public HttpResponseMessage Post() { ... }
}

Eylem: belirli eylemlerin erişimini kısıtlamak için, eylem yöntemine özniteliği ekleyin:Action: To restrict access for specific actions, add the attribute to the action method:

public class ValuesController : ApiController
{
    public HttpResponseMessage Get() { ... }

    // Require authorization for a specific action.
    [Authorize]
    public HttpResponseMessage Post() { ... }
}

Alternatif olarak, denetleyiciyi kısıtlayabilir ve ardından özniteliği kullanarak belirli eylemlere anonim erişime izin verebilirsiniz [AllowAnonymous] .Alternatively, you can restrict the controller and then allow anonymous access to specific actions, by using the [AllowAnonymous] attribute. Aşağıdaki örnekte, Post yöntemi kısıtlıdır, ancak Get Yöntem anonim erişime izin verir.In the following example, the Post method is restricted, but the Get method allows anonymous access.

[Authorize]
public class ValuesController : ApiController
{
    [AllowAnonymous]
    public HttpResponseMessage Get() { ... }

    public HttpResponseMessage Post() { ... }
}

Önceki örneklerde, filtre tüm kimliği doğrulanmış kullanıcıların kısıtlı yöntemlere erişmesine izin verir; yalnızca anonim kullanıcılar tutulur. Ayrıca, erişimi belirli kullanıcılara veya belirli rollerdeki kullanıcılara sınırlayabilirsiniz:In the previous examples, the filter allows any authenticated user to access the restricted methods; only anonymous users are kept out. You can also limit access to specific users or to users in specific roles:

// Restrict by user:
[Authorize(Users="Alice,Bob")]
public class ValuesController : ApiController
{
}
   
// Restrict by role:
[Authorize(Roles="Administrators")]
public class ValuesController : ApiController
{
}

Note

Web API denetleyicileri için AuthorizeAttribute filtresi System. Web. http ad alanında bulunur.The AuthorizeAttribute filter for Web API controllers is located in the System.Web.Http namespace. System. Web. Mvc ad alanında, Web API denetleyicileriyle uyumlu olmayan MVC denetleyicileri için benzer bir filtre vardır.There is a similar filter for MVC controllers in the System.Web.Mvc namespace, which is not compatible with Web API controllers.

Özel Yetkilendirme filtreleriCustom Authorization Filters

Özel bir yetkilendirme filtresi yazmak için, bu türlerden birini türetebilirsiniz:To write a custom authorization filter, derive from one of these types:

  • AuthorizeAttribute.AuthorizeAttribute. Geçerli kullanıcıya ve kullanıcının rollerine göre yetkilendirme mantığını gerçekleştirmek için bu sınıfı genişletin.Extend this class to perform authorization logic based on the current user and the user's roles.
  • Authorizationfilterattribute.AuthorizationFilterAttribute. Geçerli Kullanıcı veya role dayalı olması gereken zaman uyumlu yetkilendirme mantığını gerçekleştirmek için bu sınıfı genişletin.Extend this class to perform synchronous authorization logic that is not necessarily based on the current user or role.
  • IAuthorizationFilter.IAuthorizationFilter. Zaman uyumsuz yetkilendirme mantığını gerçekleştirmek için bu arabirimi uygulayın; Örneğin, yetkilendirme mantığınızın zaman uyumsuz g/ç veya ağ çağrıları yapıyorsa.Implement this interface to perform asynchronous authorization logic; for example, if your authorization logic makes asynchronous I/O or network calls. (Yetkilendirme mantığınızın CPU ile sınırlı olması durumunda, bir zaman uyumsuz yöntem yazmanıza gerek olmadığından Authorizationfilterattribute'tan türemek daha basittir.)(If your authorization logic is CPU-bound, it is simpler to derive from AuthorizationFilterAttribute, because then you don't need to write an asynchronous method.)

Aşağıdaki diyagramda AuthorizeAttribute sınıfının sınıf hiyerarşisi gösterilmektedir.The following diagram shows the class hierarchy for the AuthorizeAttribute class.

Denetleyici eylemi Içinde yetkilendirmeAuthorization Inside a Controller Action

Bazı durumlarda, bir isteğin devam etmesini sağlayabilir, ancak durumu sorumlu temelinde değiştirebilirsiniz.In some cases, you might allow a request to proceed, but change the behavior based on the principal. Örneğin, döndürülen bilgiler kullanıcının rolüne bağlı olarak değişebilir.For example, the information that you return might change depending on the user's role. Bir denetleyici yöntemi içinde, Apicontroller. User özelliğinden geçerli sorumluyu alabilirsiniz.Within a controller method, you can get the current principal from the ApiController.User property.

public HttpResponseMessage Get()
{
    if (User.IsInRole("Administrators"))
    {
        // ...
    }
}