Çok kiracılı uygulamalar için arka uç Web API 'sinin güvenliğini sağlama

Örnek kod

Tailspin anketler uygulaması ANKETLERDEKI CRUD işlemlerini yönetmek için bir arka uç Web API 'si kullanır. Örneğin, bir Kullanıcı "Anketlerim" i tıklattığında Web uygulaması Web API 'sine bir HTTP isteği gönderir:

GET /users/{userId}/surveys

Web API 'si bir JSON nesnesi döndürür:

{
  "Published":[],
  "Own":[
    {"Id":1,"Title":"Survey 1"},
    {"Id":3,"Title":"Survey 3"},
    ],
  "Contribute": [{"Id":8,"Title":"My survey"}]
}

Web API 'SI anonim isteklere izin vermiyor, bu nedenle Web uygulamasının OAuth 2 taşıyıcı belirteçlerini kullanarak kendi kimliğini doğrulaması gerekir.

Not

Bu bir sunucudan sunucuya senaryosudur. Uygulama, tarayıcı istemcisinden API 'ye herhangi bir AJAX çağrısı yapmaz.

Gerçekleştirebileceğiniz iki ana yaklaşım vardır:

  • Temsilci Kullanıcı kimliği. Web uygulaması kullanıcının kimliğiyle kimlik doğrular.
  • Uygulama kimliği. Web uygulaması, OAuth 2 istemci kimlik bilgisi akışını kullanarak istemci KIMLIĞIYLE kimlik doğrular.

Tailspin uygulaması, temsilci kullanıcı kimliğini uygular. Başlıca farklar şunlardır:

Temsilci Kullanıcı kimliği:

  • Web API 'sine gönderilen taşıyıcı belirteci kullanıcı kimliğini içerir.
  • Web API 'SI, yetkilendirme kararlarını kullanıcı kimliğine göre yapar.
  • Kullanıcının bir eylem gerçekleştirme yetkisi yoksa Web uygulamasının, Web API 'sindeki 403 (yasak) hataları işlemesi gerekir.
  • Genellikle, Web uygulaması kullanıcı arabirimini etkileyen bazı yetkilendirme kararlarını hala kullanıcı ARABIRIMI öğelerini göstermek veya gizlemek gibi) sağlar.
  • Web API 'SI, JavaScript uygulaması veya yerel istemci uygulaması gibi güvenilmeyen istemciler tarafından kullanılabilir.

Uygulama kimliği:

  • Web API 'SI Kullanıcı hakkında bilgi almaz.
  • Web API 'SI Kullanıcı kimliğini temel alan herhangi bir yetkilendirme gerçekleştiremez. Tüm yetkilendirme kararları Web uygulaması tarafından yapılır.
  • Web API 'SI güvenilmeyen bir istemci (JavaScript veya yerel istemci uygulaması) tarafından kullanılamaz.
  • Bu yaklaşım, Web API 'sinde yetkilendirme mantığı olmadığından, uygulanması biraz daha kolay olabilir.

Her iki yaklaşımda Web uygulamasının, Web API 'sini çağırmak için gereken kimlik bilgisi olan bir erişim belirteci alması gerekir.

  • temsilci kullanıcı kimliği için, belirtecin kullanıcı adına belirteç verebilen Azure Active Directory gibi bir kimlik sağlayıcısından (ıdp) gelmesi gerekir.
  • İstemci kimlik bilgileri için, bir uygulama ıDP belirtecini alabilir veya kendi belirteç sunucusunu barındıralabilir. (Ancak sıfırdan bir belirteç sunucusu yazmayın; ıdentityserver4gibi iyi test edilmiş bir çerçeve kullanın) Azure AD ile kimlik doğrulaması yaparsanız, istemci kimlik bilgisi akışı ile birlikte Azure AD 'den erişim belirtecini almak kesinlikle önerilir.

Bu makalenin geri kalanında, uygulamanın Azure AD ile kimlik doğrulaması olduğu varsayılır.

Erişim belirteci alınıyor

Azure AD 'den bir erişim belirteci isteyen ve Web API 'sine belirteç Gönderen Web uygulamasını gösteren bir diyagram.

Web API 'sini Azure AD 'ye kaydetme

Azure AD 'nin Web API 'SI için bir taşıyıcı belirteci vermesi için Azure AD 'de bazı şeyleri yapılandırmanız gerekir.

  1. Web API 'sini Azure AD 'ye kaydedin.

  2. Web uygulamasının istemci KIMLIĞINI, özelliğindeki Web API uygulaması bildirimine ekleyin knownClientApplications . daha fazla bilgi için GitHub benioku dosyasına bakın.

  3. Web API 'sini çağırmak için Web uygulamasına izin verin. Azure portal, temsilci Kullanıcı kimliği için, uygulama kimliği (istemci kimlik bilgileri akışı) için "uygulama Izinleri" veya "temsilci Izinleri" olarak iki tür izin belirleyebilirsiniz.

    Temsilci izinleri

    Uygulama izinlerini ve temsilci izinleri gösteren Azure portal ekran görüntüsü.

Erişim belirteci alma

Web API 'SI çağrılmadan önce, Web uygulaması Azure AD 'den bir erişim belirteci alır. .NET uygulamasında .net Için Microsoft kimlik doğrulama kitaplığı 'nı (msal.net)kullanın. .EnableTokenAcquisitionToCallDownstreamApi()Uygulamanın Startup. cs ' ye ekleyin.

Bir belirteci aldıktan sonra, MSAL önbelleğe alır. Bu nedenle, MSAL 'ye dahil edilen bir belirteç önbelleği uygulamasını da seçmeniz gerekir. Bu örnek, dağıtılmış önbellek kullanır. Ayrıntılar için bkz. belirteç önbelleğe alma.

Web API 'sini çağırmak için erişim belirtecini kullanma

Belirteci aldıktan sonra bir aşağı akış Web API 'SI çağırın. Bu işlem, yardımcı sınıfıyla bir aşağı akış Web API 'Si çağırmabölümünde açıklanmaktadır.

Web API 'sinde kimlik doğrulama

Web API 'sinin taşıyıcı belirtecinin kimliğini doğrulaması gerekmez. ASP.NET Core, Microsoft. AspNet. Authentication. jwttaşıyıcı paketini kullanabilirsiniz. bu paket, uygulamanın openıd Bağlan taşıyıcı belirteçleri almasına olanak tanıyan ara yazılım sağlar.

Web API sınıfınıza ara yazılımı kaydedin Startup .

services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
    .AddMicrosoftIdentityWebApi(jtwOptions =>
        {
            jtwOptions.Events = new SurveysJwtBearerEvents(loggerFactory.CreateLogger<SurveysJwtBearerEvents>()); 
        },
        msIdentityOptions => {
            Configuration.GetSection("AzureAd").Bind(msIdentityOptions);
        });

Olaylar , Jwtyataerevents'ten türetilen bir sınıftır.

Verenin doğrulaması

Jwtyataerevents. Tokendoğrulanan olayında belirteç vereni doğrulayın. Veren, "ISS" talebinde gönderilir.

Anketler uygulamasında, Web API 'SI kiracı kaydolma'yı işlemez. Bu nedenle, yalnızca veren 'in zaten uygulama veritabanında olup olmadığını denetler. Aksi takdirde, kimlik doğrulamasının başarısız olmasına neden olan bir özel durum oluşturur.

public override async Task TokenValidated(TokenValidatedContext context)
{
    var principal = context.Ticket.Principal;
    var tenantManager = context.HttpContext.RequestServices.GetService<TenantManager>();
    var userManager = context.HttpContext.RequestServices.GetService<UserManager>();
    var issuerValue = principal.GetIssuerValue();
    var tenant = await tenantManager.FindByIssuerValueAsync(issuerValue);

    if (tenant == null)
    {
        // The caller was not from a trusted issuer. Throw to block the authentication flow.
        throw new SecurityTokenValidationException();
    }

    var identity = principal.Identities.First();

    // Add new claim for survey_userid
    var registeredUser = await userManager.FindByObjectIdentifier(principal.GetObjectIdentifierValue());
    identity.AddClaim(new Claim(SurveyClaimTypes.SurveyUserIdClaimType, registeredUser.Id.ToString()));
    identity.AddClaim(new Claim(SurveyClaimTypes.SurveyTenantIdClaimType, registeredUser.TenantId.ToString()));

    // Add new claim for Email
    var email = principal.FindFirst(ClaimTypes.Upn)?.Value;
    if (!string.IsNullOrWhiteSpace(email))
    {
        identity.AddClaim(new Claim(ClaimTypes.Email, email));
    }
}

Bu örnekte gösterildiği gibi, talepleri değiştirmek için simgede doğrulanan olayını da kullanabilirsiniz. Taleplerin doğrudan Azure AD 'den gelip gelmediğini unutmayın. Web uygulaması aldığı talepleri değiştirirse, bu değişiklikler Web API 'sinin aldığı taşıyıcı belirteçte gösterilmez. Daha fazla bilgi için bkz. talep dönüştürmeleri.

Yetkilendirme

Yetkilendirmeyle ilgili genel bir açıklama için bkz. rol tabanlı ve kaynak tabanlı yetkilendirme.

Jwttaşıyıcı ara yazılımı yetkilendirme yanıtlarını işler. Örneğin, bir denetleyici eylemini kimliği doğrulanmış kullanıcılarla kısıtlamak için, [Yetkilendir] özniteliğini kullanın ve kimlik doğrulama düzeni olarak Jwtyataerdefaults. AuthenticationScheme belirtin:

[Authorize(ActiveAuthenticationSchemes = JwtBearerDefaults.AuthenticationScheme)]

Bu, kullanıcının kimliği doğrulanmıyorsa 401 durum kodu döndürür.

Bir denetleyici eylemini yetkilendirme ilkesiyle kısıtlamak için, [Yetkilendir] özniteliğinde ilke adını belirtin:

[Authorize(Policy = PolicyNames.RequireSurveyCreator)]

Bu, kullanıcının kimliği doğrulanmadığında 401 durum kodu döndürür ve kullanıcının kimliği doğrulanmışsa ancak yetkilendirilmezse 403. İlkeyi başlangıca Kaydet:

public void ConfigureServices(IServiceCollection services)
{
    services.AddAuthorization(options =>
    {
        options.AddPolicy(PolicyNames.RequireSurveyCreator,
            policy =>
            {
                policy.AddRequirements(new SurveyCreatorRequirement());
                policy.RequireAuthenticatedUser(); // Adds DenyAnonymousAuthorizationRequirement
                policy.AddAuthenticationSchemes(JwtBearerDefaults.AuthenticationScheme);
            });
        options.AddPolicy(PolicyNames.RequireSurveyAdmin,
            policy =>
            {
                policy.AddRequirements(new SurveyAdminRequirement());
                policy.RequireAuthenticatedUser(); // Adds DenyAnonymousAuthorizationRequirement
                policy.AddAuthenticationSchemes(JwtBearerDefaults.AuthenticationScheme);
            });
    });

    // ...
}

Uygulama gizli dizilerini koruma

Gizli olan ve korunması gereken uygulama ayarlarının kullanılması yaygındır, örneğin:

  • Veritabanı bağlantı dizeleri
  • Parolalar
  • Şifreleme anahtarları

En iyi güvenlik uygulaması olarak, bu gizli dizileri kaynak denetiminde asla depolamamalısınız. Kaynak kod deponuz özel olsa bile, sızmaları çok kolay. Yalnızca genel kullanıma yönelik gizli dizileri tutmak değildir. Daha büyük projelerde, hangi geliştiricilerin ve işleçlerin üretim gizliliklerine erişebileceğini kısıtlamak isteyebilirsiniz. (test veya geliştirme ortamları için Ayarlar farklıdır.)

Daha güvenli bir seçenek, bu gizli dizileri Azure Key Vaultdepolamak için kullanılır. Key Vault, şifreleme anahtarlarını ve diğer gizli dizileri yönetmek için bulut tarafından barındırılan bir hizmettir. Bu makalede, uygulamanızın yapılandırma ayarlarını depolamak için Key Vault nasıl kullanılacağı gösterilmektedir.

Tailspin anketler uygulamasında, aşağıdaki ayarlar gizli:

  • Veritabanı bağlantı dizesi.
  • Redsıs bağlantı dizesi.
  • Web uygulaması için istemci parolası.

Anketler uygulaması yapılandırma ayarlarını aşağıdaki konumlardan yükler:

  • appsettings.json dosyası
  • Kullanıcı gizli dizileri deposu (yalnızca geliştirme ortamı; test için)
  • Barındırma ortamı (Azure web uygulamalarına uygulama ayarları)
  • Key Vault (etkinleştirildiğinde)

Bu ayarların her biri öncekini geçersiz kılar, bu nedenle Key Vault öncelik alır.

Not

Varsayılan olarak, Key Vault sağlayıcı devre dışı bırakılır. Uygulamayı yerel olarak çalıştırmaya gerek yoktur. Bunu bir üretim dağıtımında etkinleştirebilirsiniz.

Başlangıçta uygulama, kayıtlı her yapılandırma sağlayıcısının ayarlarını okur ve bunları türü kesin olarak kesin olarak kaydedilmiş seçenekler nesnesini doldurmak için kullanır. Daha fazla bilgi için bkz. Seçenekleri ve yapılandırma nesnelerini kullanma.

Sonraki