Aracılığıyla paylaş


ASP.NET Core'da OpenID Connect Web (UI) kimlik doğrulamasını yapılandırma

Tarafından Damien Bowden

Örnek kodu görüntüleme veya indirme

Bu makale aşağıdaki alanları kapsar:

  • OpenID Connect gizli etkileşimli istemcisi nedir?
  • ASP.NET Core'da OpenID Connect istemcisi oluşturma
  • Kod parçacıkları içeren OpenID Connect istemcisi örnekleri
  • Üçüncü taraf OpenID Connect sağlayıcı istemcilerini kullanma
  • Ön uç için arka uç (BFF) güvenlik mimarisi
  • OpenID Connect istemcisini genişleten gelişmiş özellikler, standartlar

Alternatif bir deneyim için, .NET için Microsoft Authentication Library, Microsoft Web ve Microsoft Entra ID'yi kullanarak, ASP.NET Core web uygulamasından Microsoft Graph API'sini çağırmayı içeren "Hızlı Başlangıç: Kullanıcıları oturum açma (Azure belgeleri)" belgesine bakın.

Bunun bir örneği olarak Microsoft Entra External ID OIDC sunucusunu kullanmak için, dış kiracıda bir ASP.NET Core web uygulaması örneği için kullanıcıları oturum açmaya yönlendirme konusuna ve Microsoft Web kullanarak Microsoft Entra Dış Kimliği ile kullanıcıları doğrulayan bir ASP.NET Core web uygulamasına bakın.

OpenID Connect gizli etkileşimli istemcisi nedir?

OpenID Connect , ASP.NET Core uygulamalarında kimlik doğrulaması uygulamak için kullanılabilir. Önerilen yol, kod akışını kullanarak bir OpenID Connect gizli istemcisi kullanmaktır. Bu uygulama için OAuth Genel İstemcileri (PKCE) tarafından Kod Takası İçin Kanıt Anahtarının kullanılması önerilir. Hem uygulama istemcisinin hem de uygulamanın kullanıcısının kimliği gizli akışta doğrulanır. Uygulama istemcisi kimlik doğrulaması için bir istemci sırrı veya istemci beyanı kullanır.

Genel OpenID Connect/OAuth istemcileri artık web uygulamaları için önerilmez.

Varsayılan akış aşağıdaki diyagramda gösterildiği gibi çalışır:

PKCE kullanan OIDC kod akışı gizli istemcisi

OpenID Connect birçok çeşitlemeyle gelir ve tüm sunucu uygulamalarının parametreleri ve gereksinimleri biraz farklıdır. Bazı sunucular kullanıcı bilgisi uç noktasını desteklemez, bazıları hala PKCE'yi desteklemez ve bazıları belirteç isteğinde özel parametreler gerektirir. İstemci onayları, istemci gizli anahtarları yerine kullanılabilir. Aşağı akış API'leri için FAPI, CIBA veya DPoP gibi OpenID Connect Core'un üzerine ek güvenlik ekleyen yeni standartlar da mevcuttur.

Not

.NET 9'dan, OpenID Connect sunucusu bunu destekliyorsa OAuth 2.0 Gönderilen Yetkilendirme İstekleri (PAR) RFC 9126 varsayılan olarak kullanılır. Bu, yukarıda gösterildiği gibi iki aşamalı bir akış değil, üç adımlı bir akıştır. (Kullanıcı Bilgileri isteği isteğe bağlı bir adımdır.)

Pages kullanarak Razor Open ID Connect kod akışı istemcisi oluşturma

Aşağıdaki bölümde, boş bir ASP.NET Core Razor sayfa projesinde OpenID Connect istemcisinin nasıl uygulandığı gösterilmektedir. Aynı mantık, yalnızca kullanıcı arabirimi tümleştirmesi farklı olan herhangi bir ASP.NET Core web projesine uygulanabilir.

OpenID Connect desteği ekleme

Microsoft.AspNetCore.Authentication.OpenIdConnect Nuget paketlerini ASP.NET Core projesine ekleyin.

OpenID Connect istemcisini ayarlama

Oluşturucu hizmetlerini (Program.cs dosyasındaki) kullanarak kimlik doğrulamayı web uygulamasına ekleyin. Yapılandırma OpenID Connect sunucusuna bağlıdır. Her OpenID Connect sunucusu kurulumda küçük farklılıklar gerektirir.

OpenID Connect işleyicisi, kimlik doğrulama talepleri ve oturum sonlandırma işlemleri için kullanılır. cookie, web uygulamasındaki oturumu işlemek için kullanılır. Kimlik doğrulaması için varsayılan şemalar gerektiği gibi belirtilebilir.

Daha fazla bilgi içinASP.NET Core kılavuzuna bakın.

builder.Services.AddAuthentication(options =>
{
    options.DefaultScheme = CookieAuthenticationDefaults.AuthenticationScheme;
    options.DefaultChallengeScheme = OpenIdConnectDefaults.AuthenticationScheme;
})
.AddCookie()
.AddOpenIdConnect(options =>
{
    var oidcConfig = builder.Configuration.GetSection("OpenIDConnectSettings");

    options.Authority = oidcConfig["Authority"];
    options.ClientId = oidcConfig["ClientId"];
    options.ClientSecret = oidcConfig["ClientSecret"];

    options.SignInScheme = CookieAuthenticationDefaults.AuthenticationScheme;
    options.ResponseType = OpenIdConnectResponseType.Code;

    options.SaveTokens = true;
    options.GetClaimsFromUserInfoEndpoint = true;

    options.MapInboundClaims = false;
    options.TokenValidationParameters.NameClaimType = JwtRegisteredClaimNames.Name;
    options.TokenValidationParameters.RoleClaimType = "roles";
});

Farklı OpenID Connect seçenekleriyle ilgili ayrıntılar için bkz. OpenID Connect (OIDC) ile ASP.NET Core güvenliğini sağlama.

Farklı talep eşleme olasılıkları için bkz. ASP.NET Core'da Eşleme, talepleri özelleştirme ve dönüştürme.

Not

Aşağıdaki ad alanları gereklidir:

using Microsoft.AspNetCore.Authentication.Cookies;
using Microsoft.AspNetCore.Authentication.OpenIdConnect;
using Microsoft.IdentityModel.Protocols.OpenIdConnect;
using Microsoft.IdentityModel.Tokens;

Yapılandırma özelliklerini ayarlama

Uygulama yapılandırma özelliklerine OpenID Connect istemci ayarlarını ekleyin. Ayarların OpenID Connect sunucusundaki istemci yapılandırmasıyla eşleşmesi gerekir. Uygulama ayarlarında, yanlışlıkla kaynak kod deposuna kaydedilebilecek gizli bilgiler saklanmamalıdır. Gizli diziler, üretim ortamlarında Azure Key Vault gibi güvenli bir konumda veya geliştirme ortamındaki kullanıcı gizli dizilerinde depolanmalıdır. Daha fazla bilgi için bkz . ASP.NET Core'da geliştirme aşamasında uygulama gizli dizilerinin güvenli bir şekilde depolanması.

"OpenIDConnectSettings": {
  // OpenID Connect URL. (The base URL for the /.well-known/openid-configuration)
  "Authority": "<Authority>",
  // client ID from the OpenID Connect server
  "ClientId": "<Client ID>",
  //"ClientSecret": "--stored-in-user-secrets-or-key-vault--"
},

Oturum kapatma geri çağırma rotası yapılandırması

SignedOutCallbackPath (yapılandırma anahtarı: "SignedOutCallbackPath"), uygulamanın OpenID Connect işleyicisi tarafından kesilen temel yolundaki talep yoludur ve burada kullanıcı aracısı, kimlik sağlayıcıdan çıkış yaptıktan sonra ilk kez döndürülür. "/signout-callback-oidc" varsayılan değeri kullanıldığından örnek uygulama yol için bir değer ayarlamaz. İsteği kestikten sonra, OpenID Connect işleyicisi (belirtilmişse) SignedOutRedirectUri veya RedirectUri'e yönlendirir.

Uygulamanın OIDC sağlayıcı kaydında oturum kapatma geri çağırma yolunu yapılandırın. Aşağıdaki örnekte, {PORT} yer tutucusu uygulamanın bağlantı noktasıdır:

https://localhost:{PORT}/signout-callback-oidc

Not

Microsoft Entra ID kullanırken, Web platform yapılandırmasında, Yönlendirme URI'si girişlerindeki yolu Entra veya Azure portalında ayarlayın. Entra kullanılırken localhost adresleri için bağlantı noktası gerekmez. Diğer OIDC sağlayıcılarının çoğu doğru bağlantı noktasını gerektirir. Oturumu kapatan geri çağırma yolu URI'sini Uygulamanın Entra'daki kaydına eklemezseniz, Entra kullanıcıyı uygulamaya geri yönlendirmeyi reddeder ve yalnızca tarayıcı penceresini kapatmasını ister.

Program sınıfında ASP.NET Core işlem hattı yöntemini güncelleştirin.

UseRouting yöntemi, UseAuthorization yönteminden önce uygulanmalıdır.

app.UseHttpsRedirection();
app.UseStaticFiles();

app.UseRouting();
app.UseAuthentication();
// Authorization is applied for middleware after the UseAuthorization method
app.UseAuthorization();
app.MapRazorPages();

Zorunlu yetkilendirme

korumalı [Authorize] sayfalarına ekleyin:

[Authorize]

Uygulamanın tamamı için yetkilendirmeyi zorlamak ve güvenli olmayan sayfaları geri çevirmek daha iyi bir yaklaşımdır:

var requireAuthPolicy = new AuthorizationPolicyBuilder()
    .RequireAuthenticatedUser()
    .Build();

builder.Services.AddAuthorizationBuilder()
    .SetFallbackPolicy(requireAuthPolicy);

Genel uç noktalara [AllowAnonymous] özniteliğini uygulayarak yetkilendirmeden vazgeçin. Örnekler için Projeye yeni Logout.cshtml ve SignedOut.cshtmlRazor sayfalar ekleme ve Login sayfasını uygulama bölümlerine bakın.

Projeye yeni Logout.cshtml ve SignedOut.cshtmlRazor sayfaları ekleme

Hem cookie oturumunu hem de OpenID Connect oturumunu kapatmak için bir oturum kapatma gereklidir. Tüm uygulamanın oturumu kapatmak için OpenID Connect sunucusuna yönlendirilmesi gerekiyor. Oturum başarıyla kapatıldıktan sonra uygulama RedirectUri yolunu açar.

Varsayılan bir oturum kapatma sayfası uygulayın ve Logout razor sayfa kodunu aşağıdaki şekilde değiştirin:

[Authorize]
public class LogoutModel : PageModel
{
    public IActionResult OnGetAsync()
    {
        return SignOut(new AuthenticationProperties
        {
            RedirectUri = "/SignedOut"
        },
        // Clear auth cookie
        CookieAuthenticationDefaults.AuthenticationScheme,
        // Redirect to OIDC provider signout endpoint
        OpenIdConnectDefaults.AuthenticationScheme);
    }
}

SignedOut.cshtml için [AllowAnonymous] özniteliğigerekir:

[AllowAnonymous]
public class SignedOutModel : PageModel
{
    public void OnGet()
    {
    }
}

Login sayfasını uygula

Bir LoginRazor sayfası, gerekli ChallengeAsyncile AuthProperties'yi doğrudan çağırmak için de uygulanabilir. Web uygulaması kimlik doğrulaması gerektiriyorsa ve varsayılan sınama kullanılıyorsa bu gerekli değildir.

Login.cshtml sayfası için [AllowAnonymous] özniteliğigerekir:

using Microsoft.AspNetCore.Authentication;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;

namespace RazorPageOidc.Pages;

[AllowAnonymous]
public class LoginModel : PageModel
{
    [BindProperty(SupportsGet = true)]
    public string? ReturnUrl { get; set; }

    public async Task OnGetAsync()
    {
        var properties = GetAuthProperties(ReturnUrl);
        await HttpContext.ChallengeAsync(properties);
    }

    private static AuthenticationProperties GetAuthProperties(string? returnUrl)
    {
        const string pathBase = "/";

        // Prevent open redirects.
        if (string.IsNullOrEmpty(returnUrl))
        {
            returnUrl = pathBase;
        }
        else if (!Uri.IsWellFormedUriString(returnUrl, UriKind.Relative))
        {
            returnUrl = new Uri(returnUrl, UriKind.Absolute).PathAndQuery;
        }
        else if (returnUrl[0] != '/')
        {
            returnUrl = $"{pathBase}{returnUrl}";
        }

        return new AuthenticationProperties { RedirectUri = returnUrl };
    }
}

Kullanıcı için oturum açma ve kapama düğmesi ekle

@if (Context.User.Identity!.IsAuthenticated)
{
	<li class="nav-item">
		<a class="nav-link text-dark" asp-area="" asp-page="/Logout">Logout</a>
	</li>

	<span class="nav-link text-dark">Hi @Context.User.Identity.Name</span>
}
else
{
	<li class="nav-item">
		<a class="nav-link text-dark" asp-area="" asp-page="/Index">Login</a>
	</li>
}

Kod parçacıklarıyla örnekler

Kullanıcı Bilgileri uç noktasını kullanma örneği

OpenID Connect seçenekleri, talepleri eşlemek, işleyicileri uygulamak veya belirteçleri daha sonra kullanmak üzere oturuma kaydetmek için kullanılabilir.

Scope seçeneği, OpenID Connect sunucusuna bilgi olarak gönderilen farklı talepler veya yenileme belirteci istemek için kullanılabilir. offline_access istemek, sunucudan uygulamanın kullanıcısının kimliğini yeniden doğrulamadan oturumu yenilemek için kullanılabilecek bir başvuru belirteci döndürmesini istiyor.

services.AddAuthentication(options =>
{
    options.DefaultScheme = CookieAuthenticationDefaults.AuthenticationScheme;
    options.DefaultChallengeScheme = OpenIdConnectDefaults.AuthenticationScheme;
})
.AddCookie()
.AddOpenIdConnect(OpenIdConnectDefaults.AuthenticationScheme, options =>
{
    var oidcConfig = builder.Configuration.GetSection("OpenIDConnectSettings");
    options.Authority = oidcConfig["IdentityProviderUrl"];
    options.ClientSecret = oidcConfig["ClientSecret"];
    options.ClientId = oidcConfig["Audience"];
    options.ResponseType = OpenIdConnectResponseType.Code;

    options.Scope.Clear();
    options.Scope.Add("openid");
    options.Scope.Add("profile");
    options.Scope.Add("email");
    options.Scope.Add("offline_access");

    options.ClaimActions.Remove("amr");
    options.ClaimActions.MapUniqueJsonKey("website", "website");

    options.GetClaimsFromUserInfoEndpoint = true;
    options.SaveTokens = true;

    // .NET 9 feature
    options.PushedAuthorizationBehavior = PushedAuthorizationBehavior.Require;

    options.TokenValidationParameters.NameClaimType = "name";
    options.TokenValidationParameters.RoleClaimType = "role";
});

Microsoft kimlik sağlayıcılarını uygulama

Microsoft'un birden çok kimlik sağlayıcısı ve OpenID Connect uygulaması vardır. Microsoft'un farklı OpenID Connect sunucuları vardır:

  • Microsoft Entra Kimlik
  • Microsoft Entra Dış Kimlik
  • Azure AD B2C

ASP.NET Core'daki Microsoft kimlik sağlayıcılarından birini kullanarak kimlik doğrulaması yaparsanız, Microsoft.Identity.Web Nuget paketlerinin kullanılması önerilir.

Microsoft.Identity.Web Nuget paketleri, ASP.NET Core OpenID Connect istemcisi üzerinde yerleşik olarak bulunan ve varsayılan istemcide bazı değişiklikler yapılan microsofta özgü bir istemcidir.

Üçüncü taraf OpenID Connect sağlayıcı istemcilerini kullanma

Birçok OpenID Connect sunucu uygulaması, aynı OpenID Connect uygulaması için iyileştirilmiş Nuget paketleri oluşturur. Bu paketler, belirli OpenID Connect sunucusunun gerektirdiği ek özellikleri içeren OpenID Connect istemci özelliklerini uygular. Microsoft.Identity.Web bunun bir örneğidir.

Tek bir uygulamada farklı OpenID Connect sunucularından birden çok OpenID Connect istemcisi uyguluyorsanız, farklı istemciler diğer istemcileri etkileyen bazı seçeneklerin üzerine yazarken varsayılan ASP.NET Core uygulamasına geri dönmek normalde daha iyidir.

OpenIddict Web sağlayıcıları , birçok farklı sunucu uygulamasını destekleyen bir istemci uygulamasıdır.

IdentityModel, talep tabanlı kimlik, OAuth 2.0 ve OpenID Connect için bir .NET standart yardımcı kitaplığıdır. Bu, istemci uygulamasına yardımcı olmak için de kullanılabilir.

Ön uç için arka uç (BFF) güvenlik mimarisi

Artık herhangi bir web uygulaması için OpenID Connect genel istemcilerinin uygulanması önerilmez.

Daha fazla bilgi için bkz. Browser-Based Uygulamalarıiçin OAuth 2.0 taslağı .

Bağımsız arka ucu olmayan web uygulamalarını hayata geçiriyorsanız, Ön Uç için Arka Uç (BFF) deseni güvenlik mimarisini kullanmanızı öneririz. Bu düzen farklı şekillerde uygulanabilir, ancak kimlik doğrulaması her zaman arka uçta uygulanır ve daha fazla yetkilendirme veya kimlik doğrulaması akışları için web istemcisine hassas veri gönderilmez.

Gelişmiş özellikler, standartlar, OIDC istemcisini genişletme

Kayıt Alma İşlemi

OpenID Connect istemcilerinin hatalarını ayıklamak zor olabilir. Kişisel bilgiler (PII) verileri varsayılan olarak günlüğe kaydedilmez. Geliştirme modunda hata ayıklama yapılıyorsa, hassas kişisel verileri günlüğe kaydetmek için IdentityModelEventSource.ShowPII kullanılabilir. IdentityModelEventSource.ShowPII içeren bir uygulamayı üretken sunuculara dağıtmayın.

//using ...

using Microsoft.IdentityModel.Logging;

var builder = WebApplication.CreateBuilder(args);

//... code 

var app = builder.Build();

IdentityModelEventSource.ShowPII = true;

//... code 

app.Run();

Daha fazla bilgi için bkz. Logging.

Not

Tüm gerekli günlükleri görebilmek için yapılandırılmış günlük düzeyini düşürmek isteyebilirsiniz.

OIDC ve OAuth Parametre Özelleştirmesi

OAuth ve OIDC kimlik doğrulama işleyicileri (AdditionalAuthorizationParameters) seçeneği, genellikle yeniden yönlendirme sorgu dizesinin parçası olarak eklenen yetkilendirme iletisi parametrelerinin özelleştirilmesine olanak tanır.

OpenID Connect'ten talepleri eşleme

Daha fazla bilgi için bkz. ASP.NET Core'de talepleri eşleme, özelleştirme ve dönüştürme.

Blazor OpenID Connect

Daha fazla bilgi için bkz. OpenID Connect (OIDC)ile ASP.NET Core güvenliğini sağlama .

Standartlar