Güvenli .NET Mikro Hizmetleri ve Web Uygulamaları oluşturma

Tavsiye

Bu içerik, .NET Docs veya çevrimdışı olarak okunabilen ücretsiz indirilebilir bir PDF olarak sağlanan Kapsayıcılı .NET Uygulamaları için .NET Mikro Hizmet Mimarisi adlı e-Kitap'tan bir alıntıdır.

.NET Mikro Hizmetler Mimarisi Kapsayıcılı .NET Uygulamaları için eKitabın kapak küçük resmi .

Mikro hizmetlerde ve web uygulamalarında güvenlikle ilgili o kadar çok özellik vardır ki konu bunun gibi birkaç kitabı kolayca alabilir. Bu nedenle, bu bölümde kimlik doğrulaması, yetkilendirme ve uygulama gizli dizilerine odaklanacağız.

.NET mikro hizmetlerinde ve web uygulamalarında kimlik doğrulamasını uygulama

Genellikle bir hizmet tarafından yayımlanan kaynakların ve API'lerin belirli güvenilen kullanıcılar veya istemciler ile sınırlı olması gerekir. Bu tür API düzeyinde güven kararları vermenin ilk adımı kimlik doğrulamasıdır. Kimlik doğrulaması, kullanıcının kimliğini güvenilir bir şekilde doğrulama işlemidir.

Mikro hizmet senaryolarında kimlik doğrulaması genellikle merkezi olarak işlenir. API Gateway kullanıyorsanız, Şekil 9-1'de gösterildiği gibi ağ geçidi kimlik doğrulaması için iyi bir yerdir. Bu yaklaşımı kullanırsanız, ağ geçidinden gelen veya gelmeyen iletilerin kimliğini doğrulamak için ek güvenlik sağlanmadığı sürece tek tek mikro hizmetlere doğrudan (API Gateway olmadan) ulaşılamadığından emin olun.

İstemci mobil uygulamasının arka uçla nasıl etkileşime geçtiğini gösteren Diyagramı.

Şekil 9-1. API Gateway ile merkezi kimlik doğrulaması

API Gateway kimlik doğrulamasını merkezileştirdiğinde, istekleri mikro hizmetlere iletirken kullanıcı bilgilerini ekler. Hizmetlere doğrudan erişilebiliyorsa, kullanıcıların kimliğini doğrulamak için Azure Active Directory gibi bir kimlik doğrulama hizmeti veya güvenlik belirteci hizmeti (STS) olarak davranan ayrılmış bir kimlik doğrulama mikro hizmeti kullanılabilir. Güven kararları, güvenlik belirteçleri veya tanımlama bilgileriyle hizmetler arasında paylaşılır. (Bu belirteçler gerekirse tanımlama bilgisi paylaşımı uygulanarak ASP.NET Core uygulamaları arasında paylaşılabilir.) Bu desen Şekil 9-2'de gösterilmiştir.

Arka uç mikro hizmetleri aracılığıyla kimlik doğrulamayı gösteren diyagram.

Şekil 9-2. Kimlik mikro hizmeti ile kimlik doğrulaması yapılır; güven, yetkilendirme belirteciyle paylaşılır.

Mikro hizmetlere doğrudan erişildiğinde, kimlik doğrulaması ve yetkilendirme içeren güven, mikro hizmetler arasında paylaşılan ayrılmış bir mikro hizmet tarafından verilen bir güvenlik belirteci tarafından işlenir.

ASP.NET Çekirdek Kimliği ile kimlik doğrulaması

ASP.NET Core'da bir uygulamanın kullanıcılarını tanımlamak için birincil mekanizma ASP.NET Core Identity üyelik sistemidir. ASP.NET Core Identity, kullanıcı bilgilerini (oturum açma bilgileri, roller ve talepler dahil) geliştirici tarafından yapılandırılan bir veri deposunda depolar. Genellikle ASP.NET Core Identity veri deposu, pakette Microsoft.AspNetCore.Identity.EntityFrameworkCore sağlanan bir Entity Framework deposudur. Ancak, kimlik bilgilerini Azure Tablo Depolama, CosmosDB veya diğer konumlarda depolamak için özel depolar veya diğer üçüncü taraf paketleri kullanılabilir.

Tavsiye

ASP.NET Core 2.1 ve üzeri, Razor Sınıf Kitaplığı olarak ASP.NET Core Identity sağlar, bu nedenle önceki sürümlerde olduğu gibi projenizde gerekli kodların çoğunu görmezsiniz. Kimlik kodunu gereksinimlerinize uyacak şekilde özelleştirme hakkında ayrıntılı bilgi için bkz. ASP.NET Core projelerinde yapı iskelesi kimliği.

Aşağıdaki kod, tek tek kullanıcı hesabı kimlik doğrulaması seçili ASP.NET Çekirdek Web Uygulaması MVC proje şablonundan alınır. Program.cs dosyasında Entity Framework Core kullanarak ASP.NET Core Kimliğini yapılandırmayı gösterir.

//...
builder.Services.AddDbContext<ApplicationDbContext>(options =>
    options.UseSqlServer(
        builder.Configuration.GetConnectionString("DefaultConnection")));

builder.Services.AddDefaultIdentity<IdentityUser>(options =>
    options.SignIn.RequireConfirmedAccount = true)
        .AddEntityFrameworkStores<ApplicationDbContext>();

builder.Services.AddRazorPages();
//...

ASP.NET Core Identity yapılandırıldıktan sonra, hizmetin app.UseAuthentication() dosyasında aşağıdaki kodda gösterildiği gibi endpoints.MapRazorPages() ve öğelerini ekleyerek etkinleştirebilirsiniz.

//...
app.UseRouting();

app.UseAuthentication();
app.UseAuthorization();

app.UseEndpoints(endpoints =>
{
    endpoints.MapRazorPages();
});
//...

Önemli

Öncesindeki koddaki satırlar, Identity'nin düzgün çalışması için GÖSTERİLEN DÜZENDE OLMALIDIR.

ASP.NET Çekirdek Kimliği'nin kullanılması birkaç senaryoya olanak tanır:

  • UserManager türünü (userManager.CreateAsync) kullanarak yeni kullanıcı bilgileri oluşturun.

  • SignInManager türünü kullanarak kullanıcıların kimliğini doğrulayın. signInManager.SignInAsync doğrudan oturum açmak için kullanabilir veya signInManager.PasswordSignInAsync kullanıcının parolasının doğru olduğunu onaylayarak oturum açabilirsiniz.

  • Bir kullanıcıyı, bilgilerinin ASP.NET Core Identity middleware tarafından okunan tanımlama bilgisinde saklandığı şekilde tanımlayın ki tarayıcıdan gelen sonraki istekler oturum açmış kullanıcının kimliği ve taleplerini içersin.

ASP.NET Core Identity , iki öğeli kimlik doğrulamasını da destekler.

Yerel bir kullanıcı veri deposu kullanan ve çerezleri kullanarak istekler arasında kimliği koruyan kimlik doğrulama senaryoları için (MVC web uygulamalarında olduğu gibi) ASP.NET Core Identity önerilen bir çözümdür.

Dış sağlayıcılarla kimlik doğrulaması

ASP.NET Core, kullanıcıların OAuth 2.0 akışları aracılığıyla oturum açmasına izin vermek için dış kimlik doğrulama sağlayıcılarının kullanılmasını da destekler. Bu, kullanıcıların Microsoft, Google, Facebook veya Twitter gibi sağlayıcılardan gelen mevcut kimlik doğrulama işlemlerini kullanarak oturum açabileceği ve bu kimlikleri uygulamanızdaki bir ASP.NET Core kimliğiyle ilişkilendirebileceği anlamına gelir.

Dış kimlik doğrulamasını kullanmak için, daha önce belirtildiği gibi kimlik doğrulama ara yazılımının yanı sıra yöntemini kullanarak app.UseAuthentication() , dış sağlayıcıyı aşağıdaki örnekte gösterildiği gibi Program.cs'a da kaydetmeniz gerekir:

//...
services.AddDefaultIdentity<IdentityUser>(options => options.SignIn.RequireConfirmedAccount = true)
    .AddEntityFrameworkStores<ApplicationDbContext>();

services.AddAuthentication()
    .AddMicrosoftAccount(microsoftOptions =>
    {
        microsoftOptions.ClientId = builder.Configuration["Authentication:Microsoft:ClientId"];
        microsoftOptions.ClientSecret = builder.Configuration["Authentication:Microsoft:ClientSecret"];
    })
    .AddGoogle(googleOptions => { ... })
    .AddTwitter(twitterOptions => { ... })
    .AddFacebook(facebookOptions => { ... });
//...

Popüler dış kimlik doğrulama sağlayıcıları ve bunların ilişkili NuGet paketleri aşağıdaki tabloda gösterilmiştir:

Sağlayıcı Paket
Microsoft Microsoft.AspNetCore.Authentication.MicrosoftAccount
Google Microsoft.AspNetCore.Authentication.Google
Facebook Microsoft.AspNetCore.Authentication.Facebook
Heyecan Microsoft.AspNetCore.Authentication.Twitter

Her durumda, satıcıya bağımlı olan ve genellikle şunları içeren bir uygulama kayıt yordamını tamamlamanız gerekir:

  1. İstemci Uygulama Kimliği alınıyor.
  2. İstemci Uygulama Gizli Anahtarını Alma.
  3. Yetkilendirme ara yazılımı ve kayıtlı sağlayıcı tarafından işlenen yeniden yönlendirme URL'sini yapılandırma
  4. İsteğe bağlı olarak, Tek Oturum Açma (SSO) senaryosunda oturumu kapatma işlemini düzgün bir şekilde yönetmek için bir oturum kapatma URL'si yapılandırma.

Uygulamanızı bir dış sağlayıcı için yapılandırma hakkında ayrıntılı bilgi için ASP.NET Core belgelerindeki Dış sağlayıcı kimlik doğrulamasına bakın).

Tavsiye

Tüm ayrıntılar, daha önce bahsedilen yetkilendirme ara yazılımı ve hizmetler tarafından işlenir. Bu nedenle, Daha önce bahsedilen kimlik doğrulama sağlayıcılarını kaydetmenin yanı sıra Şekil 9-3'te gösterildiği gibi Visual Studio'da ASP.NET Core web uygulaması projesini oluştururken Tek Tek Kullanıcı Hesabı kimlik doğrulaması seçeneğini belirlemeniz gerekir.

Yeni ASP.NET Çekirdek Web Uygulaması iletişim kutusunun ekran görüntüsü.

Şekil 9-3. Visual Studio 2019'da bir web uygulaması projesi oluştururken dış kimlik doğrulaması kullanmak için Bireysel Kullanıcı Hesapları seçeneğini belirleme.

Daha önce listelenen dış kimlik doğrulama sağlayıcılarına ek olarak, çok daha fazla dış kimlik doğrulama sağlayıcısı kullanmak için ara yazılım sağlayan üçüncü taraf paketleri mevcuttur. Liste için GitHub'daki AspNet.Security.OAuth.Providers deposuna bakın.

Bazı özel ihtiyaçları çözmek için kendi dış kimlik doğrulama ara yazılımınızı da oluşturabilirsiniz.

Taşıyıcı belirteçlerle kimlik doğrulaması

ASP.NET Çekirdek Kimlik (veya Kimlik artı dış kimlik doğrulama sağlayıcıları) ile kimlik doğrulaması, kullanıcı bilgilerinin tanımlama bilgisinde depolanmasının uygun olduğu birçok web uygulaması senaryosunda iyi sonuç verir. Ancak diğer senaryolarda tanımlama bilgileri, verileri kalıcı tutmanın ve iletmenin doğal bir yolu değildir.

Örneğin, Tek Sayfalı Uygulamalar (SPA'lar), yerel istemciler ve hatta diğer Web API'leri tarafından erişilebilen RESTful uç noktalarını kullanıma sunan bir ASP.NET Core Web API'sinde genellikle taşıyıcı belirteç kimlik doğrulaması kullanmak istersiniz. Bu tür uygulamalar tanımlama bilgileriyle çalışmaz, ancak taşıyıcı belirteci kolayca alabilir ve sonraki isteklerin yetkilendirme üst bilgisine ekleyebilir. belirteç kimlik doğrulamasını etkinleştirmek için ASP.NET Core, OAuth 2.0 ve OpenID Connect kullanmak için çeşitli seçenekleri destekler.

OpenID Connect veya OAuth 2.0 Kimlik sağlayıcısıyla kimlik doğrulaması

Kullanıcı bilgileri Azure Active Directory'de veya OpenID Connect veya OAuth 2.0'ı destekleyen başka bir kimlik çözümünde depolanıyorsa, OpenID Connect iş akışını kullanarak kimlik doğrulaması yapmak için Microsoft.AspNetCore.Authentication.OpenIdConnect paketini kullanabilirsiniz. Örneğin, bir ASP.NET Core web uygulaması, eShopOnContainers'daki Identity.Api mikro hizmeti için kimlik doğrulaması yapmak için, Program.cs'deki aşağıdaki basitleştirilmiş örnekte gösterildiği gibi bu paketten ara yazılımı kullanabilir:

// Program.cs

var identityUrl = builder.Configuration.GetValue<string>("IdentityUrl");
var callBackUrl = builder.Configuration.GetValue<string>("CallBackUrl");
var sessionCookieLifetime = builder.Configuration.GetValue("SessionCookieLifetimeMinutes", 60);

// Add Authentication services

services.AddAuthentication(options =>
{
    options.DefaultScheme = CookieAuthenticationDefaults.AuthenticationScheme;
    options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
})
.AddCookie(setup => setup.ExpireTimeSpan = TimeSpan.FromMinutes(sessionCookieLifetime))
.AddOpenIdConnect(options =>
{
    options.SignInScheme = CookieAuthenticationDefaults.AuthenticationScheme;
    options.Authority = identityUrl.ToString();
    options.SignedOutRedirectUri = callBackUrl.ToString();
    options.ClientId = useLoadTest ? "mvctest" : "mvc";
    options.ClientSecret = "secret";
    options.ResponseType = useLoadTest ? "code id_token token" : "code id_token";
    options.SaveTokens = true;
    options.GetClaimsFromUserInfoEndpoint = true;
    options.RequireHttpsMetadata = false;
    options.Scope.Add("openid");
    options.Scope.Add("profile");
    options.Scope.Add("orders");
    options.Scope.Add("basket");
    options.Scope.Add("marketing");
    options.Scope.Add("locations");
    options.Scope.Add("webshoppingagg");
    options.Scope.Add("orders.signalrhub");
});

// Build the app
//…
app.UseAuthentication();
//…
app.UseEndpoints(endpoints =>
{
    //...
});

Bu iş akışını kullandığınızda, tüm kullanıcı bilgileri depolama alanı ve kimlik doğrulaması Kimlik hizmeti tarafından işlendiğinden ASP.NET Core Identity ara yazılımı gerekmez.

ASP.NET Core hizmetinden güvenlik belirteçleri verme

Dış kimlik sağlayıcısı kullanmak yerine yerel ASP.NET Çekirdek Kimlik kullanıcıları için güvenlik belirteçleri vermek isterseniz, bazı iyi üçüncü taraf kitaplıklarından yararlanabilirsiniz.

IdentityServer4 ve OpenIddict , ASP.NET Core hizmetinden güvenlik belirteçleri vermenizi sağlamak için ASP.NET Core Identity ile kolayca tümleşen OpenID Connect sağlayıcılarıdır. IdentityServer4 belgelerinde kitaplığı kullanmaya yönelik ayrıntılı yönergeler bulunur. Ancak, belirteçleri vermek için IdentityServer4 kullanmanın temel adımları aşağıdaki gibidir.

  1. Program.cs'da IdentityServer4'u oluşturucuya çağrı yaparak yapılandırabilirsiniz. Services.AddIdentityServer.

  2. Uygulamanın HTTP isteği işleme işlem hattına IdentityServer4 eklemek için Program.cs dosyasında app.UseIdentityServer çağırırsınız. Bu, kitaplığın /connect/token gibi OpenID Connect ve OAuth2 uç noktalarına istek sunabilmesini sağlar.

  3. Kimlik sunucusunu yapılandırmak için aşağıdaki verileri ayarlarsınız:

    • İmzalama için kullanılacak kimlik bilgileri .

    • Kullanıcıların erişim isteyebileceği Kimlik ve API kaynakları :

      • API kaynakları, bir kullanıcının erişim belirteci ile erişebileceği korumalı verileri veya işlevleri temsil edebilir. API kaynağına örnek olarak yetkilendirme gerektiren bir web API'si (veya API kümesi) gösterilebilir.

      • Kimlik kaynakları, bir kullanıcıyı tanımlamak için bir istemciye verilen bilgileri (talepleri) temsil edebilir. Talepler kullanıcı adını, e-posta adresini vb. içerebilir.

    • Belirteç istemek için bağlanacak istemciler .

    • ASP.NET Core Identity veya alternatif gibi kullanıcı bilgileri için depolama mekanizması.

IdentityServer4 için kullanılacak istemcileri ve kaynakları belirttiğinizde, bellek içi istemci veya kaynak depolarıyla çalışan yöntemlere uygun türde bir IEnumerable<T> koleksiyonunu iletebilirsiniz. Daha karmaşık senaryolar için, Bağımlılık Ekleme aracılığıyla istemci veya kaynak sağlayıcısı türleri sağlayabilirsiniz.

IdentityServer4'in özel bir IClientStore türü tarafından sağlanan bellek içi kaynakları ve istemcileri kullanması için örnek bir yapılandırma aşağıdaki örneğe benzer olabilir:

// Program.cs

builder.Services.AddSingleton<IClientStore, CustomClientStore>();
builder.Services.AddIdentityServer()
    .AddSigningCredential("CN=sts")
    .AddInMemoryApiResources(MyApiResourceProvider.GetAllResources())
    .AddAspNetIdentity<ApplicationUser>();
//...

Güvenlik belirteçlerini kullanma

OpenID Connect uç noktasında kimlik doğrulaması veya kendi güvenlik belirteçlerinizi verme bazı senaryoları kapsar. Peki ya yalnızca farklı bir hizmet tarafından sağlanan geçerli güvenlik belirteçlerine sahip kullanıcılara erişimi sınırlaması gereken bir hizmet ne olacak?

Bu senaryo için JWT belirteçlerini işleyen kimlik doğrulama ara yazılımı Microsoft.AspNetCore.Authentication.JwtBearer paketinde kullanılabilir. JWT, "JSON Web Belirteci" anlamına gelir ve güvenlik taleplerini iletmek için ortak bir güvenlik belirteci biçimidir (RFC 7519 tarafından tanımlanır). Bu tür belirteçleri kullanmak için ara yazılımların nasıl kullanılacağına ilişkin basitleştirilmiş bir örnek, eShopOnContainers'ın Ordering.Api mikro hizmetinden alınan bu kod parçası gibi görünebilir.

// Program.cs

var identityUrl = builder.Configuration.GetValue<string>("IdentityUrl");

// Add Authentication services

builder.Services.AddAuthentication(options =>
{
    options.DefaultAuthenticateScheme = AspNetCore.Authentication.JwtBearer.JwtBearerDefaults.AuthenticationScheme;
    options.DefaultChallengeScheme = AspNetCore.Authentication.JwtBearer.JwtBearerDefaults.AuthenticationScheme;

}).AddJwtBearer(options =>
{
    options.Authority = identityUrl;
    options.RequireHttpsMetadata = false;
    options.Audience = "orders";
});

// Build the app

app.UseAuthentication();
//…
app.UseEndpoints(endpoints =>
{
    //...
});

Bu kullanımdaki parametreler şunlardır:

  • Audience gelen belirtecin alıcısını veya belirtecin erişim iznini veren kaynağı temsil eder. Bu parametrede belirtilen değer belirteçteki parametreyle eşleşmiyorsa belirteç reddedilir.

  • Authority, belirteç veren kimlik doğrulama sunucusunun adresidir. JWT taşıyıcı kimlik doğrulama ara yazılımı, belirtecin imzasını doğrulamak için kullanılabilecek ortak anahtarı almak için bu URI'yi kullanır. Ara yazılım, belirteçteki parametrenin iss bu URI ile eşleşdiğini de onaylar.

Başka bir parametre olan RequireHttpsMetadata, test amacıyla kullanışlıdır; sertifikanız olmayan ortamlarda test edebilmeniz için bu parametreyi false olarak ayarlarsınız. Gerçek dünya dağıtımlarında JWT taşıyıcı belirteçleri her zaman yalnızca HTTPS üzerinden geçirilmelidir.

Bu ara yazılım uygulandığında, JWT belirteçleri yetkilendirme üst bilgilerinden otomatik olarak ayıklanır. Daha sonra seri durumdan çıkarılır, Audience ve Authority parametrelerindeki değerler kullanılarak doğrulanır ve ardından MVC eylemleri veya yetkilendirme filtreleri tarafından ileri bir zamanda referans alınacak kullanıcı bilgileri olarak depolanır.

JWT taşıyıcı kimlik doğrulaması ara yazılımı, yetkili yoksa belirteci doğrulamak için yerel sertifika kullanma gibi daha gelişmiş senaryoları da destekleyebilir. Bu senaryo için TokenValidationParameters nesnesinde bir JwtBearerOptions nesne belirtebilirsiniz.

Ek kaynaklar