Not
Bu sayfaya erişim yetkilendirme gerektiriyor. Oturum açmayı veya dizinleri değiştirmeyi deneyebilirsiniz.
Bu sayfaya erişim yetkilendirme gerektiriyor. Dizinleri değiştirmeyi deneyebilirsiniz.
Bu makalede, Microsoft.Identity.Web kullanarak ASP.NET Core web API'lerinde yetkilendirme uygulayacaksınız. Korumalı kaynaklara erişimi denetlemek için kapsamları (temsilci izinleri) ve uygulama izinlerini (uygulama izinleri) doğrulayacaksınız. Örneklerde kimlik sağlayıcısı olarak Microsoft Entra ID kullanılır.
Yetkilendirme kavramlarını anlama
Bu bölümde kimlik doğrulama ve yetkilendirme arasındaki temel farklar ele alınmakta ve Microsoft.Identity.Web'in erişim belirteçlerinde neyi doğruladığı açıklanmaktadır.
Kimlik doğrulaması ve yetkilendirme karşılaştırması
| Konsept | Amaç | Result |
|---|---|---|
| Kimlik Doğrulaması | Kimliği doğrulama | 401 Başarısız olursa yetkisiz |
| Authorization | İzinleri doğrulama | Yetersizse 403 Yasak |
Neler doğrulanır?
Bir web API'si erişim belirteci aldığında Microsoft. Identity.Web doğrular:
- Jeton imzası - Güvenilir bir otoriteden mi?
- Token kitle - Bu API için mi tasarlandı?
- Jeton süresi dolma - Hala geçerli mi?
- Kapsamlar/Roller - İstemci uygulaması ve konu (kullanıcı) doğru izinlere sahip mi?
Bu kılavuz, kapsamları ve uygulama izinlerini doğrulamak için #4'e odaklanır.
Kapsamlar (temsilci izinleri)
Kapsamlar, kullanıcı bir uygulamaya kendi adına işlem yapma izni verdiğinde (örneğin, oturum açmış bir kullanıcı adına çağrılan bir web API'sinde) uygulanır.
| Ayrıntı | Değer |
|---|---|
| Token talebi |
scp veya scope (istemci uygulaması); roles (kullanıcı) |
| Örnek değerler |
"access_as_user", "User.Read", "Files.ReadWrite" |
Uygulama izinleri (uygulama izinleri)
Uygulama izinleri, bir uygulama istemci kimlik bilgilerini kullanan bir daemon veya arka plan hizmeti gibi kullanıcı bağlamı olmadan web API'sini kendisi olarak çağırdığında uygulanır.
| Ayrıntı | Değer |
|---|---|
| Token talebi | roles |
| Örnek değerler |
"Mail.Read.All", "User.Read.All" |
RequiredScope ile kapsamları doğrulama
özniteliği, RequiredScope erişim belirtecinin belirtilen kapsamlardan en az birini içerdiğini denetler. API'niz yalnızca kullanıcı tarafından atanan isteklere hizmet veriyorsa bu özniteliği kullanın.
Kapsam doğrulamayı ayarlama
API'nizde kapsam doğrulamayı etkinleştirmek için bu adımları izleyin.
1. API'nizde yetkilendirmeyi etkinleştirin:
Uygulama işlem hattınıza kimlik doğrulaması ve yetkilendirme hizmetleri ekleyin:
using Microsoft.AspNetCore.Authentication.JwtBearer;
using Microsoft.Identity.Web;
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
.AddMicrosoftIdentityWebApi(builder.Configuration.GetSection("AzureAd"));
builder.Services.AddAuthorization(); // Required for authorization
var app = builder.Build();
app.UseAuthentication();
app.UseAuthorization(); // Must be after UseAuthentication
app.MapControllers();
app.Run();
2. Denetleyicileri veya eylemleri koruyun:
[Authorize] ve [RequiredScope] özniteliklerini kontrolcünüz veya bireysel işlemleriniz için uygulayın.
using Microsoft.AspNetCore.Authorization;
using Microsoft.Identity.Web.Resource;
[Authorize]
[RequiredScope("access_as_user")]
public class TodoListController : ControllerBase
{
[HttpGet]
public IActionResult GetTodos()
{
// Only accessible if token has "access_as_user" scope
return Ok(new[] { "Todo 1", "Todo 2" });
}
}
Kapsam desenlerini uygulama
Uygulamanızdaki kapsamları yönetme şeklinize en uygun deseni seçin.
Desen 1: Sabit kodlanmış kapsamlar
Kapsamlar sabitlendiğinde ve geliştirme zamanında bilindiğinde bu düzeni kullanın.
[Authorize]
[RequiredScope("access_as_user")]
public class TodoListController : ControllerBase
{
// All actions require "access_as_user" scope
}
Birden çok kapsamdan birini kabul etmek için bunları parametre olarak listeleyin:
[Authorize]
[RequiredScope("read", "write", "admin")]
public class TodoListController : ControllerBase
{
// Token must have "read" OR "write" OR "admin"
}
Kalıp 2: Yapılandırma kapsamları
Kapsamların ortam başına yapılandırılabilir olması gerektiğinde bu düzeni kullanın. Yapılandırma dosyanızda kapsamları tanımlayın:
appsettings.json:
{
"AzureAd": {
"Instance": "https://login.microsoftonline.com/",
"TenantId": "your-tenant-id",
"ClientId": "your-api-client-id",
"Scopes": "access_as_user read write"
}
}
Denetleyicinizdeki yapılandırma anahtarına başvurun:
[Authorize]
[RequiredScope(RequiredScopesConfigurationKey = "AzureAd:Scopes")]
public class TodoListController : ControllerBase
{
// Scopes read from configuration
}
Bu yaklaşım, kapsamları yeniden derlemeden değiştirmenize olanak tanır.
Desen 3: Eylem düzeyi kapsamlar
Farklı eylemler farklı izinler gerektirdiğinde bu düzeni kullanın. Bireysel eylem yöntemlerine [RequiredScope] uygula
[Authorize]
public class TodoListController : ControllerBase
{
[HttpGet]
[RequiredScope("read")]
public IActionResult GetTodos()
{
return Ok(todos);
}
[HttpPost]
[RequiredScope("write")]
public IActionResult CreateTodo([FromBody] Todo todo)
{
// Only tokens with "write" scope can create
return CreatedAtAction(nameof(GetTodos), todo);
}
[HttpDelete("{id}")]
[RequiredScope("admin")]
public IActionResult DeleteTodo(int id)
{
// Only tokens with "admin" scope can delete
return NoContent();
}
}
Doğrulama akışını anlama
Bir istek geldiğinde ara yazılım bunu aşağıdaki sırayla işler:
- ASP.NET Core kimlik doğrulaması ara yazılımı belirteci doğrular
-
RequiredScopeveyascptalebine yönelikscopeöznitelik denetimleri - Belirteç en az bir eşleşen kapsam içeriyorsa istek devam eder.
- Eşleşen kapsam bulunmazsa, API bir 403 Yasaklama yanıtı döndürür.
Aşağıdaki örnekte tipik bir hata yanıtı gösterilmektedir:
{
"error": "insufficient_scope",
"error_description": "The token does not have the required scope 'access_as_user'."
}
RequiredScopeOrAppPermission ile uygulama izinlerini doğrulama
RequiredScopeOrAppPermission özniteliği kapsamları (temsilci) veya uygulama izinlerini (uygulama) doğrular. API'niz aynı uç noktadan hem kullanıcı tarafından temsilci atanan uygulamalara hem de daemon/hizmet uygulamalarına hizmet veriyorsa bu özniteliği kullanın.
API'niz yalnızca kullanıcı tarafından atanan isteklere hizmet veriyorsa, bunun yerine kullanın RequiredScope .
Kapsam veya uygulama izni doğrulamayı ayarlama
İki belirteç türünü de kabul etmek için özniteliğini uygulayın:
using Microsoft.Identity.Web.Resource;
[Authorize]
[RequiredScopeOrAppPermission(
AcceptedScope = new[] { "access_as_user" },
AcceptedAppPermission = new[] { "TodoList.ReadWrite.All" }
)]
public class TodoListController : ControllerBase
{
[HttpGet]
public IActionResult GetTodos()
{
// Accessible with EITHER:
// - User-delegated token with "access_as_user" scope, OR
// - App-only token with "TodoList.ReadWrite.All" app permission
return Ok(todos);
}
}
Ayarlardan uygulama izinlerini yapılandırma
Kapsamları ve uygulama izinlerini yeniden derlemeden değiştirmek için yapılandırmada depolayın.
appsettings.json:
{
"AzureAd": {
"Instance": "https://login.microsoftonline.com/",
"TenantId": "your-tenant-id",
"ClientId": "your-api-client-id",
"Scopes": "access_as_user",
"AppPermissions": "TodoList.ReadWrite.All TodoList.Admin"
}
}
Denetleyicinizdeki yapılandırma anahtarlarını inceleyin:
[Authorize]
[RequiredScopeOrAppPermission(
RequiredScopesConfigurationKey = "AzureAd:Scopes",
RequiredAppPermissionsConfigurationKey = "AzureAd:AppPermissions"
)]
public class TodoListController : ControllerBase
{
// Scopes and app permissions from configuration
}
Belirteç talebi farklarını karşılaştırma
Aşağıdaki tabloda taleplerin kullanıcı tarafından atanan ve yalnızca uygulama belirteçleri arasında nasıl farklılık gösterdiği gösterilmektedir:
| Belirteç Türü | İddia | Örnek Değer |
|---|---|---|
| Kullanıcı tarafından atanan |
scp veya scope |
"access_as_user User.Read" |
| Yalnızca uygulama | roles |
["TodoList.ReadWrite.All"] |
Aşağıdaki örnekte kullanıcı yetkilendirmesiyle oluşturulan bir belirteç gösterilmektedir:
{
"aud": "api://your-api-client-id",
"iss": "https://login.microsoftonline.com/.../v2.0",
"scp": "access_as_user",
"sub": "user-object-id",
...
}
Aşağıdaki örnekte yalnızca uygulama belirteci gösterilmektedir:
{
"aud": "api://your-api-client-id",
"iss": "https://login.microsoftonline.com/.../v2.0",
"roles": ["TodoList.ReadWrite.All"],
"sub": "app-object-id",
...
}
Yetkilendirme ilkeleri oluşturma
Karmaşık yetkilendirme senaryoları için ASP.NET Core yetkilendirme ilkelerini kullanın. İlkeler kuralları merkezileştirmenize, birden çok gereksinimi birleştirmenize ve test edilebilir yetkilendirme mantığı yazmanıza olanak sağlar.
| Benefit | Description |
|---|---|
| Merkezi mantık | Yetkilendirme kurallarını bir kez tanımlama, her yerde yeniden kullanma |
| Birleştirilebilir | Birden çok gereksinimi birleştirme (kapsamlar + talepler + özel mantık) |
| Sınanabilir | Yetkilendirme mantığının birim testi daha kolay. |
| Esnek | Kapsam doğrulaması dışındaki özel gereksinimler |
Desen 1: RequireScope ile ilke tanımlama
Belirli kapsamlar gerektiren adlandırılmış ilkeler tanımlayın ve ardından denetleyicilerinizde bunlara başvurun:
using Microsoft.Identity.Web;
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
.AddMicrosoftIdentityWebApi(builder.Configuration.GetSection("AzureAd"));
builder.Services.AddAuthorization(options =>
{
options.AddPolicy("TodoReadPolicy", policyBuilder =>
{
policyBuilder.RequireScope("read", "access_as_user");
});
options.AddPolicy("TodoWritePolicy", policyBuilder =>
{
policyBuilder.RequireScope("write", "admin");
});
});
var app = builder.Build();
İlkeleri denetleyici eylemlerine uygulayın:
[Authorize]
public class TodoListController : ControllerBase
{
[HttpGet]
[Authorize(Policy = "TodoReadPolicy")]
public IActionResult GetTodos()
{
return Ok(todos);
}
[HttpPost]
[Authorize(Policy = "TodoWritePolicy")]
public IActionResult CreateTodo([FromBody] Todo todo)
{
return CreatedAtAction(nameof(GetTodos), todo);
}
}
Örnek 2: ScopeAuthorizationRequirement ile politika tanımlama
Daha açık kapsam gereksinimleri için kullanın ScopeAuthorizationRequirement :
using Microsoft.Identity.Web;
using Microsoft.Identity.Web.Resource;
builder.Services.AddAuthorization(options =>
{
options.AddPolicy("CustomPolicy", policyBuilder =>
{
policyBuilder.AddRequirements(
new ScopeAuthorizationRequirement(new[] { "access_as_user" })
);
});
});
Desen 3: Varsayılan ilke ayarlama
Tüm [Authorize] özniteliklere otomatik olarak uygulanan bir varsayılan ilke ayarlayın:
builder.Services.AddAuthorization(options =>
{
var defaultPolicy = new AuthorizationPolicyBuilder()
.RequireScope("access_as_user")
.Build();
options.DefaultPolicy = defaultPolicy;
});
Artık her [Authorize] öznitelik için access_as_user kapsam gereklidir.
[Authorize] // Automatically requires "access_as_user" scope
public class TodoListController : ControllerBase
{
// All actions protected by default policy
}
Desen 4: Birden çok gereksinimi birleştirme
Kapsam, rol ve kimlik doğrulama gereksinimlerini tek bir ilkede birleştirin:
builder.Services.AddAuthorization(options =>
{
options.AddPolicy("AdminPolicy", policyBuilder =>
{
policyBuilder.RequireScope("admin");
policyBuilder.RequireRole("Admin"); // Also check role claim
policyBuilder.RequireAuthenticatedUser();
});
});
Desen 5: Yapılandırmadan ilke oluşturma
İlkeleri ortama özgü tutmak için kapsamları yapılandırmadan yükleyin:
var requiredScopes = builder.Configuration["AzureAd:Scopes"]?.Split(' ');
builder.Services.AddAuthorization(options =>
{
options.AddPolicy("ApiAccessPolicy", policyBuilder =>
{
if (requiredScopes != null)
{
policyBuilder.RequireScope(requiredScopes);
}
});
});
İstekleri kiracıya göre filtreleme
Belirli Microsoft Entra kiracılarından gelen belirteçlere API erişimini kısıtlayın. Bu, çok kiracılı API'nizin yalnızca onaylanan müşteri kiracılarından gelen istekleri kabul etmesi gerektiğinde kullanışlıdır.
İzin verilen kiracılara erişimi kısıtlama
Kiracı kimliği beyanını izin verilenler listesine göre denetleen bir ilke tanımlayın:
builder.Services.AddAuthorization(options =>
{
string[] allowedTenants =
{
"14c2f153-90a7-4689-9db7-9543bf084dad", // Contoso tenant
"af8cc1a0-d2aa-4ca7-b829-00d361edb652", // Fabrikam tenant
"979f4440-75dc-4664-b2e1-2cafa0ac67d1" // Northwind tenant
};
options.AddPolicy("AllowedTenantsOnly", policyBuilder =>
{
policyBuilder.RequireClaim(
"http://schemas.microsoft.com/identity/claims/tenantid",
allowedTenants
);
});
// Apply to all endpoints by default
options.DefaultPolicy = options.GetPolicy("AllowedTenantsOnly");
});
Ayarlardan kiracı filtrelemeyi yapılandırma
İzin verilen kiracı kimliklerini kod değişikliği olmadan yönetmek için yapılandırmada depolayın.
appsettings.json:
{
"AzureAd": {
"Instance": "https://login.microsoftonline.com/",
"ClientId": "your-api-client-id",
"AllowedTenants": [
"14c2f153-90a7-4689-9db7-9543bf084dad",
"af8cc1a0-d2aa-4ca7-b829-00d361edb652"
]
}
}
Kiracı listesini okuyun ve başlangıçta ilkeyi oluşturun:
var allowedTenants = builder.Configuration.GetSection("AzureAd:AllowedTenants")
.Get<string[]>();
builder.Services.AddAuthorization(options =>
{
options.AddPolicy("AllowedTenantsOnly", policyBuilder =>
{
policyBuilder.RequireClaim(
"http://schemas.microsoft.com/identity/claims/tenantid",
allowedTenants ?? Array.Empty<string>()
);
});
});
Kiracı bazlı filtreleme ile kapsamları birleştirme
Hem geçerli bir kapsam hem de onaylı bir kiracı gerektiren bir ilke oluşturun:
builder.Services.AddAuthorization(options =>
{
options.AddPolicy("SecureApiAccess", policyBuilder =>
{
// Require specific scope
policyBuilder.RequireScope("access_as_user");
// AND require specific tenant
policyBuilder.RequireClaim(
"http://schemas.microsoft.com/identity/claims/tenantid",
allowedTenants
);
});
});
En iyi yöntemleri izleyin
Güvenli, sürdürülebilir yetkilendirme mantığı oluşturmak için bu önerileri uygulayın.
Yapılması Gerekenler
1. Her zaman kapsam doğrulaması ile eşleştirin [Authorize] :
[Authorize] // Authentication
[RequiredScope("access_as_user")] // Authorization
public class MyController : ControllerBase { }
2. Ortama özgü kapsamlar için yapılandırmayı kullanın:
[RequiredScope(RequiredScopesConfigurationKey = "AzureAd:Scopes")]
3. En az ayrıcalık uygula:
[HttpGet]
[RequiredScope("read")] // Only read permission needed
[HttpPost]
[RequiredScope("write")] // Write permission for modifications
4. Karmaşık yetkilendirme için ilkeleri kullanın:
builder.Services.AddAuthorization(options =>
{
options.AddPolicy("AdminOnly", policy =>
{
policy.RequireScope("admin");
policy.RequireClaim("department", "IT");
});
});
5. Geliştirme sırasında ayrıntılı hata yanıtlarını etkinleştirin:
if (builder.Environment.IsDevelopment())
{
Microsoft.IdentityModel.Logging.IdentityModelEventSource.ShowPII = true;
}
Yapılmaması Gerekenler
1. [Authorize] kullanırken RequiredScope atlamayın:
// Wrong - RequiredScope won't work without [Authorize]
[RequiredScope("access_as_user")]
public class MyController : ControllerBase { }
// Correct
[Authorize]
[RequiredScope("access_as_user")]
public class MyController : ControllerBase { }
2. Üretimde kiracı kimliklerini sabit kodlamayın:
// Wrong
policyBuilder.RequireClaim("tid", "14c2f153-90a7-4689-9db7-9543bf084dad");
// Better - use configuration
var tenants = Configuration.GetSection("AllowedTenants").Get<string[]>();
policyBuilder.RequireClaim("tid", tenants);
3. Kapsamları rollerle karıştırmayın:
// Wrong - This checks roles claim, not scopes
[RequiredScope("Admin")] // "Admin" is typically a role, not a scope
// Correct
[RequiredScope("access_as_user")] // Scope
[Authorize(Roles = "Admin")] // Role
4. Üretim ortamı hata iletilerinde hassas kapsam bilgilerini ifşa etme:
Üretim ortamları için uygun günlük düzeylerini ve hata işlemeyi yapılandırın.
Yetkilendirme sorunlarını giderme
Yaygın yetkilendirme sorunlarını tanılamak için aşağıdaki kılavuzu kullanın.
403 Yasak - eksik kapsam
Hata: API, geçerli bir belirteçle bile 403 döndürür.
Tanı:
- jwt.ms'deki jetonu çözümle.
-
scpveyascopeiddiasını kontrol edin. - Değerin özniteliğinizle eşleştiğinden
RequiredScopeemin olun.
Çözüm:
- belirteci alırken istemci uygulamasının doğru kapsamı istediğinden emin olun.
- kapsamın Microsoft Entra'daki API uygulama kaydında kullanıma sunulduğundan emin olun.
- Gerekirse yönetici onayı verin.
RequiredScope çalışmıyor
Belirti: Özniteliği yoksayılmış gibi görünüyor.
Denetleyin:
- Özniteliğini eklediniz
[Authorize]mi? -
app.UseAuthorization(),app.UseAuthentication()sonrası mı çağrılır? - Kayıtlı mı
services.AddAuthorization()?
Yapılandırma anahtarı bulunamadı
Hata: Kapsam doğrulaması sessizce başarısız oluyor.
Denetleyin:
{
"AzureAd": {
"Scopes": "access_as_user" // Matches RequiredScopesConfigurationKey
}
}
Yapılandırma yolunun tam olarak eşleştiğinden emin olun.