Rol tabanlı ve kaynak tabanlı yetkilendirme
Başvuru uygulamamız bir ASP.NET Core. Bu makalede, yetkilendirmeye yönelik iki genel yaklaşıma göz atarak bu makalede sağlanan yetkilendirme API'lerini ASP.NET Core.
- Rol tabanlı yetkilendirme. Bir kullanıcıya atanan rollere göre eylem yetkilendirme. Örneğin, bazı eylemler bir yönetici rolü gerektirir.
- Kaynak tabanlı yetkilendirme. Belirli bir kaynağa göre eylem yetkilendirme. Örneğin, her kaynağın bir sahibi olur. Sahip kaynağı silebilir; diğer kullanıcılar tarafından kullanılamaz.
Tipik bir uygulama her ikisinin bir karışımını işe alar. Örneğin, bir kaynağı silmek için kullanıcının kaynak sahibi veya yöneticisi olması gerekir.
Rol tabanlı yetkilendirme
Tailspin Surveys uygulaması aşağıdaki rolleri tanımlar:
- Yönetici. Bu kiracıya ait herhangi bir ankette tüm CRUD işlemlerini gerçekleştirin.
- Yaratıcısı. Yeni anketler oluşturabilir
- Okuyucu. Bu kiracıya ait tüm anketleri okuyabilir
Roller uygulamanın kullanıcıları için geçerlidir. Surveys uygulamasında kullanıcı yönetici, oluşturucu veya okuyucudur.
Rolleri tanımlama ve yönetme hakkında daha fazla bilgi için bkz. Uygulama rolleri.
Rolleri nasıl yönetmenize bakılmaksızın yetkilendirme kodunuz benzer şekilde olur. ASP.NET Core yetkilendirme ilkeleri adlı bir soyutlama vardır. Bu özellikle, yetkilendirme ilkelerini kodda tanımlar ve ardından bu ilkeleri denetleyici eylemlerine uygulayabilirsiniz. İlke, denetleyiciden çözüler.
İlkeleri oluşturma
İlke tanımlamak için önce uygulayan bir sınıf IAuthorizationRequirement oluşturun. 'den türetilen en kolay AuthorizationHandler yöntemdir. yönteminde Handle ilgili taleplere bakarak.
Tailspin Surveys uygulamasından bir örnek:
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, kullanıcının yeni bir anket oluşturma gereksinimini tanımlar. Kullanıcının SurveyAdmin veya SurveyCreator rolünde olması gerekir.
Başlangıç sınıfınıza, bir veya daha fazla gereksinimlerini içeren adlandırılmış bir ilke tanımlayın. Birden çok gereksinim varsa, kullanıcının yetkilendirilen tüm gereksinimleri karşılaması gerekir. Aşağıdaki kod iki ilke tanımlar:
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 kimlik doğrulama düzenini ayarlar ve bu da ASP.NET başarısız olması durumunda hangi kimlik doğrulama ara yazılımlarını çalıştırması gerektiğini belirtir. Bu durumda tanımlama bilgisi kimlik doğrulaması ara yazılımı, kullanıcıya "Yasak" sayfasına yönlendirene kadar tanımlama bilgisi kimlik doğrulaması ara yazılımı belirtiriz. Yasak sayfasının konumu tanımlama bilgisi ara yazılımı seçeneğinde AccessDeniedPath ayarlanır; bkz. Kimlik doğrulaması AccessDeniedPath
Denetleyici eylemlerini yetkilendirme
Son olarak, MVC denetleyicisinde bir eylemi yetkilendirmek için özniteliğinde ilkeyi Authorize ayarlayın:
[Authorize(Policy = PolicyNames.RequireSurveyCreator)]
public IActionResult Create()
{
var survey = new SurveyDTO();
return View(survey);
}
Önceki sürümlerde ASP.NET, özniteliğinde Roller özelliğini ayarlayın:
// old way
[Authorize(Roles = "SurveyCreator")]
Bu durum yine de ASP.NET Core ancak yetkilendirme ilkeleriyle karşılaştırıldığında bazı dezavantajları vardır:
- Belirli bir talep türünü varsayıyor. İlkeler herhangi bir talep türünü kontrol ediyor olabilir. Roller yalnızca bir talep t type'larıdır.
- Rol adı, özniteliğine sabit olarak kodlandı. İlkelerle yetkilendirme mantığının hepsi tek bir yerdedir ve yapılandırma ayarlarından güncelleştirmeyi ve hatta yüklemeyi kolaylaştırır.
- İlkeler, basit rol üyeliğiyle ifade edilemez daha karmaşık yetkilendirme kararları (örneğin, yaş > = 21) sağlar.
Kaynak tabanlı yetkilendirme
Kaynak tabanlı yetkilendirme, yetkilendirme bir işlemden etkilenecek belirli bir kaynağa bağlı olduğunda gerçekleşir. Tailspin Surveys uygulamasında her anketin sahibi ve sıfıra çok katkıda bulunanları vardır.
- Sahibi anketleri okuyabilir, güncelleştirecek, silebilir, yayımdan kaldırmış ve yayımdan kaldırmış olabilir.
- Sahibi ankete katkıda bulunanlar atay olabilir.
- Katkıda bulunanlar anketi okuyabilir ve güncelleştirmektedir.
"Sahip" ve "katkıda bulunan" rollerinin uygulama rolü olmadığını unutmayın; Bunlar, uygulama veritabanında anket başına depolanır. Örneğin, bir kullanıcının bir anketi silebilir olup olmadığını kontrol etmek için uygulama, kullanıcının o ankete sahip olup olmadığını denetler.
Bu ASP.NET Core AuthorizationHandler'dan türeterek ve Handle yöntemini geçersiz karak kaynak tabanlı yetkilendirmeyi gerçekleştirin.
public class SurveyAuthorizationHandler : AuthorizationHandler<OperationAuthorizationRequirement, Survey>
{
protected override void HandleRequirementAsync(AuthorizationHandlerContext context, OperationAuthorizationRequirement operation, Survey resource)
{
}
}
Bu sınıfın Survey nesneleri için kesin olarak yazıldıklarını fark edersiniz. Başlangıçta DI için sınıfı kaydetme:
services.AddSingleton<IAuthorizationHandler>(factory =>
{
return new SurveyAuthorizationHandler();
});
Yetkilendirme denetimleri gerçekleştirmek için, denetleyicilerinize girebilirsiniz IAuthorizationService arabirimini kullanın. Aşağıdaki kod, bir kullanıcının anket okuyabilip okuyabile olmadığını denetler:
if (await _authorizationService.AuthorizeAsync(User, survey, Operations.Read) == false)
{
return StatusCode(403);
}
Bir nesnesi ilediğimiz Survey için, bu çağrı çağıracak. SurveyAuthorizationHandler
Yetkilendirme kodunda, kullanıcının rol tabanlı ve kaynak tabanlı izinlerinin tümlerini toplamak ve ardından istenen işlem için kümeyi kontrol etmek iyi bir yaklaşımdır. İşte Surveys uygulamasından bir örnek. Uygulama birkaç izin türü tanımlar:
- Yönetici
- Katılımcı
- Oluşturucu
- Sahip
- Okuyucu
Uygulama ayrıca anketler üzerinde bir dizi olası işlem tanımlar:
- Oluştur
- Okuma
- Güncelleştir
- Sil
- Yayımlama
- Yayımdan kaldır
Aşağıdaki kod, belirli bir kullanıcı ve anket için bir izin listesi oluşturur. Bu kodun hem kullanıcının uygulama rollerine hem de ankette sahip/katkıda bulunan alanlarına bakarak dikkat edin.
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, izinlerin başka bir kiracının verilerine "sızmaması" gerekir. Anketler uygulamasında kiracılar genelinde Katkıda Bulunan iznine izin verilir; başka bir kiracıdan birini katkıda bulunan olarak atabilirsiniz. Diğer izin türleri, kullanıcının kiracısına ait olan kaynaklarla sınırlıdır. Bu gereksinimi zorlamak için kod, izni verilmeden önce kiracı kimliğini denetler. (Anket TenantId oluşturulduğunda atanan alan.)
Sonraki adım, işlemi (okuma, güncelleştirme veya silme gibi) izinlere göre kontrol etmektir. Surveys uygulaması, işlev arama tablosunu kullanarak bu adımı gerçekleştirir:
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) }
};
Örnek kod