Rol tabanlı ve kaynak tabanlı yetkilendirmeRole-based and resource-based authorization

GitHub Örnek kodGitHub Sample code

Bizim uygulama başvuru bir ASP.NET Core uygulaması.Our reference implementation is an ASP.NET Core application. Bu makalede iki genel yaklaşım, yetkilendirme için yetkilendirme ASP.NET Core içinde sağlanan API'leri kullanarak inceleyeceğiz.In this article we'll look at two general approaches to authorization, using the authorization APIs provided in ASP.NET Core.

  • Rol tabanlı yetkilendirme.Role-based authorization. Bir kullanıcıya atanan rollerin dayalı bir eylem yetkilendirme.Authorizing an action based on the roles assigned to a user. Örneğin, bazı eylemler, bir yönetici rolü gerektirir.For example, some actions require an administrator role.
  • Kaynak tabanlı yetkilendirme.Resource-based authorization. Belirli bir kaynağa göre bir eylem yetkilendirme.Authorizing an action based on a particular resource. Örneğin, her kaynak bir sahibi yoktur.For example, every resource has an owner. Kaynak sahibi silebilir; diğer kullanıcılar değiştiremez.The owner can delete the resource; other users cannot.

Normal bir uygulama, her ikisinin bir karışımı kullanılacaktır.A typical app will employ a mix of both. Örneğin, bir kaynağı silmek için kullanıcının kaynak sahibi olması gerekir veya yönetici yapabilirsiniz.For example, to delete a resource, the user must be the resource owner or an admin.

Rol tabanlı yetkilendirmeRole-Based Authorization

[Tailspin Surveys] Tailspin uygulama aşağıdaki rolleri tanımlar:The Tailspin Surveys application defines the following roles:

  • Yönetici.Administrator. Bu kiracıya ait herhangi bir anket tüm CRUD işlemleri gerçekleştirebilirsiniz.Can perform all CRUD operations on any survey that belongs to that tenant.
  • Oluşturucu.Creator. Yeni anket oluşturabilirsinizCan create new surveys
  • Okuyucu.Reader. Bu kiracıya ait herhangi bir anket okuyabilirsinizCan read any surveys that belong to that tenant

Rolleri uygulamak için kullanıcılar uygulama.Roles apply to users of the application. Anket uygulamasında, bir kullanıcı bir yönetici, oluşturucu veya okuyucu olabilir.In the Surveys application, a user is either an administrator, creator, or reader.

Tanımlamak ve rolleri yönetmek nasıl bir tartışma için bkz uygulama rolleri.For a discussion of how to define and manage roles, see Application roles.

Rolleri yönetme bağımsız olarak, yetkilendirme kodu aşağıdakine benzer olacaktır.Regardless of how you manage the roles, your authorization code will look similar. ASP.NET Core sahip olarak adlandırılan bir Özet Yetkilendirme İlkeleri.ASP.NET Core has an abstraction called authorization policies. Bu özellik ile kodda Yetkilendirme İlkeleri tanımlar ve sonra denetleyici eylemleri için bu ilkeleri uygulayın.With this feature, you define authorization policies in code, and then apply those policies to controller actions. İlke denetleyicisinden ayrılır.The policy is decoupled from the controller.

İlkeleri oluşturmaCreate policies

İlke tanımlamak için önce uygulayan bir sınıf oluşturun IAuthorizationRequirement.To define a policy, first create a class that implements IAuthorizationRequirement. Öğesinden türetilen en kolayıdır AuthorizationHandler.It's easiest to derive from AuthorizationHandler. İçinde Handle yöntemi, ilgili talep inceleyin.In the Handle method, examine the relevant claim(s).

Tailspin Surveys uygulaması bir örnek burada verilmiştir:Here is an example from the Tailspin Surveys application:

public class SurveyCreatorRequirement : AuthorizationHandler<SurveyCreatorRequirement>, IAuthorizationRequirement
{
    protected override Task HandleRequirementAsync(AuthorizationHandlerContext context, SurveyCreatorRequirement requirement)
    {
        if (context.User.HasClaim(ClaimTypes.Role, Roles.SurveyAdmin) ||
            context.User.HasClaim(ClaimTypes.Role, Roles.SurveyCreator))
        {
            context.Succeed(requirement);
        }
        return Task.FromResult(0);
    }
}

Bu sınıf, bir kullanıcının yeni anket oluşturmak gereksinim tanımlar.This class defines the requirement for a user to create a new survey. Kullanıcının SurveyAdmin veya SurveyCreator rolünde olması gerekir.The user must be in the SurveyAdmin or SurveyCreator role.

Başlangıç sınıfınızda, bir veya birkaç gereksinimi içeren bir adlandırılmış ilke tanımlayın.In your startup class, define a named policy that includes one or more requirements. Birden fazla gereksinimi varsa, kullanıcı karşılamalıdır her yetki verilmesi için gereksinim.If there are multiple requirements, the user must meet every requirement to be authorized. Aşağıdaki kod, iki ilke tanımlar:The following code defines two policies:

services.AddAuthorization(options =>
{
    options.AddPolicy(PolicyNames.RequireSurveyCreator,
        policy =>
        {
            policy.AddRequirements(new SurveyCreatorRequirement());
            policy.RequireAuthenticatedUser(); // Adds DenyAnonymousAuthorizationRequirement
            // By adding the CookieAuthenticationDefaults.AuthenticationScheme, if an authenticated
            // user is not in the appropriate role, they will be redirected to a "forbidden" page.
            policy.AddAuthenticationSchemes(CookieAuthenticationDefaults.AuthenticationScheme);
        });

    options.AddPolicy(PolicyNames.RequireSurveyAdmin,
        policy =>
        {
            policy.AddRequirements(new SurveyAdminRequirement());
            policy.RequireAuthenticatedUser();  
            policy.AddAuthenticationSchemes(CookieAuthenticationDefaults.AuthenticationScheme);
        });
});

Bu kod ayrıca ASP.NET yetkilendirme başarısız olursa hangi kimlik doğrulaması ara yazılımı çalışması gerektiğini söyleyen bir kimlik doğrulama şeması ayarlar.This code also sets the authentication scheme, which tells ASP.NET which authentication middleware should run if authorization fails. Bu durumda, çünkü tanımlama bilgisi kimlik doğrulaması ara yazılımı kullanıcı bir "Yasak" sayfasına yönlendirebilir biz tanımlama bilgisi kimlik doğrulaması ara yazılımı belirtin.In this case, we specify the cookie authentication middleware, because the cookie authentication middleware can redirect the user to a "Forbidden" page. Yasak sayfanın konumunu kümesinde AccessDeniedPath seçeneği için tanımlama bilgisi Ara; bkz kimlik doğrulaması ara yazılımını yapılandırma.The location of the Forbidden page is set in the AccessDeniedPath option for the cookie middleware; see Configuring the authentication middleware.

Denetleyici eylemleri YetkilendirAuthorize controller actions

Son olarak, bir MVC denetleyicisi eylemi yetkilendirmek için ilke kümesindeki Authorize özniteliği:Finally, to authorize an action in an MVC controller, set the policy in the Authorize attribute:

[Authorize(Policy = PolicyNames.RequireSurveyCreator)]
public IActionResult Create()
{
    var survey = new SurveyDTO();
    return View(survey);
}

ASP.NET önceki sürümlerinde ayarlarsınız rolleri öznitelik özelliği:In earlier versions of ASP.NET, you would set the Roles property on the attribute:

// old way
[Authorize(Roles = "SurveyCreator")]

Bu, ASP.NET Core desteklenir, ancak Yetkilendirme İlkeleri ile karşılaştırıldığında bazı dezavantajları vardır:This is still supported in ASP.NET Core, but it has some drawbacks compared with authorization policies:

  • Bu, belirli bir talep türü varsayar.It assumes a particular claim type. İlkeleri, herhangi bir talep türü için kontrol edebilirsiniz.Policies can check for any claim type. Yalnızca bir talep türünü rolleridir.Roles are just a type of claim.
  • Öznitelik içinde sabit kodlanmış rol adıdır.The role name is hard-coded into the attribute. İle yetkilendirme mantığının tek bir yerde, güncelleştirme veya hatta yük aracılığıyla yapılandırma ayarlarınızı kolaylaştırarak ilkesidir.With policies, the authorization logic is all in one place, making it easier to update or even load from configuration settings.
  • İlkeleri daha karmaşık yetkilendirme kararları olanak tanır (örn., geçerlilik süresi > = 21), ifade edilemez basit rolü üyeliğine göre.Policies enable more complex authorization decisions (e.g., age >= 21) that can't be expressed by simple role membership.

Kaynak tabanlı yetkilendirmeResource based authorization

Kaynak tabanlı yetkilendirme bir işlemden etkilenen belirli bir kaynak yetkilendirme bağımlı olduğunda gerçekleşir.Resource based authorization occurs whenever the authorization depends on a specific resource that will be affected by an operation. Tailspin Surveys uygulaması içinde her anket sahibi ve sıfır çok katkıda bulunanlar var.In the Tailspin Surveys application, every survey has an owner and zero-to-many contributors.

  • Sahibi okuma, güncelleştirme, silme, yayımlama ve anketi Yayımdan Kaldır.The owner can read, update, delete, publish, and unpublish the survey.
  • Sahibi, Katkıda Bulunanlar anketi atayabilirsiniz.The owner can assign contributors to the survey.
  • Katkıda Bulunanlar, okuma ve anketi güncelleştirin.Contributors can read and update the survey.

"Sahip" ve "katılımcı" uygulama rolleri olmadığına dikkat edin; ankette uygulama veritabanı başına depolanır.Note that "owner" and "contributor" are not application roles; they are stored per survey, in the application database. Bir kullanıcı bir anket silin olup olmadığını denetlemek için örneğin, uygulama kullanıcı bu anketi sahibi olup olmadığını denetler.To check whether a user can delete a survey, for example, the app checks whether the user is the owner for that survey.

ASP.NET Core, kaynak tabanlı yetkilendirme türeterek uygulamak AuthorizationHandler ve geçersiz kılma işlemek yöntemi.In ASP.NET Core, implement resource-based authorization by deriving from AuthorizationHandler and overriding the Handle method.

public class SurveyAuthorizationHandler : AuthorizationHandler<OperationAuthorizationRequirement, Survey>
{
    protected override void HandleRequirementAsync(AuthorizationHandlerContext context, OperationAuthorizationRequirement operation, Survey resource)
    {
    }
}

Bu sınıf, anket nesneler için kesin yazıldığını dikkat edin.Notice that this class is strongly typed for Survey objects. Sınıfı için DI başlangıçta kaydedin:Register the class for DI on startup:

services.AddSingleton<IAuthorizationHandler>(factory =>
{
    return new SurveyAuthorizationHandler();
});

Yetkilendirme denetimleri gerçekleştirmek için kullanın Iauthorizationservice arabirimi denetleyicilerinizi ekleyebilir.To perform authorization checks, use the IAuthorizationService interface, which you can inject into your controllers. Aşağıdaki kod, bir kullanıcı bir anket erişip erişemeyeceğini denetler:The following code checks whether a user can read a survey:

if (await _authorizationService.AuthorizeAsync(User, survey, Operations.Read) == false)
{
    return StatusCode(403);
}

Biz geçirin çünkü bir Survey nesne bu çağrı çağırılır SurveyAuthorizationHandler.Because we pass in a Survey object, this call will invoke the SurveyAuthorizationHandler.

Yetkilendirme kodunuzda kullanıcının rol tabanlı ve kaynak tabanlı izinler ve onay karşı istenen işlemi belirleyebilirsiniz toplama tümü için iyi bir yaklaşım olan.In your authorization code, a good approach is to aggregate all of the user's role-based and resource-based permissions, then check the aggregate set against the desired operation. Anketler uygulamasından bir örnek aşağıda verilmiştir.Here is an example from the Surveys app. Uygulama izni türlerinden tanımlar:The application defines several permission types:

  • Yönetim BölgesiAdmin
  • KatılımcıContributor
  • OluşturanCreator
  • SahipOwner
  • OkuyucuReader

Uygulama ayrıca anketler üzerinde olası işlemler kümesini tanımlar:The application also defines a set of possible operations on surveys:

  • OluşturCreate
  • OkumaRead
  • GüncelleştirmeUpdate
  • SilDelete
  • YayımlamaPublish
  • Yayımdan kaldırUnpublish

Aşağıdaki kod, belirli kullanıcı ve Anket izinlerini listesini oluşturur.The following code creates a list of permissions for a particular user and survey. Bu kod kullanıcının uygulama rollerini hem anket sahip/katkıda bulunan alanları bakan dikkat edin.Notice that this code looks at both the user's app roles, and the owner/contributor fields in the survey.

public class SurveyAuthorizationHandler : AuthorizationHandler<OperationAuthorizationRequirement, Survey>
{
    protected override Task HandleRequirementAsync(AuthorizationHandlerContext context, OperationAuthorizationRequirement requirement, Survey resource)
    {
        var permissions = new List<UserPermissionType>();
        int surveyTenantId = context.User.GetSurveyTenantIdValue();
        int userId = context.User.GetSurveyUserIdValue();
        string user = context.User.GetUserName();

        if (resource.TenantId == surveyTenantId)
        {
            // Admin can do anything, as long as the resource belongs to the admin's tenant.
            if (context.User.HasClaim(ClaimTypes.Role, Roles.SurveyAdmin))
            {
                context.Succeed(requirement);
                return Task.FromResult(0);
            }

            if (context.User.HasClaim(ClaimTypes.Role, Roles.SurveyCreator))
            {
                permissions.Add(UserPermissionType.Creator);
            }
            else
            {
                permissions.Add(UserPermissionType.Reader);
            }

            if (resource.OwnerId == userId)
            {
                permissions.Add(UserPermissionType.Owner);
            }
        }
        if (resource.Contributors != null && resource.Contributors.Any(x => x.UserId == userId))
        {
            permissions.Add(UserPermissionType.Contributor);
        }

        if (ValidateUserPermissions[requirement](permissions))
        {
            context.Succeed(requirement);
        }
        return Task.FromResult(0);
    }
}

Çok kiracılı bir uygulamada, izinleri "başka bir kiracının veri sızıntısı yoksa," emin olmanız gerekir.In a multi-tenant application, you must ensure that permissions don't "leak" to another tenant's data. Anket uygulamasında kiracılar genelinde katkıda bulunan izni verildiğinden — birisi katkıda bulunan olarak başka bir kiracıdaki atayabilirsiniz.In the Surveys app, the Contributor permission is allowed across tenants — you can assign someone from another tenant as a contributor. Kullanıcının kiracısında kaynakları diğer iznini türleri kısıtlanır.The other permission types are restricted to resources that belong to that user's tenant. Bu gereksinim zorunlu kılmak için kod, Kiracı kimliği izin vermeden önce denetler.To enforce this requirement, the code checks the tenant ID before granting the permission. ( TenantId Alan anket oluşturulduğunda atanan gibi.)(The TenantId field as assigned when the survey is created.)

Sonraki adım, işlemin (okuma, güncelleştirme, silme, vb.) izinlerine karşı denetlemektir.The next step is to check the operation (read, update, delete, etc) against the permissions. Surveys uygulamasını işlevleri arama tablosu kullanarak bu adımı gerçekleştirir:The Surveys app implements this step by using a lookup table of functions:

static readonly Dictionary<OperationAuthorizationRequirement, Func<List<UserPermissionType>, bool>> ValidateUserPermissions
    = new Dictionary<OperationAuthorizationRequirement, Func<List<UserPermissionType>, bool>>

    {
        { Operations.Create, x => x.Contains(UserPermissionType.Creator) },

        { Operations.Read, x => x.Contains(UserPermissionType.Creator) ||
                                x.Contains(UserPermissionType.Reader) ||
                                x.Contains(UserPermissionType.Contributor) ||
                                x.Contains(UserPermissionType.Owner) },

        { Operations.Update, x => x.Contains(UserPermissionType.Contributor) ||
                                x.Contains(UserPermissionType.Owner) },

        { Operations.Delete, x => x.Contains(UserPermissionType.Owner) },

        { Operations.Publish, x => x.Contains(UserPermissionType.Owner) },

        { Operations.UnPublish, x => x.Contains(UserPermissionType.Owner) }
    };

SonrakiNext