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.
Not
Bu, bu makalenin en son sürümü değildir. Geçerli sürüm için bu makalenin .NET 10 sürümüne bakın.
Uyarı
ASP.NET Core'un bu sürümü artık desteklenmiyor. Daha fazla bilgi için bkz. .NET ve .NET Core Destek İlkesi. Geçerli sürüm için bu makalenin .NET 10 sürümüne bakın.
Tarafından Damien Bowden
Çok faktörlü kimlik doğrulaması (MFA), kullanıcının oturum açma sırasında daha fazla tanımlama biçimi için istendiği bir işlemdir. İstem, kullanıcıdan bir cep telefonundan kod girmesini, FIDO2 anahtarı kullanmasını veya parmak izi taraması sağlamasını isteyebilir. İkinci bir kimlik doğrulama biçimine ihtiyacınız olduğunda güvenlik iyileştirilmiştir. Ek faktör bir siber saldırı aracı tarafından kolayca elde edilemez veya çoğaltılmaz.
Bu makalede, ASP.NET Core'da çok faktörlü kimlik doğrulamasına genel bir bakış ve aşağıdakilerin nasıl yapıldığını gösteren örneklerle birlikte önerilen kimlik doğrulama akışları sağlanır:
- ASP.NET Core Identity kullanarak yönetim sayfaları için MFA'yi yapılandırın.
- OpenID Connect sunucusuna bir MFA oturum açma gereksinimi gönderin.
- ASP.NET Core OpenID Connect istemcisini MFA gerektirmeye zorlar.
Örnek kodu görüntüleyin veya indirin (nasıl indirilir).
MFA ile 2FA karşılaştırması
MFA, kimlik için en az iki veya daha fazla türde kanıt gerektirir. Kanıt türleri bildiğiniz bir şey, sahip olduğunuz bir şey veya kullanıcının kimlik doğrulaması için biyometrik doğrulama olabilir.
İki öğeli kimlik doğrulaması (2FA), MFA'nın bir alt kümesi gibidir. 2FA tam olarak iki tür kanıt gerektirirken, MFA kimliği kanıtlamak için iki veya daha fazla faktör gerektirebilir.
2FA, ASP.NET Core Identitykullanılırken varsayılan olarak desteklenir. Belirli bir kullanıcı için 2FA'yı etkinleştirmek veya devre dışı bırakmak için özelliğini ayarlayın IdentityUser<TKey>.TwoFactorEnabled . ASP.NET Temel Identity Varsayılan kullanıcı arabirimi, 2FA'nın yapılandırılması için sayfalar içerir.
MFA TOTP (Zamana Dayalı Tek Seferlik Parola Algoritması)
TOTP ile MFA, ASP.NET Core Identity kullanılırken varsayılan olarak desteklenir. Bu yaklaşım, aşağıdakiler dahil olmak üzere tüm uyumlu kimlik doğrulayıcı uygulamalarıyla birlikte kullanılabilir:
- Microsoft Authenticator
- Google Kimlik Doğrulayıcı
Uygulama ayrıntıları için bkz . ASP.NET Core'da TOTP kimlik doğrulayıcı uygulamaları için QR Kodu oluşturmayı etkinleştirme.
MFA TOTP desteğini devre dışı bırakmak için, kimlik doğrulamayı AddIdentity yöntemi yerine AddDefaultIdentity yöntemini kullanarak yapılandırın.
AddDefaultIdentity yöntemi, MFA TOTP için olan da dahil olmak üzere birden çok belirteç sağlayıcısını kaydeden AddDefaultTokenProviders yöntemini dahili olarak çağırır. Yalnızca belirli belirteç sağlayıcılarını kaydetmek için gereken her sağlayıcı adına AddTokenProvider yöntemini çağırın. Kullanılabilir belirteç sağlayıcıları hakkında daha fazla bilgi için GitHub deposundaki dotnet/aspnetcore bakın.
Not
.NET başvuru kaynağına yönelik belge bağlantıları genellikle deponun varsayılan dalını yükler ve bu dal .NET'in sonraki sürümü için geçerli geliştirmeyi temsil eder. Belirli bir sürüm için bir etiket seçmek için Dallar ve etiketler arasında geçiş yap açılan listesini kullanın. Daha fazla bilgi için bkz. ASP.NET Core kaynak kodunun sürüm etiketini seçme (dotnet/AspNetCore.Docs #26205).
MFA geçiş anahtarları/FIDO2 veya parolasız
Passkeys/FIDO2 yaklaşımı şu anda:
- MFA'ya ulaşmanın en güvenli yolu.
- Kimlik avı saldırılarına karşı koruma sunan MFA (ayrıca sertifika kimlik doğrulaması ve Windows for Business).
ASP.NET Core, ASP.NET Core Identity kullanarak geçiş tuşlarını destekler. Geçiş anahtarları/FIDO2, MFA veya parolasız akışlar için kullanılabilir. Daha fazla bilgi için bkz . Web Kimlik Doğrulaması API'sini (WebAuthn) etkinleştirme geçiş anahtarları.
Microsoft Entra ID, geçiş anahtarları/FIDO2 ve parolasız akışlar için destek sağlar. Daha fazla bilgi için bkz. Authentication methods in Microsoft Entra ID - passkeys (FIDO2).
Parolasız MFA'nın diğer biçimleri kimlik avına karşı koruma sağlamaz veya korumayabilir.
Dışişleri Bakanlığı SMS Gönderimi
SMS ile MFA, parola kimlik doğrulaması (tek faktör) ile karşılaştırıldığında güvenliği büyük ölçüde artırır. Ancak SMS'in ikinci bir faktör olarak kullanılması artık önerilmez. Bu tür bir uygulama için çok fazla bilinen saldırı vektörleri var.
Daha fazla bilgi için bkz . NIST Dijital Identity Yönergeleri (Özel Yayın 800-63B).
ASP.NET Core Identity ile yönetim sayfaları için MFA'yi yapılandırma
Kullanıcılardaki MFA'yı bir ASP.NET Core Identity uygulamasındaki hassas sayfalara erişimi etkinleştirmeye zorlayabilirsiniz. Bu yaklaşım, farklı kimlikler için farklı erişim düzeylerinin bulunduğu uygulamalar için yararlı olabilir. Örneğin, kullanıcılar bir parola oturum açma işlemi kullanarak profil verilerini görüntüleyebilir, ancak yöneticinin yönetim sayfalarına erişmek için MFA kullanması gerekir.
MFA talebiyle oturum açma işlemini genişletme
Örnek kod yapılandırması, Identity ve Razor Pages ile ASP.NET Core kullanır.
AddIdentity yöntemi yerine AddDefaultIdentitykullanılır, bu nedenle başarıyla oturum açıldıktan sonra kimliğe talep eklemek için bir IUserClaimsPrincipalFactory uygulama kullanılabilir.
Uyarı
Bu makalede bağlantı dizesi kullanımı gösterilmektedir. Geliştirme ve test için yerel veritabanı kullanıldığında, bağlantı dizesi aracılığıyla veritabanı kullanıcı kimlik doğrulaması gerekmez. Üretim ortamlarında, bağlantı dizeleri bazen veritabanı erişiminin veya veritabanı işlemlerinin kimliğini doğrulamak için bir parola içerir. Bir bağlantı dizesindeki kaynak sahibi parola kimlik bilgisi (ROPC), üretim uygulamalarında kaçınılması gereken bir güvenlik riskidir. Üretim uygulamaları kullanılabilir en güvenli kimlik doğrulama akışını kullanmalıdır. Test veya üretim ortamlarına dağıtılan uygulamalar için kimlik doğrulaması hakkında daha fazla bilgi için ASP.NET Temel güvenlik konularına bakın.
builder.Services.AddDbContext<ApplicationDbContext>(options =>
options.UseSqlite(
Configuration.GetConnectionString("DefaultConnection")));
builder.Services.AddIdentity<IdentityUser, IdentityRole>(options =>
options.SignIn.RequireConfirmedAccount = false)
.AddEntityFrameworkStores<ApplicationDbContext>()
.AddDefaultTokenProviders();
builder.Services.AddSingleton<IEmailSender, EmailSender>();
builder.Services.AddScoped<IUserClaimsPrincipalFactory<IdentityUser>,
AdditionalUserClaimsPrincipalFactory>();
builder.Services.AddAuthorization(options =>
options.AddPolicy("TwoFactorEnabled", x => x.RequireClaim("amr", "mfa")));
builder.Services.AddRazorPages();
AdditionalUserClaimsPrincipalFactory sınıfı, amr claim’ini (Authentication Methods References claim) yalnızca başarılı bir oturum açmanın ardından kullanıcı claim’lerine ekler. Talep değeri veritabanından okunur. Talep buraya eklenir çünkü kullanıcının yalnızca kimlik MFA ile oturum açmışsa daha yüksek korumalı görünüme erişmesi gerekir. Veritabanı görünümü talebi kullanmak yerine doğrudan veritabanından okunursa, MFA etkinleştirildikten sonra doğrudan MFA olmadan görünüme erişmek mümkündür.
using Microsoft.AspNetCore.Identity;
using Microsoft.Extensions.Options;
using System.Collections.Generic;
using System.Security.Claims;
using System.Threading.Tasks;
namespace IdentityStandaloneMfa
{
public class AdditionalUserClaimsPrincipalFactory :
UserClaimsPrincipalFactory<IdentityUser, IdentityRole>
{
public AdditionalUserClaimsPrincipalFactory(
UserManager<IdentityUser> userManager,
RoleManager<IdentityRole> roleManager,
IOptions<IdentityOptions> optionsAccessor)
: base(userManager, roleManager, optionsAccessor)
{
}
public async override Task<ClaimsPrincipal> CreateAsync(IdentityUser user)
{
var principal = await base.CreateAsync(user);
var identity = (ClaimsIdentity)principal.Identity;
var claims = new List<Claim>();
if (user.TwoFactorEnabled)
{
claims.Add(new Claim("amr", "mfa"));
}
else
{
claims.Add(new Claim("amr", "pwd"));
}
identity.AddClaims(claims);
return principal;
}
}
}
Startup sınıfında Identity hizmet yapılandırması değiştiğinden, Identity düzenlerinin güncellenmesi gerekir:
Uygulamaya Identity sayfalarını iskeleye ekleyin.
IdentityDüzeni /Account/Manage/_Layout.cshtml dosyasında tanımlayın.
@{ Layout = "/Pages/Shared/_Layout.cshtml"; }Ayrıca, tüm yönetim sayfaları için Identity sayfalarındaki düzeni atayın:
@{ Layout = "_Layout.cshtml"; }
Yönetim sayfasında MFA gereksinimini doğrulama
Yönetim Razor Sayfası, kullanıcının MFA aracılığıyla oturum açtığını doğrular.
OnGet yönteminde kimlik, kullanıcı taleplerine erişmek için kullanılır. Talep amr değeri mfa için denetlendi. Kimlik bu iddiayı içermiyorsa veya kimlik falseise, sayfa Çok Faktörlü Kimlik Doğrulamayı Etkinleştir sayfasına yönlendirilir. Kullanıcı zaten oturum açtığından ancak MFA olmadan bu eylem mümkündür.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;
namespace IdentityStandaloneMfa
{
public class AdminModel : PageModel
{
public IActionResult OnGet()
{
var claimTwoFactorEnabled =
User.Claims.FirstOrDefault(t => t.Type == "amr");
if (claimTwoFactorEnabled != null &&
"mfa".Equals(claimTwoFactorEnabled.Value))
{
// You logged in with MFA, do the administrative stuff
}
else
{
return Redirect(
"/Identity/Account/Manage/TwoFactorAuthentication");
}
return Page();
}
}
}
Kullanıcı oturum açma bilgilerini değiştirmek için kullanıcı arabirimi mantığı
Başlangıçta bir yetkilendirme ilkesi eklendi. İlke, değeri mfa olan amr talebini gerektirir:
services.AddAuthorization(options =>
options.AddPolicy("TwoFactorEnabled",
x => x.RequireClaim("amr", "mfa")));
Bu ilke daha sonra görünümde _Layoutyönetici menüsünü şu uyarıyla göstermek veya gizlemek için kullanılabilir:
@using Microsoft.AspNetCore.Authorization
@using Microsoft.AspNetCore.Identity
@inject SignInManager<IdentityUser> SignInManager
@inject UserManager<IdentityUser> UserManager
@inject IAuthorizationService AuthorizationService
Kimlik doğrulaması MFA ile yapıldıysa, Yönetici menüsü bilgi ipucu uyarısı olmadan görüntülenir.
Kullanıcı MFA olmadan oturum açtığında Yönetici (Etkin Değil) menüsü, kullanıcıyı bilgilendiren araç ipucuyla birlikte görüntülenir (uyarıyı açıklar).
@if (SignInManager.IsSignedIn(User))
{
@if ((AuthorizationService.AuthorizeAsync(User, "TwoFactorEnabled")).Result.Succeeded)
{
<li class="nav-item">
<a class="nav-link text-dark" asp-area="" asp-page="/Admin">Admin</a>
</li>
}
else
{
<li class="nav-item">
<a class="nav-link text-dark" asp-area="" asp-page="/Admin"
id="tooltip-demo"
data-toggle="tooltip"
data-placement="bottom"
title="MFA is NOT enabled. This is required for the Admin Page. If you have activated MFA, then logout, login again.">
Admin (Not Enabled)
</a>
</li>
}
}
Kullanıcı MFA olmadan oturum açarsa , Yönetici seçeneği (Etkin Değil) uyarısını gösterir:
Kullanıcı Yönetici seçeneğini seçtiğinde, MFA'yı etkinleştirebileceği bir görünüme yönlendirilir:
OpenID Connect sunucusuna MFA oturum açma gereksinimi gönderme
parametresi, acr_values bir kimlik doğrulama isteğinde mfa istemciden sunucuya gerekli değeri geçirmek için kullanılabilir.
Not
Bu acr_values yaklaşımın çalışması için parametresinin OpenID Connect sunucusunda işlenmesi gerekir.
OpenID Connect ASP.NET Core istemcisi
ASP.NET Core Razor Pages OpenID Connect istemci uygulaması, OpenID Connect sunucusunda oturum açmak için AddOpenIdConnect yöntemini kullanır.
acr_values değeriyle ayarlanan mfa parametresi, kimlik doğrulama isteğiyle gönderilir.
OpenIdConnectEvents bu değeri eklemek için kullanılır.
Önerilen acr_values parametre değerleri için bkz. IETF Kimlik Doğrulama Yöntemi Başvuru Değerleri belirtimi.
build.Services.AddAuthentication(options =>
{
options.DefaultScheme =
CookieAuthenticationDefaults.AuthenticationScheme;
options.DefaultChallengeScheme =
OpenIdConnectDefaults.AuthenticationScheme;
})
.AddCookie()
.AddOpenIdConnect(options =>
{
options.SignInScheme =
CookieAuthenticationDefaults.AuthenticationScheme;
options.Authority = "<OpenID Connect server URL>";
options.RequireHttpsMetadata = true;
options.ClientId = "<OpenID Connect client ID>";
options.ClientSecret = "<>";
options.ResponseType = "code";
options.UsePkce = true;
options.Scope.Add("profile");
options.Scope.Add("offline_access");
options.SaveTokens = true;
options.AdditionalAuthorizationParameters.Add("acr_values", "mfa");
});
Örnek: OpenID Connect Duende IdentityServer sunucusu
Aşağıdaki örnekte, ASP.NET Core Identity ile OpenID Connect Duende IdentityServer sunucusu gösterilmektedir.
Identity Pages ile ASP.NET Core Razor kullanılarak uygulanan OpenID Connect sunucusunda, ErrorEnable2FA.cshtml adlı yeni bir sayfa oluşturulur.
Sayfa görünümü:
- Identity, MFA gerektiren bir uygulamadan kaynaklanıyorsa ancak kullanıcı Identity içinde MFA'yı etkinleştirmemişse görüntülenir.
- Kullanıcıyı bilgilendirip bunu etkinleştirmek için bir bağlantı ekler.
@{
ViewData["Title"] = "ErrorEnable2FA";
}
<h1>The client application requires you to have MFA enabled. Enable this, try login again.</h1>
<br />
You can enable MFA to login here:
<br />
<a href="~/Identity/Account/Manage/TwoFactorAuthentication">Enable MFA</a>
yönteminde LoginIIdentityServerInteractionService , arabirim uygulaması _interaction OpenID Connect istek parametrelerine erişmek için kullanılır.
acr_values parametresine AcrValues özelliği kullanılarak erişilir. İstemci bunu mfa ayarlı olarak gönderdiğinden, bu daha sonra kontrol edilebilir.
MFA gerekliyse ve ASP.NET Core Identity içindeki kullanıcı MFA ile etkinleştirilirse, oturum açma işlemi devam eder. Kullanıcının MFA'sı etkin olmadığında, kullanıcı özel görünümüne ErrorEnable2FA.cshtmlyönlendirilir. Ardından ASP.NET Core Identity kullanıcının oturumunu açar.
Fido2Store, kullanıcının özel bir FIDO2 Belirteç Sağlayıcısı kullanarak MFA'yi etkinleştirip etkinleştirmediğini denetlemek için kullanılır.
public async Task<IActionResult> OnPost()
{
// check if we are in the context of an authorization request
var context = await _interaction.GetAuthorizationContextAsync(Input.ReturnUrl);
var requires2Fa = context?.AcrValues.Count(t => t.Contains("mfa")) >= 1;
var user = await _userManager.FindByNameAsync(Input.Username);
if (user != null && !user.TwoFactorEnabled && requires2Fa)
{
return RedirectToPage("/Home/ErrorEnable2FA/Index");
}
// code omitted for brevity
if (ModelState.IsValid)
{
var result = await _signInManager.PasswordSignInAsync(Input.Username, Input.Password, Input.RememberLogin, lockoutOnFailure: true);
if (result.Succeeded)
{
// code omitted for brevity
}
if (result.RequiresTwoFactor)
{
var fido2ItemExistsForUser = await _fido2Store.GetCredentialsByUserNameAsync(user.UserName);
if (fido2ItemExistsForUser.Count > 0)
{
return RedirectToPage("/Account/LoginFido2Mfa", new { area = "Identity", Input.ReturnUrl, Input.RememberLogin });
}
return RedirectToPage("/Account/LoginWith2fa", new { area = "Identity", Input.ReturnUrl, RememberMe = Input.RememberLogin });
}
await _events.RaiseAsync(new UserLoginFailureEvent(Input.Username, "invalid credentials", clientId: context?.Client.ClientId));
ModelState.AddModelError(string.Empty, LoginOptions.InvalidCredentialsErrorMessage);
}
// something went wrong, show form with error
await BuildModelAsync(Input.ReturnUrl);
return Page();
}
Kullanıcı zaten oturum açmışsa istemci uygulaması:
Yine de talebi doğrular
amr.MFA, ASP.NET Core Identity görünümündeki Enable MFA gibi bir bağlantıyla ayarlanabilir:
ASP.NET Core OpenID Connect istemcisini MFA gerektirmeye zorlama
Bu örnekte, oturum açmak için OpenID Connect kullanan bir ASP.NET Core Razor Sayfası uygulamasının kullanıcıların MFA kullanılarak kimlik doğrulaması yapılmasını nasıl gerektirebileceği gösterilmektedir.
MFA gereksinimini doğrulamak için bir IAuthorizationRequirement gereksinim oluşturulur. Gereksinim, MFA gerektiren bir ilke kullanılarak sayfalara eklenir.
using Microsoft.AspNetCore.Authorization;
namespace AspNetCoreRequireMfaOidc;
public class RequireMfa : IAuthorizationRequirement{}
Bir AuthorizationHandler, amr talebini kullanmak ve değerin mfa olup olmadığını denetlemek için uygulanır.
amr başarılı bir kimlik doğrulamasında id_token döndürülür ve IETF Kimlik Doğrulama Yöntemi Başvuru Değerleri belirtiminde tanımlandığı gibi birçok farklı değere sahip olabilir.
Döndürülen değer, kimliğin nasıl doğrulandığına ve OpenID Connect sunucu uygulamasına bağlıdır.
AuthorizationHandler
RequireMfa gereksinimini kullanır ve amr talebini doğrular. OpenID Connect sunucusu Duende Identity Server ile ASP.NET Core Identity kullanılarak uygulanabilir. Bir kullanıcı TOTP kullanarak oturum açtığında, amr talep bir MFA değeriyle döndürülür. Farklı bir OpenID Connect sunucu uygulaması veya farklı bir MFA türü kullanıyorsanız, amr talep farklı bir değere sahip olabilir. Kodun diğer olası değerleri kabul etmek için genişletilmesi gerekir.
public class RequireMfaHandler : AuthorizationHandler<RequireMfa>
{
protected override Task HandleRequirementAsync(
AuthorizationHandlerContext context,
RequireMfa requirement)
{
if (context == null)
throw new ArgumentNullException(nameof(context));
if (requirement == null)
throw new ArgumentNullException(nameof(requirement));
var amrClaim =
context.User.Claims.FirstOrDefault(t => t.Type == "amr");
if (amrClaim != null && amrClaim.Value == Amr.Mfa)
{
context.Succeed(requirement);
}
return Task.CompletedTask;
}
}
Program dosyasında, AddOpenIdConnect yöntemi varsayılan sınama şeması olarak kullanılır.
amr talebini kontrol etmek için kullanılan yetkilendirme işleyicisi, Kontrolün Tersine Çevrilmesi kapsayıcısına eklenir. Ardından RequireMfa gereksinimini ekleyen bir politika oluşturulur.
builder.Services.ConfigureApplicationCookie(options =>
options.Cookie.SecurePolicy =
CookieSecurePolicy.Always);
builder.Services.AddSingleton<IAuthorizationHandler, RequireMfaHandler>();
builder.Services.AddAuthentication(options =>
{
options.DefaultScheme =
CookieAuthenticationDefaults.AuthenticationScheme;
options.DefaultChallengeScheme =
OpenIdConnectDefaults.AuthenticationScheme;
})
.AddCookie()
.AddOpenIdConnect(options =>
{
options.SignInScheme =
CookieAuthenticationDefaults.AuthenticationScheme;
options.Authority = "https://localhost:44352";
options.RequireHttpsMetadata = true;
options.ClientId = "AspNetCoreRequireMfaOidc";
options.ClientSecret = "AspNetCoreRequireMfaOidcSecret";
options.ResponseType = "code";
options.UsePkce = true;
options.Scope.Add("profile");
options.Scope.Add("offline_access");
options.SaveTokens = true;
});
builder.Services.AddAuthorization(options =>
{
options.AddPolicy("RequireMfa", policyIsAdminRequirement =>
{
policyIsAdminRequirement.Requirements.Add(new RequireMfa());
});
});
builder.Services.AddRazorPages();
Politika daha sonra gerektiği şekilde Razor sayfasında kullanılır. İlke, uygulamanın tamamı için genel olarak da eklenebilir.
[Authorize(Policy= "RequireMfa")]
public class IndexModel : PageModel
{
public void OnGet()
{
}
}
Kullanıcı MFA olmadan kimlik doğrulaması yaparsa, talebin amr büyük olasılıkla bir pwd (parola) değeri vardır. Sonuç olarak, istek sayfaya erişme yetkisine sahip değildir. Kullanıcı varsayılan değerleri kullanarakAccessDenied> sayfasına yönlendirilir. Bu davranış değiştirilebilir veya kendi özel mantığınızı uygulayabilirsiniz. Bu örnekte, geçerli kullanıcının hesabı için MFA ayarlayabilmesi için bir bağlantı eklenir.
@page
@model AspNetCoreRequireMfaOidc.AccessDeniedModel
@{
ViewData["Title"] = "AccessDenied";
Layout = "~/Pages/Shared/_Layout.cshtml";
}
<h1>AccessDenied</h1>
You require MFA to login here
<a href="https://localhost:44352/Manage/TwoFactorAuthentication">Enable MFA</a>
Bu değişiklik sonrasında, sayfaya veya web sitesine yalnızca MFA ile kimlik doğrulayan kullanıcılar erişebilir. Farklı MFA türleri kullanılıyorsa veya 2FA'ya izin verilirse, talebin amr farklı değerleri vardır ve doğru işlenmesi gerekir. Farklı OpenID Connect sunucuları da bu talep için farklı değerler döndürür. Bu değerler IETF Kimlik Doğrulama Yöntemi Başvuru Değerleri belirtimini izlemeyebilir.
Kullanıcı MFA olmadan oturum açtığında (örneğin, yalnızca parola kullanarak):
amrclaim'i,pwdparola değerine sahiptir:
Erişim reddedildi:
Alternatif olarak, kullanıcı Identity ile OTP kullanarak oturum açtığında, amr claim’i mfa değerine sahiptir:
OIDC ve OAuth parametre özelleştirmesi
OAuth ve OIDC kimlik doğrulama işleyicileri AdditionalAuthorizationParameters seçeneği, yeniden yönlendirme sorgu dizesinin parçası olarak yaygın olarak dahil edilen yetkilendirme iletisi parametrelerinin özelleştirilmesine olanak tanır:
builder.Services.AddAuthentication().AddOpenIdConnect(options =>
{
options.AdditionalAuthorizationParameters.Add("prompt", "login");
options.AdditionalAuthorizationParameters.Add("audience", "https://api.example.com");
});
İlgili içerik
- ASP.NET Core'da TOTP kimlik doğrulayıcı uygulamaları için QR Kodu oluşturmayı etkinleştirme
- Microsoft Entra ID kimlik doğrulama yöntemleri - geçiş anahtarları (FIDO2)
- FIDO2 için FIDO2 .NET kitaplığı / .NET (GitHub) ile WebAuthn kanıtlama ve onaylama
- WebAuthn ve Passkeys Awesome (GitHub)
Tarafından Damien Bowden
Örnek kodu görüntüleme veya indirme (damienbod/AspNetCoreHybridFlowWithApi GitHub deposu)
Çok faktörlü kimlik doğrulaması (MFA), bir kullanıcının ek tanımlama biçimleri için oturum açma olayı sırasında istendiği bir işlemdir. Bu istem, bir cep telefonundan kod girmek, FIDO2 anahtarı kullanmak veya parmak izi taraması sağlamak olabilir. İkinci bir kimlik doğrulama biçimine ihtiyacınız olduğunda güvenlik iyileştirilmiştir. Ek faktör bir siber saldırı aracı tarafından kolayca elde edilemez veya çoğaltılmaz.
Bu makale aşağıdaki alanları kapsar:
- MFA nedir ve hangi MFA akışları önerilir?
- ASP.NET Core kullanarak yönetim sayfaları için MFA'yi yapılandırma Identity
- OpenID Connect sunucusuna MFA oturum açma gereksinimi gönderme
- ASP.NET Core OpenID Connect istemcisini MFA gerektirmeye zorlama
MFA (Çok Faktörlü Kimlik Doğrulama), 2FA (İki Faktörlü Kimlik Doğrulama)
MFA, bildiğiniz, sahip olduğunuz bir şey veya kullanıcının kimlik doğrulaması için biyometrik doğrulama gibi bir kimlik için en az iki veya daha fazla türde kanıt gerektirir.
İki öğeli kimlik doğrulaması (2FA), MFA'nın bir alt kümesi gibidir, ancak MFA'nın kimliği kanıtlamak için iki veya daha fazla faktör gerektirmesi farktır.
2FA, ASP.NET Core Identitykullanılırken varsayılan olarak desteklenir. Belirli bir kullanıcı için 2FA'yı etkinleştirmek veya devre dışı bırakmak için özelliğini ayarlayın IdentityUser<TKey>.TwoFactorEnabled . ASP.NET Temel Identity Varsayılan kullanıcı arabirimi, 2FA'nın yapılandırılması için sayfalar içerir.
MFA TOTP (Zamana Dayalı Tek Seferlik Parola Algoritması)
TOTP kullanan MFA, ASP.NET Core Identitykullanılırken varsayılan olarak desteklenir. Bu yaklaşım, aşağıdakiler dahil olmak üzere tüm uyumlu kimlik doğrulayıcı uygulamalarıyla birlikte kullanılabilir:
- Microsoft Authenticator
- Google Kimlik Doğrulayıcı
Uygulama ayrıntıları için bkz . ASP.NET Core'da TOTP kimlik doğrulayıcı uygulamaları için QR Kodu oluşturmayı etkinleştirme.
MFA TOTP desteğini devre dışı bırakmak için AddIdentity yerine AddDefaultIdentity kullanarak kimlik doğrulamasını yapılandırın.
AddDefaultIdentity dahili olarak AddDefaultTokenProviders fonksiyonunu çağırır, bu da MFA TOTP için bir tane de dahil olmak üzere birden çok belirteç sağlayıcısını kaydeder. Yalnızca belirli belirteç sağlayıcılarını kaydetmek için gerekli sağlayıcılar için AddTokenProvider kullanın. Kullanılabilir belirteç sağlayıcıları hakkında daha fazla bilgi için IdentityBuilderExtensions adresinde uzantı yöntemlerine bakın.
MFA geçiş anahtarları/FIDO2 veya parolasız
passkeys/FIDO2 şu anda:
- MFA'ya ulaşmanın en güvenli yolu.
- Kimlik avı saldırılarına karşı koruma sağlayan Çok Faktörlü Kimlik Doğrulama (MFA). (Sertifika kimlik doğrulaması ve İş için Windows'un yanı sıra)
Şu anda ASP.NET Core doğrudan geçiş anahtarlarını/FIDO2'yi desteklememektedir. Geçiş anahtarları/FIDO2, MFA veya parolasız akışlar için kullanılabilir.
Microsoft Entra ID, geçiş anahtarları/FIDO2 ve parolasız akışlar için destek sağlar. Daha fazla bilgi için bkz. Parolasız kimlik doğrulama seçenekleri.
Parolasız MFA'nın diğer biçimleri kimlik avına karşı koruma sağlamaz veya korumayabilir.
Dışişleri Bakanlığı SMS Gönderimi
SMS ile MFA, parola kimlik doğrulaması (tek faktör) ile karşılaştırıldığında güvenliği büyük ölçüde artırır. Ancak SMS'in ikinci bir faktör olarak kullanılması artık önerilmez. Bu tür bir uygulama için çok fazla bilinen saldırı vektörleri var.
ASP.NET Core kullanarak yönetim sayfaları için MFA'yi yapılandırma Identity
MFA, kullanıcılara ASP.NET Core Identity uygulamasındaki hassas sayfalara erişmeye zorlanabilir. Bu, farklı kimlikler için farklı erişim düzeylerinin bulunduğu uygulamalar için yararlı olabilir. Örneğin, kullanıcılar profil verilerini parolayla oturum açma bilgilerini kullanarak görüntüleyebilir, ancak yöneticinin yönetim sayfalarına erişmek için MFA kullanması gerekebilir.
MFA talebiyle oturum açmayı genişletme
Tanıtım kodu, ASP.NET Core Identity ve Razor Pages kullanılarak kuruldu.
AddIdentity yöntemi AddDefaultIdentity yöntemi yerine kullanıldığından, başarılı bir oturum açma sonrasında kimliğe talep eklemek için bir IUserClaimsPrincipalFactory uygulaması kullanılabilir.
Uyarı
Bu makalede bağlantı dizesi kullanımı gösterilmektedir. Geliştirme ve test için yerel veritabanı kullanıldığında, bağlantı dizesi aracılığıyla veritabanı kullanıcı kimlik doğrulaması gerekmez. Üretim ortamlarında, bağlantı dizeleri bazen veritabanı erişiminin veya veritabanı işlemlerinin kimliğini doğrulamak için bir parola içerir. Bir bağlantı dizesindeki kaynak sahibi parola kimlik bilgisi (ROPC), üretim uygulamalarında kaçınılması gereken bir güvenlik riskidir. Üretim uygulamaları kullanılabilir en güvenli kimlik doğrulama akışını kullanmalıdır. Test veya üretim ortamlarına dağıtılan uygulamalar için kimlik doğrulaması hakkında daha fazla bilgi için ASP.NET Temel güvenlik konularına bakın.
builder.Services.AddDbContext<ApplicationDbContext>(options =>
options.UseSqlite(
Configuration.GetConnectionString("DefaultConnection")));
builder.Services.AddIdentity<IdentityUser, IdentityRole>(options =>
options.SignIn.RequireConfirmedAccount = false)
.AddEntityFrameworkStores<ApplicationDbContext>()
.AddDefaultTokenProviders();
builder.Services.AddSingleton<IEmailSender, EmailSender>();
builder.Services.AddScoped<IUserClaimsPrincipalFactory<IdentityUser>,
AdditionalUserClaimsPrincipalFactory>();
builder.Services.AddAuthorization(options =>
options.AddPolicy("TwoFactorEnabled", x => x.RequireClaim("amr", "mfa")));
builder.Services.AddRazorPages();
AdditionalUserClaimsPrincipalFactory sınıfı, yalnızca başarılı bir oturum açma sonrasında amr talebini kullanıcı taleplerine ekler. Talebin değeri veritabanından okunur. Talep buraya eklenir çünkü kullanıcının yalnızca kimlik MFA ile oturum açmışsa daha yüksek korumalı görünüme erişmesi gerekir. Veritabanı görünümü talebi kullanmak yerine doğrudan veritabanından okunursa, MFA etkinleştirildikten sonra doğrudan MFA olmadan görünüme erişmek mümkündür.
using Microsoft.AspNetCore.Identity;
using Microsoft.Extensions.Options;
using System.Collections.Generic;
using System.Security.Claims;
using System.Threading.Tasks;
namespace IdentityStandaloneMfa
{
public class AdditionalUserClaimsPrincipalFactory :
UserClaimsPrincipalFactory<IdentityUser, IdentityRole>
{
public AdditionalUserClaimsPrincipalFactory(
UserManager<IdentityUser> userManager,
RoleManager<IdentityRole> roleManager,
IOptions<IdentityOptions> optionsAccessor)
: base(userManager, roleManager, optionsAccessor)
{
}
public async override Task<ClaimsPrincipal> CreateAsync(IdentityUser user)
{
var principal = await base.CreateAsync(user);
var identity = (ClaimsIdentity)principal.Identity;
var claims = new List<Claim>();
if (user.TwoFactorEnabled)
{
claims.Add(new Claim("amr", "mfa"));
}
else
{
claims.Add(new Claim("amr", "pwd"));
}
identity.AddClaims(claims);
return principal;
}
}
}
Identity hizmet kurulumu Startup sınıfında değiştiği için, Identity düzenlerinin güncellenmesi gerekir. Uygulamaya Identity sayfalarını iskeleye ekleyin. Dosyadaki Identity/Account/Manage/_Layout.cshtml düzeni tanımlayın.
@{
Layout = "/Pages/Shared/_Layout.cshtml";
}
Ayrıca, Identity sayfalarından tüm yönetim sayfaları için düzeni belirleyin.
@{
Layout = "_Layout.cshtml";
}
Yönetim sayfasında MFA gereksinimini doğrulama
Yönetim Razor Sayfası, kullanıcının MFA kullanarak oturum açtığını doğrular.
OnGet yönteminde kimlik, kullanıcı taleplerine erişmek için kullanılır. Talep amr değeri mfa için denetlendi. Kimlik bu iddiayı içermiyorsa veya kimlik falseise, sayfa Çok Faktörlü Kimlik Doğrulamayı Etkinleştir sayfasına yönlendirilir. Kullanıcı MFA olmadan zaten oturum açtığından bu mümkündür.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;
namespace IdentityStandaloneMfa
{
public class AdminModel : PageModel
{
public IActionResult OnGet()
{
var claimTwoFactorEnabled =
User.Claims.FirstOrDefault(t => t.Type == "amr");
if (claimTwoFactorEnabled != null &&
"mfa".Equals(claimTwoFactorEnabled.Value))
{
// You logged in with MFA, do the administrative stuff
}
else
{
return Redirect(
"/Identity/Account/Manage/TwoFactorAuthentication");
}
return Page();
}
}
}
Kullanıcı oturum açma bilgilerini değiştirmek için kullanıcı arabirimi mantığı
Başlangıçta bir yetkilendirme ilkesi eklendi. İlke, amr değerine sahip mfa talep gerektirir.
services.AddAuthorization(options =>
options.AddPolicy("TwoFactorEnabled",
x => x.RequireClaim("amr", "mfa")));
Bu ilke daha sonra görünümde _Layoutyönetici menüsünü şu uyarıyla göstermek veya gizlemek için kullanılabilir:
@using Microsoft.AspNetCore.Authorization
@using Microsoft.AspNetCore.Identity
@inject SignInManager<IdentityUser> SignInManager
@inject UserManager<IdentityUser> UserManager
@inject IAuthorizationService AuthorizationService
Kimlik MFA kullanarak oturum açtıysa, Yönetici menüsü araç ipucu uyarısı olmadan görüntülenir. Kullanıcı MFA olmadan oturum açtığında, kullanıcıyı bilgilendiren araç ipucuyla birlikte Yönetici (Etkin Değil) menüsü görüntülenir (uyarı açıklanmaktadır).
@if (SignInManager.IsSignedIn(User))
{
@if ((AuthorizationService.AuthorizeAsync(User, "TwoFactorEnabled")).Result.Succeeded)
{
<li class="nav-item">
<a class="nav-link text-dark" asp-area="" asp-page="/Admin">Admin</a>
</li>
}
else
{
<li class="nav-item">
<a class="nav-link text-dark" asp-area="" asp-page="/Admin"
id="tooltip-demo"
data-toggle="tooltip"
data-placement="bottom"
title="MFA is NOT enabled. This is required for the Admin Page. If you have activated MFA, then logout, login again.">
Admin (Not Enabled)
</a>
</li>
}
}
Kullanıcı MFA olmadan oturum açarsa uyarı görüntülenir:
Kullanıcı, Yönetici bağlantısına tıklandığında MFA etkinleştirme görünümüne yönlendirilir:
OpenID Connect sunucusuna MFA oturum açma gereksinimi gönderme
parametresi, acr_values bir kimlik doğrulama isteğinde mfa istemciden sunucuya gerekli değeri geçirmek için kullanılabilir.
Not
Bunun acr_values çalışması için parametresinin OpenID Connect sunucusunda işlenmesi gerekir.
OpenID Connect ASP.NET Core istemcisi
ASP.NET Core Razor Pages OpenID Connect istemci uygulaması, OpenID Connect sunucusunda oturum açmak için yöntemini kullanır AddOpenIdConnect .
acr_values değeriyle ayarlanan mfa parametresi, kimlik doğrulama isteğiyle gönderilir.
OpenIdConnectEvents bunu eklemek için kullanılır.
Önerilen acr_values parametre değerleri için bkz. Kimlik Doğrulama Yöntemi Başvuru Değerleri.
build.Services.AddAuthentication(options =>
{
options.DefaultScheme =
CookieAuthenticationDefaults.AuthenticationScheme;
options.DefaultChallengeScheme =
OpenIdConnectDefaults.AuthenticationScheme;
})
.AddCookie()
.AddOpenIdConnect(options =>
{
options.SignInScheme =
CookieAuthenticationDefaults.AuthenticationScheme;
options.Authority = "<OpenID Connect server URL>";
options.RequireHttpsMetadata = true;
options.ClientId = "<OpenID Connect client ID>";
options.ClientSecret = "<>";
options.ResponseType = "code";
options.UsePkce = true;
options.Scope.Add("profile");
options.Scope.Add("offline_access");
options.SaveTokens = true;
options.Events = new OpenIdConnectEvents
{
OnRedirectToIdentityProvider = context =>
{
context.ProtocolMessage.SetParameter("acr_values", "mfa");
return Task.FromResult(0);
}
};
});
ASP.NET Core ile OpenID Connect Duende IdentityServer sunucusu örneği Identity
OpenID Connect sunucusunda, ASP.NET Core Identity ve Razor Pages kullanılarak uygulanan yeni bir ErrorEnable2FA.cshtml adlı sayfa oluşturuluyor. Görünüm:
- Eğer Identity, MFA gerektiren bir uygulamadan geliyorsa ama kullanıcı bunu Identity içinde etkinleştirmediyse görüntülenir.
- Kullanıcıyı bilgilendirip bunu etkinleştirmek için bir bağlantı ekler.
@{
ViewData["Title"] = "ErrorEnable2FA";
}
<h1>The client application requires you to have MFA enabled. Enable this, try login again.</h1>
<br />
You can enable MFA to login here:
<br />
<a href="~/Identity/Account/Manage/TwoFactorAuthentication">Enable MFA</a>
yönteminde LoginIIdentityServerInteractionService , arabirim uygulaması _interaction OpenID Connect istek parametrelerine erişmek için kullanılır.
acr_values parametresine AcrValues özelliği kullanılarak erişilir. İstemci bunu mfa ayarlı olarak gönderdiği zaman, bu daha sonra kontrol edilebilir.
MFA gerekliyse ve ASP.NET Core'daki Identity kullanıcı MFA'yı etkinleştirdiyse oturum açma işlemi devam eder. Kullanıcının MFA'sı etkin olmadığında, kullanıcı özel görünümüne ErrorEnable2FA.cshtmlyönlendirilir. Ardından ASP.NET Core Identity kullanıcının oturumunu açar.
Fido2Store, kullanıcının özel bir FIDO2 Belirteç Sağlayıcısı kullanarak MFA'yi etkinleştirip etkinleştirmediğini denetlemek için kullanılır.
public async Task<IActionResult> OnPost()
{
// check if we are in the context of an authorization request
var context = await _interaction.GetAuthorizationContextAsync(Input.ReturnUrl);
var requires2Fa = context?.AcrValues.Count(t => t.Contains("mfa")) >= 1;
var user = await _userManager.FindByNameAsync(Input.Username);
if (user != null && !user.TwoFactorEnabled && requires2Fa)
{
return RedirectToPage("/Home/ErrorEnable2FA/Index");
}
// code omitted for brevity
if (ModelState.IsValid)
{
var result = await _signInManager.PasswordSignInAsync(Input.Username, Input.Password, Input.RememberLogin, lockoutOnFailure: true);
if (result.Succeeded)
{
// code omitted for brevity
}
if (result.RequiresTwoFactor)
{
var fido2ItemExistsForUser = await _fido2Store.GetCredentialsByUserNameAsync(user.UserName);
if (fido2ItemExistsForUser.Count > 0)
{
return RedirectToPage("/Account/LoginFido2Mfa", new { area = "Identity", Input.ReturnUrl, Input.RememberLogin });
}
return RedirectToPage("/Account/LoginWith2fa", new { area = "Identity", Input.ReturnUrl, RememberMe = Input.RememberLogin });
}
await _events.RaiseAsync(new UserLoginFailureEvent(Input.Username, "invalid credentials", clientId: context?.Client.ClientId));
ModelState.AddModelError(string.Empty, LoginOptions.InvalidCredentialsErrorMessage);
}
// something went wrong, show form with error
await BuildModelAsync(Input.ReturnUrl);
return Page();
}
Kullanıcı zaten oturum açmışsa istemci uygulaması:
- Yine de talebi doğrular
amr. - MFA'yı ASP.NET Çekirdek Identity görünümüne bir bağlantıyla ayarlayabilir.
ASP.NET Core OpenID Connect istemcisini MFA gerektirmeye zorlama
Bu örnekte, oturum açmak için OpenID Connect kullanan bir ASP.NET Temel Razor Sayfa uygulamasının kullanıcıların MFA kullanarak kimlik doğrulaması yapılmasını nasıl gerektirebileceği gösterilmektedir.
MFA gereksinimini doğrulamak için bir IAuthorizationRequirement gereksinim oluşturulur. Bu, MFA gerektiren bir ilke kullanılarak sayfalara eklenir.
using Microsoft.AspNetCore.Authorization;
namespace AspNetCoreRequireMfaOidc;
public class RequireMfa : IAuthorizationRequirement{}
AuthorizationHandler, amr talebini kullanarak ve mfa değerini denetleyerek uygulanır.
amr başarılı bir kimlik doğrulamasında id_token döndürülür ve Kimlik Doğrulama Yöntemi Başvuru Değerleri belirtiminde tanımlanan birçok farklı değere sahip olabilir.
Döndürülen değer, kimliğin nasıl doğrulandığına ve OpenID Connect sunucu uygulamasına bağlıdır.
AuthorizationHandler
RequireMfa gereksinimini kullanır ve amr talebini doğrular. OpenID Connect sunucusu, ASP.NET Core Identityile Duende Identity Sunucusu kullanılarak uygulanabilir. Bir kullanıcı TOTP kullanarak oturum açtığında, amr talep bir MFA değeriyle döndürülür. Farklı bir OpenID Connect sunucu uygulaması veya farklı bir MFA türü kullanıyorsanız, amr talep farklı bir değere sahip olabilir veya olabilir. Kodun da bunu kabul etmesi için genişletilmesi gerekir.
public class RequireMfaHandler : AuthorizationHandler<RequireMfa>
{
protected override Task HandleRequirementAsync(
AuthorizationHandlerContext context,
RequireMfa requirement)
{
if (context == null)
throw new ArgumentNullException(nameof(context));
if (requirement == null)
throw new ArgumentNullException(nameof(requirement));
var amrClaim =
context.User.Claims.FirstOrDefault(t => t.Type == "amr");
if (amrClaim != null && amrClaim.Value == Amr.Mfa)
{
context.Succeed(requirement);
}
return Task.CompletedTask;
}
}
Program dosyasında, AddOpenIdConnect yöntemi varsayılan sınama şeması olarak kullanılır.
amr talebini kontrol etmek için kullanılan yetkilendirme işleyicisi, Kontrolün Tersine Çevrilmesi kapsayıcısına eklenir. Ardından RequireMfa gereksinimini ekleyen bir politika oluşturulur.
builder.Services.ConfigureApplicationCookie(options =>
options.Cookie.SecurePolicy =
CookieSecurePolicy.Always);
builder.Services.AddSingleton<IAuthorizationHandler, RequireMfaHandler>();
builder.Services.AddAuthentication(options =>
{
options.DefaultScheme =
CookieAuthenticationDefaults.AuthenticationScheme;
options.DefaultChallengeScheme =
OpenIdConnectDefaults.AuthenticationScheme;
})
.AddCookie()
.AddOpenIdConnect(options =>
{
options.SignInScheme =
CookieAuthenticationDefaults.AuthenticationScheme;
options.Authority = "https://localhost:44352";
options.RequireHttpsMetadata = true;
options.ClientId = "AspNetCoreRequireMfaOidc";
options.ClientSecret = "AspNetCoreRequireMfaOidcSecret";
options.ResponseType = "code";
options.UsePkce = true;
options.Scope.Add("profile");
options.Scope.Add("offline_access");
options.SaveTokens = true;
});
builder.Services.AddAuthorization(options =>
{
options.AddPolicy("RequireMfa", policyIsAdminRequirement =>
{
policyIsAdminRequirement.Requirements.Add(new RequireMfa());
});
});
builder.Services.AddRazorPages();
Bu ilke, gerektiğinde Razor sayfada kullanılır. İlke, uygulamanın tamamı için de genel olarak eklenebilir.
[Authorize(Policy= "RequireMfa")]
public class IndexModel : PageModel
{
public void OnGet()
{
}
}
Kullanıcı MFA olmadan kimlik doğrulaması yaparsa, amr talep büyük olasılıkla bir pwd değere sahip olur. İstek, sayfaya erişim izni almayacaktır. Kullanıcı varsayılan değerleri kullanarak Account/AccessDenied sayfasına yönlendirilir. Bu davranış değiştirilebilir veya burada kendi özel mantığınızı uygulayabilirsiniz. Bu örnekte, geçerli kullanıcının hesabı için MFA ayarlayabilmesi için bir bağlantı eklenir.
@page
@model AspNetCoreRequireMfaOidc.AccessDeniedModel
@{
ViewData["Title"] = "AccessDenied";
Layout = "~/Pages/Shared/_Layout.cshtml";
}
<h1>AccessDenied</h1>
You require MFA to login here
<a href="https://localhost:44352/Manage/TwoFactorAuthentication">Enable MFA</a>
Artık sayfaya veya web sitesine yalnızca MFA ile kimlik doğrulayan kullanıcılar erişebilir. Farklı MFA türleri kullanılıyorsa veya 2FA uygunsa, amr talep farklı değerlere sahip olur ve doğru işlenmesi gerekir. Farklı OpenID Connect sunucuları da bu talep için farklı değerler döndürür ve Kimlik Doğrulama Yöntemi Başvuru Değerleri belirtimini izlemeyebilir.
MFA olmadan oturum açarken (örneğin, yalnızca bir parola kullanarak):
amrşu değerepwdsahiptir:
Erişim reddedildi:
Alternatif olarak, Identity kullanarak OTP ile oturum açma:
Ek kaynaklar
Tarafından Damien Bowden
Örnek kodu görüntüleme veya indirme (damienbod/AspNetCoreHybridFlowWithApi GitHub deposu)
Çok faktörlü kimlik doğrulaması (MFA), bir kullanıcının ek tanımlama biçimleri için oturum açma olayı sırasında istendiği bir işlemdir. Bu istem, bir cep telefonundan kod girmek, FIDO2 anahtarı kullanmak veya parmak izi taraması sağlamak olabilir. İkinci bir kimlik doğrulama biçimine ihtiyacınız olduğunda güvenlik iyileştirilmiştir. Ek faktör bir siber saldırı aracı tarafından kolayca elde edilemez veya çoğaltılmaz.
Bu makale aşağıdaki alanları kapsar:
- MFA nedir ve hangi MFA akışları önerilir?
- ASP.NET Core kullanarak yönetim sayfaları için MFA'yi yapılandırma Identity
- OpenID Connect sunucusuna MFA oturum açma gereksinimi gönderme
- ASP.NET Core OpenID Connect istemcisini MFA gerektirmeye zorlama
MFA (Çok Faktörlü Kimlik Doğrulama), 2FA (İki Faktörlü Kimlik Doğrulama)
MFA, bildiğiniz, sahip olduğunuz bir şey veya kullanıcının kimlik doğrulaması için biyometrik doğrulama gibi bir kimlik için en az iki veya daha fazla türde kanıt gerektirir.
İki öğeli kimlik doğrulaması (2FA), MFA'nın bir alt kümesi gibidir, ancak MFA'nın kimliği kanıtlamak için iki veya daha fazla faktör gerektirmesi farktır.
MFA TOTP (Zamana Dayalı Tek Seferlik Parola Algoritması)
TOTP kullanan MFA, ASP.NET Core Identitykullanan desteklenen bir uygulamadır. Bu, aşağıdakiler dahil olmak üzere tüm uyumlu kimlik doğrulayıcı uygulamalarıyla birlikte kullanılabilir:
- Microsoft Authenticator Uygulaması
- Google Authenticator Uygulaması
Uygulama ayrıntıları için aşağıdaki bağlantıya bakın:
ASP.NET Core'da TOTP kimlik doğrulayıcı uygulamaları için QR Kodu oluşturmayı etkinleştirme
MFA geçiş anahtarları/FIDO2 veya parolasız
passkeys/FIDO2 şu anda:
- MFA'ya ulaşmanın en güvenli yolu.
- Kimlik avı saldırılarına karşı koruma sağlayan Çok Faktörlü Kimlik Doğrulama (MFA). (Sertifika kimlik doğrulaması ve İş için Windows'un yanı sıra)
Şu anda ASP.NET Core doğrudan geçiş anahtarlarını/FIDO2'yi desteklememektedir. Geçiş anahtarları/FIDO2, MFA veya parolasız akışlar için kullanılabilir.
Microsoft Entra ID, geçiş anahtarları/FIDO2 ve parolasız akışlar için destek sağlar. Daha fazla bilgi için bkz. Parolasız kimlik doğrulama seçenekleri.
Parolasız MFA'nın diğer biçimleri kimlik avına karşı koruma sağlamaz veya korumayabilir.
Dışişleri Bakanlığı SMS Gönderimi
SMS ile MFA, parola kimlik doğrulaması (tek faktör) ile karşılaştırıldığında güvenliği büyük ölçüde artırır. Ancak SMS'in ikinci bir faktör olarak kullanılması artık önerilmez. Bu tür bir uygulama için çok fazla bilinen saldırı vektörleri var.
ASP.NET Core kullanarak yönetim sayfaları için MFA'yi yapılandırma Identity
MFA, kullanıcılara ASP.NET Core Identity uygulamasındaki hassas sayfalara erişmeye zorlanabilir. Bu, farklı kimlikler için farklı erişim düzeylerinin bulunduğu uygulamalar için yararlı olabilir. Örneğin, kullanıcılar profil verilerini parolayla oturum açma bilgilerini kullanarak görüntüleyebilir, ancak yöneticinin yönetim sayfalarına erişmek için MFA kullanması gerekebilir.
MFA talebiyle oturum açmayı genişletme
Tanıtım kodu, ASP.NET Core Identity ve Razor Pages kullanılarak kuruldu.
AddIdentity yöntemi AddDefaultIdentity yöntemi yerine kullanıldığından, başarılı bir oturum açma sonrasında kimliğe talep eklemek için bir IUserClaimsPrincipalFactory uygulaması kullanılabilir.
Uyarı
Bu makalede bağlantı dizesi kullanımı gösterilmektedir. Geliştirme ve test için yerel veritabanı kullanıldığında, bağlantı dizesi aracılığıyla veritabanı kullanıcı kimlik doğrulaması gerekmez. Üretim ortamlarında, bağlantı dizeleri bazen veritabanı erişiminin veya veritabanı işlemlerinin kimliğini doğrulamak için bir parola içerir. Bir bağlantı dizesindeki kaynak sahibi parola kimlik bilgisi (ROPC), üretim uygulamalarında kaçınılması gereken bir güvenlik riskidir. Üretim uygulamaları kullanılabilir en güvenli kimlik doğrulama akışını kullanmalıdır. Test veya üretim ortamlarına dağıtılan uygulamalar için kimlik doğrulaması hakkında daha fazla bilgi için ASP.NET Temel güvenlik konularına bakın.
public void ConfigureServices(IServiceCollection services)
{
services.AddDbContext<ApplicationDbContext>(options =>
options.UseSqlite(
Configuration.GetConnectionString("DefaultConnection")));
services.AddIdentity<IdentityUser, IdentityRole>(
options => options.SignIn.RequireConfirmedAccount = false)
.AddEntityFrameworkStores<ApplicationDbContext>()
.AddDefaultTokenProviders();
services.AddSingleton<IEmailSender, EmailSender>();
services.AddScoped<IUserClaimsPrincipalFactory<IdentityUser>,
AdditionalUserClaimsPrincipalFactory>();
services.AddAuthorization(options =>
options.AddPolicy("TwoFactorEnabled",
x => x.RequireClaim("amr", "mfa")));
services.AddRazorPages();
}
AdditionalUserClaimsPrincipalFactory sınıfı, yalnızca başarılı bir oturum açma sonrasında amr talebini kullanıcı taleplerine ekler. Talebin değeri veritabanından okunur. Talep buraya eklenir çünkü kullanıcının yalnızca kimlik MFA ile oturum açmışsa daha yüksek korumalı görünüme erişmesi gerekir. Veritabanı görünümü talebi kullanmak yerine doğrudan veritabanından okunursa, MFA etkinleştirildikten sonra doğrudan MFA olmadan görünüme erişmek mümkündür.
using Microsoft.AspNetCore.Identity;
using Microsoft.Extensions.Options;
using System.Collections.Generic;
using System.Security.Claims;
using System.Threading.Tasks;
namespace IdentityStandaloneMfa
{
public class AdditionalUserClaimsPrincipalFactory :
UserClaimsPrincipalFactory<IdentityUser, IdentityRole>
{
public AdditionalUserClaimsPrincipalFactory(
UserManager<IdentityUser> userManager,
RoleManager<IdentityRole> roleManager,
IOptions<IdentityOptions> optionsAccessor)
: base(userManager, roleManager, optionsAccessor)
{
}
public async override Task<ClaimsPrincipal> CreateAsync(IdentityUser user)
{
var principal = await base.CreateAsync(user);
var identity = (ClaimsIdentity)principal.Identity;
var claims = new List<Claim>();
if (user.TwoFactorEnabled)
{
claims.Add(new Claim("amr", "mfa"));
}
else
{
claims.Add(new Claim("amr", "pwd"));
}
identity.AddClaims(claims);
return principal;
}
}
}
Identity hizmet kurulumu Startup sınıfında değiştiği için, Identity düzenlerinin güncellenmesi gerekir. Uygulamaya Identity sayfalarını iskeleye ekleyin. Dosyadaki Identity/Account/Manage/_Layout.cshtml düzeni tanımlayın.
@{
Layout = "/Pages/Shared/_Layout.cshtml";
}
Ayrıca, Identity sayfalarından tüm yönetim sayfaları için düzeni belirleyin.
@{
Layout = "_Layout.cshtml";
}
Yönetim sayfasında MFA gereksinimini doğrulama
Yönetim Razor Sayfası, kullanıcının MFA kullanarak oturum açtığını doğrular.
OnGet yönteminde kimlik, kullanıcı taleplerine erişmek için kullanılır. Talep amr değeri mfa için denetlendi. Kimlik bu iddiayı içermiyorsa veya kimlik falseise, sayfa Çok Faktörlü Kimlik Doğrulamayı Etkinleştir sayfasına yönlendirilir. Kullanıcı MFA olmadan zaten oturum açtığından bu mümkündür.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;
namespace IdentityStandaloneMfa
{
public class AdminModel : PageModel
{
public IActionResult OnGet()
{
var claimTwoFactorEnabled =
User.Claims.FirstOrDefault(t => t.Type == "amr");
if (claimTwoFactorEnabled != null &&
"mfa".Equals(claimTwoFactorEnabled.Value))
{
// You logged in with MFA, do the administrative stuff
}
else
{
return Redirect(
"/Identity/Account/Manage/TwoFactorAuthentication");
}
return Page();
}
}
}
Kullanıcı oturum açma bilgilerini değiştirmek için kullanıcı arabirimi mantığı
Program dosyasına bir yetkilendirme ilkesi eklendi. İlke, amr değerine sahip mfa talep gerektirir.
builder.Services.AddAuthorization(options =>
options.AddPolicy("TwoFactorEnabled",
x => x.RequireClaim("amr", "mfa")));
Bu ilke daha sonra görünümde _Layoutyönetici menüsünü şu uyarıyla göstermek veya gizlemek için kullanılabilir:
@using Microsoft.AspNetCore.Authorization
@using Microsoft.AspNetCore.Identity
@inject SignInManager<IdentityUser> SignInManager
@inject UserManager<IdentityUser> UserManager
@inject IAuthorizationService AuthorizationService
Kimlik MFA kullanarak oturum açtıysa, Yönetici menüsü araç ipucu uyarısı olmadan görüntülenir. Kullanıcı MFA olmadan oturum açtığında, kullanıcıyı bilgilendiren araç ipucuyla birlikte Yönetici (Etkin Değil) menüsü görüntülenir (uyarı açıklanmaktadır).
@if (SignInManager.IsSignedIn(User))
{
@if ((AuthorizationService.AuthorizeAsync(User, "TwoFactorEnabled")).Result.Succeeded)
{
<li class="nav-item">
<a class="nav-link text-dark" asp-area="" asp-page="/Admin">Admin</a>
</li>
}
else
{
<li class="nav-item">
<a class="nav-link text-dark" asp-area="" asp-page="/Admin"
id="tooltip-demo"
data-toggle="tooltip"
data-placement="bottom"
title="MFA is NOT enabled. This is required for the Admin Page. If you have activated MFA, then logout, login again.">
Admin (Not Enabled)
</a>
</li>
}
}
Kullanıcı MFA olmadan oturum açarsa uyarı görüntülenir:
Kullanıcı, Yönetici bağlantısına tıklandığında MFA etkinleştirme görünümüne yönlendirilir:
OpenID Connect sunucusuna MFA oturum açma gereksinimi gönderme
parametresi, acr_values bir kimlik doğrulama isteğinde mfa istemciden sunucuya gerekli değeri geçirmek için kullanılabilir.
Not
Bunun acr_values çalışması için parametresinin OpenID Connect sunucusunda işlenmesi gerekir.
OpenID Connect ASP.NET Core istemcisi
ASP.NET Core Razor Pages OpenID Connect istemci uygulaması, OpenID Connect sunucusunda oturum açmak için yöntemini kullanır AddOpenIdConnect .
acr_values değeriyle ayarlanan mfa parametresi, kimlik doğrulama isteğiyle gönderilir.
OpenIdConnectEvents bunu eklemek için kullanılır.
Önerilen acr_values parametre değerleri için bkz. Kimlik Doğrulama Yöntemi Başvuru Değerleri.
public void ConfigureServices(IServiceCollection services)
{
services.AddAuthentication(options =>
{
options.DefaultScheme =
CookieAuthenticationDefaults.AuthenticationScheme;
options.DefaultChallengeScheme =
OpenIdConnectDefaults.AuthenticationScheme;
})
.AddCookie()
.AddOpenIdConnect(options =>
{
options.SignInScheme =
CookieAuthenticationDefaults.AuthenticationScheme;
options.Authority = "<OpenID Connect server URL>";
options.RequireHttpsMetadata = true;
options.ClientId = "<OpenID Connect client ID>";
options.ClientSecret = "<>";
options.ResponseType = "code";
options.UsePkce = true;
options.Scope.Add("profile");
options.Scope.Add("offline_access");
options.SaveTokens = true;
options.Events = new OpenIdConnectEvents
{
OnRedirectToIdentityProvider = context =>
{
context.ProtocolMessage.SetParameter("acr_values", "mfa");
return Task.FromResult(0);
}
};
});
ASP.NET Core ile Örnek OpenID Connect IdentityServer 4 sunucusu Identity
MVC görünümleriyle ASP.NET Core Identity kullanılarak uygulanan OpenID Connect sunucusunda adlı ErrorEnable2FA.cshtml yeni bir görünüm oluşturulur. Görünüm:
- Eğer Identity, MFA gerektiren bir uygulamadan geliyorsa ama kullanıcı bunu Identity içinde etkinleştirmediyse görüntülenir.
- Kullanıcıyı bilgilendirip bunu etkinleştirmek için bir bağlantı ekler.
@{
ViewData["Title"] = "ErrorEnable2FA";
}
<h1>The client application requires you to have MFA enabled. Enable this, try login again.</h1>
<br />
You can enable MFA to login here:
<br />
<a asp-controller="Manage" asp-action="TwoFactorAuthentication">Enable MFA</a>
yönteminde LoginIIdentityServerInteractionService , arabirim uygulaması _interaction OpenID Connect istek parametrelerine erişmek için kullanılır.
acr_values parametresine AcrValues özelliği kullanılarak erişilir. İstemci bunu mfa ayarlı olarak gönderdiği zaman, bu daha sonra kontrol edilebilir.
MFA gerekliyse ve ASP.NET Core'daki Identity kullanıcı MFA'yı etkinleştirdiyse oturum açma işlemi devam eder. Kullanıcının MFA'sı etkin olmadığında, kullanıcı özel görünümüne ErrorEnable2FA.cshtmlyönlendirilir. Ardından ASP.NET Core Identity kullanıcının oturumunu açar.
//
// POST: /Account/Login
[HttpPost]
[AllowAnonymous]
[ValidateAntiForgeryToken]
public async Task<IActionResult> Login(LoginInputModel model)
{
var returnUrl = model.ReturnUrl;
var context =
await _interaction.GetAuthorizationContextAsync(returnUrl);
var requires2Fa =
context?.AcrValues.Count(t => t.Contains("mfa")) >= 1;
var user = await _userManager.FindByNameAsync(model.Email);
if (user != null && !user.TwoFactorEnabled && requires2Fa)
{
return RedirectToAction(nameof(ErrorEnable2FA));
}
// code omitted for brevity
ExternalLoginCallback yöntemi yerel Identity oturum açma gibi çalışır.
AcrValues özelliği, mfa değeri için denetlendi. Eğer mfa değeri varsa, oturum açma tamamlanmadan önce MFA kullanımı zorlanır (örneğin, ErrorEnable2FA görünümüne yönlendirilir).
//
// GET: /Account/ExternalLoginCallback
[HttpGet]
[AllowAnonymous]
public async Task<IActionResult> ExternalLoginCallback(
string returnUrl = null,
string remoteError = null)
{
var context =
await _interaction.GetAuthorizationContextAsync(returnUrl);
var requires2Fa =
context?.AcrValues.Count(t => t.Contains("mfa")) >= 1;
if (remoteError != null)
{
ModelState.AddModelError(
string.Empty,
_sharedLocalizer["EXTERNAL_PROVIDER_ERROR",
remoteError]);
return View(nameof(Login));
}
var info = await _signInManager.GetExternalLoginInfoAsync();
if (info == null)
{
return RedirectToAction(nameof(Login));
}
var email = info.Principal.FindFirstValue(ClaimTypes.Email);
if (!string.IsNullOrEmpty(email))
{
var user = await _userManager.FindByNameAsync(email);
if (user != null && !user.TwoFactorEnabled && requires2Fa)
{
return RedirectToAction(nameof(ErrorEnable2FA));
}
}
// Sign in the user with this external login provider if the user already has a login.
var result = await _signInManager
.ExternalLoginSignInAsync(
info.LoginProvider,
info.ProviderKey,
isPersistent:
false);
// code omitted for brevity
Kullanıcı zaten oturum açmışsa istemci uygulaması:
- Yine de talebi doğrular
amr. - MFA'yı ASP.NET Çekirdek Identity görünümüne bir bağlantıyla ayarlayabilir.
ASP.NET Core OpenID Connect istemcisini MFA gerektirmeye zorlama
Bu örnekte, oturum açmak için OpenID Connect kullanan bir ASP.NET Temel Razor Sayfa uygulamasının kullanıcıların MFA kullanarak kimlik doğrulaması yapılmasını nasıl gerektirebileceği gösterilmektedir.
MFA gereksinimini doğrulamak için bir IAuthorizationRequirement gereksinim oluşturulur. Bu, MFA gerektiren bir ilke kullanılarak sayfalara eklenir.
using Microsoft.AspNetCore.Authorization;
namespace AspNetCoreRequireMfaOidc
{
public class RequireMfa : IAuthorizationRequirement{}
}
AuthorizationHandler, amr talebini kullanarak ve mfa değerini denetleyerek uygulanır.
amr başarılı bir kimlik doğrulamasında id_token döndürülür ve Kimlik Doğrulama Yöntemi Başvuru Değerleri belirtiminde tanımlanan birçok farklı değere sahip olabilir.
Döndürülen değer, kimliğin nasıl doğrulandığına ve OpenID Connect sunucu uygulamasına bağlıdır.
AuthorizationHandler
RequireMfa gereksinimini kullanır ve amr talebini doğrular. OpenID Connect sunucusu, ASP.NET Core Identityile IdentityServer4 kullanılarak uygulanabilir. Bir kullanıcı TOTP kullanarak oturum açtığında, amr talep bir MFA değeriyle döndürülür. Farklı bir OpenID Connect sunucu uygulaması veya farklı bir MFA türü kullanıyorsanız, amr talep farklı bir değere sahip olabilir veya olabilir. Kodun da bunu kabul etmesi için genişletilmesi gerekir.
public class RequireMfaHandler : AuthorizationHandler<RequireMfa>
{
protected override Task HandleRequirementAsync(
AuthorizationHandlerContext context,
RequireMfa requirement)
{
if (context == null)
throw new ArgumentNullException(nameof(context));
if (requirement == null)
throw new ArgumentNullException(nameof(requirement));
var amrClaim =
context.User.Claims.FirstOrDefault(t => t.Type == "amr");
if (amrClaim != null && amrClaim.Value == Amr.Mfa)
{
context.Succeed(requirement);
}
return Task.CompletedTask;
}
}
"Startup.ConfigureServices yönteminde, AddOpenIdConnect yöntemi varsayılan sınama şeması olarak kullanılır."
amr talebini kontrol etmek için kullanılan yetkilendirme işleyicisi, Kontrolün Tersine Çevrilmesi kapsayıcısına eklenir. Ardından RequireMfa gereksinimini ekleyen bir politika oluşturulur.
public void ConfigureServices(IServiceCollection services)
{
services.ConfigureApplicationCookie(options =>
options.Cookie.SecurePolicy =
CookieSecurePolicy.Always);
services.AddSingleton<IAuthorizationHandler, RequireMfaHandler>();
services.AddAuthentication(options =>
{
options.DefaultScheme =
CookieAuthenticationDefaults.AuthenticationScheme;
options.DefaultChallengeScheme =
OpenIdConnectDefaults.AuthenticationScheme;
})
.AddCookie()
.AddOpenIdConnect(options =>
{
options.SignInScheme =
CookieAuthenticationDefaults.AuthenticationScheme;
options.Authority = "https://localhost:44352";
options.RequireHttpsMetadata = true;
options.ClientId = "AspNetCoreRequireMfaOidc";
options.ClientSecret = "AspNetCoreRequireMfaOidcSecret";
options.ResponseType = "code";
options.UsePkce = true;
options.Scope.Add("profile");
options.Scope.Add("offline_access");
options.SaveTokens = true;
});
services.AddAuthorization(options =>
{
options.AddPolicy("RequireMfa", policyIsAdminRequirement =>
{
policyIsAdminRequirement.Requirements.Add(new RequireMfa());
});
});
services.AddRazorPages();
}
Bu ilke, gerektiğinde Razor sayfada kullanılır. İlke, uygulamanın tamamı için de genel olarak eklenebilir.
[Authorize(Policy= "RequireMfa")]
public class IndexModel : PageModel
{
public void OnGet()
{
}
}
Kullanıcı MFA olmadan kimlik doğrulaması yaparsa, amr talep büyük olasılıkla bir pwd değere sahip olur. İstek, sayfaya erişim izni almayacaktır. Kullanıcı varsayılan değerleri kullanarak Account/AccessDenied sayfasına yönlendirilir. Bu davranış değiştirilebilir veya burada kendi özel mantığınızı uygulayabilirsiniz. Bu örnekte, geçerli kullanıcının hesabı için MFA ayarlayabilmesi için bir bağlantı eklenir.
@page
@model AspNetCoreRequireMfaOidc.AccessDeniedModel
@{
ViewData["Title"] = "AccessDenied";
Layout = "~/Pages/Shared/_Layout.cshtml";
}
<h1>AccessDenied</h1>
You require MFA to login here
<a href="https://localhost:44352/Manage/TwoFactorAuthentication">Enable MFA</a>
Artık sayfaya veya web sitesine yalnızca MFA ile kimlik doğrulayan kullanıcılar erişebilir. Farklı MFA türleri kullanılıyorsa veya 2FA uygunsa, amr talep farklı değerlere sahip olur ve doğru işlenmesi gerekir. Farklı OpenID Connect sunucuları da bu talep için farklı değerler döndürür ve Kimlik Doğrulama Yöntemi Başvuru Değerleri belirtimini izlemeyebilir.
MFA olmadan oturum açarken (örneğin, yalnızca bir parola kullanarak):
amrşu değerepwdsahiptir:
Erişim reddedildi:
Alternatif olarak, Identity kullanarak OTP ile oturum açma:
Ek kaynaklar
ASP.NET Core