ASP.NET Core'da çok faktörlü kimlik doğrulaması
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 8 sürümüne bakın.
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, 2FA
MFA, bildiğiniz, sahip olduğunuz bir şey veya kullanıcının kimlik doğrulaması için biyometrik doğrulama gibi bir identity şey 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 kanıtlaması identityiç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 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 Authenticator
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 yerine kullanarak AddIdentity kimlik doğrulamasını AddDefaultIdentityyapılandırın. AddDefaultIdentity
, MFA TOTP için bir tane de dahil olmak üzere birden çok belirteç sağlayıcısını kaydeden dahili olarak çağırır AddDefaultTokenProviders . Yalnızca belirli belirteç sağlayıcılarını kaydetmek için her gerekli sağlayıcıyı çağırın AddTokenProvider . Kullanılabilir belirteç sağlayıcıları hakkında daha fazla bilgi için GitHub'daki AddDefaultTokenProviders kaynağına 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 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.
MFA SMS
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 ve Razor Sayfaları ile Identity ASP.NET Core kullanılarak ayarlanır. AddIdentity
yöntemi bir yerine AddDefaultIdentity
kullanılır, bu nedenle başarılı bir oturum açmadan sonra öğesine talep eklemek için identity bir IUserClaimsPrincipalFactory
uygulama kullanılabilir.
Uyarı
Bu makalede bağlantı dizesi kullanımı gösterilmektedir. Yerel bir veritabanıyla kullanıcının kimliğinin doğrulanması gerekmez, ancak üretimde bağlantı dizesi bazen kimlik doğrulaması için bir parola içerir. Kaynak sahibi parola kimlik bilgileri (ROPC), üretim veritabanları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 bkz . Güvenli kimlik doğrulama akışları.
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();
sınıfı, AdditionalUserClaimsPrincipalFactory
talebi yalnızca başarılı bir oturum açma sonrasında kullanıcı taleplerine ekler amr
. Talebin değeri veritabanından okunur. Talep buraya eklenir çünkü kullanıcının yalnızca MFA ile oturum açmışsa daha yüksek korumalı görünüme identity 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 sınıfında değiştiğindenStartup
, düzenlerinin Identity güncelleştirilmiş olması gerekir. Identity Sayfaları uygulamaya iskelesi oluşturun. Dosyadaki Identity/Account/Manage/_Layout.cshtml
düzeni tanımlayın.
@{
Layout = "/Pages/Shared/_Layout.cshtml";
}
Ayrıca, sayfalardan tüm yönetme sayfaları için düzeni atayın Identity :
@{
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. yönteminde OnGet
, identity kullanıcı taleplerine erişmek için kullanılır. Talep amr
değeri mfa
için denetlendi. identity bu talep eksikse veya isefalse
, sayfa MFA'yı 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, değerine mfa
sahip talebi gerektiriramr
.
services.AddAuthorization(options =>
options.AddPolicy("TwoFactorEnabled",
x => x.RequireClaim("amr", "mfa")));
Bu ilke daha sonra görünümde _Layout
yö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
identity 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
parametresi değeriyle mfa
ayarlanır ve 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.AdditionalAuthorizationParameters.Add("acr_values", "mfa");
});
ASP.NET Core ile OpenID Connect Duende IdentityServer sunucusu örneği Identity
Pages ile Razor ASP.NET Core Identity kullanılarak uygulanan OpenID Connect sunucusunda adlı ErrorEnable2FA.cshtml
yeni bir sayfa oluşturulur. Görünüm:
- , Identity MFA gerektiren ancak kullanıcı tarafından içinde Identityetkinleştirilmemiş bir uygulamadan geliyorsa 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 Login
IIdentityServerInteractionService
, 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 set ile mfa
gönderdiğinde, bu daha sonra denetlenebilir.
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.cshtml
yö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
, talebi kullanacak amr
ve değerini mfa
denetleyecek şekilde 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ği doğrulanmış ve identity OpenID Connect sunucu uygulamasına bağlıdır.
gereksinimini AuthorizationHandler
RequireMfa
kullanır ve talebi doğrular amr
. 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. Talebi denetlemek amr
için kullanılan yetkilendirme işleyicisi, Inversion of Control kapsayıcısına eklenir. Ardından gereksinimi ekleyen RequireMfa
bir ilke 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 daha sonra sayfada gerektiği gibi kullanılır Razor . İ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şme yetkisine sahip olmayacaktı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ğerepwd
sahiptir:Erişim reddedildi:
Alternatif olarak, ile IdentityOTP kullanarak oturum açma:
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 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");
});
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, 2FA
MFA, bildiğiniz, sahip olduğunuz bir şey veya kullanıcının kimlik doğrulaması için biyometrik doğrulama gibi bir identity şey 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 kanıtlaması identityiç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 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 Authenticator
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 yerine kullanarak AddIdentity kimlik doğrulamasını AddDefaultIdentityyapılandırın. AddDefaultIdentity
, MFA TOTP için bir tane de dahil olmak üzere birden çok belirteç sağlayıcısını kaydeden dahili olarak çağırır AddDefaultTokenProviders . Yalnızca belirli belirteç sağlayıcılarını kaydetmek için her gerekli sağlayıcıyı çağırın AddTokenProvider . Kullanılabilir belirteç sağlayıcıları hakkında daha fazla bilgi için GitHub'daki AddDefaultTokenProviders kaynağına 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 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.
MFA SMS
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 ve Razor Sayfaları ile Identity ASP.NET Core kullanılarak ayarlanır. AddIdentity
yöntemi bir yerine AddDefaultIdentity
kullanılır, bu nedenle başarılı bir oturum açmadan sonra öğesine talep eklemek için identity bir IUserClaimsPrincipalFactory
uygulama kullanılabilir.
Uyarı
Bu makalede bağlantı dizesi kullanımı gösterilmektedir. Yerel bir veritabanıyla kullanıcının kimliğinin doğrulanması gerekmez, ancak üretimde bağlantı dizesi bazen kimlik doğrulaması için bir parola içerir. Kaynak sahibi parola kimlik bilgileri (ROPC), üretim veritabanları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 bkz . Güvenli kimlik doğrulama akışları.
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();
sınıfı, AdditionalUserClaimsPrincipalFactory
talebi yalnızca başarılı bir oturum açma sonrasında kullanıcı taleplerine ekler amr
. Talebin değeri veritabanından okunur. Talep buraya eklenir çünkü kullanıcının yalnızca MFA ile oturum açmışsa daha yüksek korumalı görünüme identity 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 sınıfında değiştiğindenStartup
, düzenlerinin Identity güncelleştirilmiş olması gerekir. Identity Sayfaları uygulamaya iskelesi oluşturun. Dosyadaki Identity/Account/Manage/_Layout.cshtml
düzeni tanımlayın.
@{
Layout = "/Pages/Shared/_Layout.cshtml";
}
Ayrıca, sayfalardan tüm yönetme sayfaları için düzeni atayın Identity :
@{
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. yönteminde OnGet
, identity kullanıcı taleplerine erişmek için kullanılır. Talep amr
değeri mfa
için denetlendi. identity bu talep eksikse veya isefalse
, sayfa MFA'yı 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, değerine mfa
sahip talebi gerektiriramr
.
services.AddAuthorization(options =>
options.AddPolicy("TwoFactorEnabled",
x => x.RequireClaim("amr", "mfa")));
Bu ilke daha sonra görünümde _Layout
yö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
identity 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
parametresi değeriyle mfa
ayarlanır ve 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
Pages ile Razor ASP.NET Core Identity kullanılarak uygulanan OpenID Connect sunucusunda adlı ErrorEnable2FA.cshtml
yeni bir sayfa oluşturulur. Görünüm:
- , Identity MFA gerektiren ancak kullanıcı tarafından içinde Identityetkinleştirilmemiş bir uygulamadan geliyorsa 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 Login
IIdentityServerInteractionService
, 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 set ile mfa
gönderdiğinde, bu daha sonra denetlenebilir.
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.cshtml
yö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
, talebi kullanacak amr
ve değerini mfa
denetleyecek şekilde 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ği doğrulanmış ve identity OpenID Connect sunucu uygulamasına bağlıdır.
gereksinimini AuthorizationHandler
RequireMfa
kullanır ve talebi doğrular amr
. 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. Talebi denetlemek amr
için kullanılan yetkilendirme işleyicisi, Inversion of Control kapsayıcısına eklenir. Ardından gereksinimi ekleyen RequireMfa
bir ilke 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 daha sonra sayfada gerektiği gibi kullanılır Razor . İ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şme yetkisine sahip olmayacaktı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ğerepwd
sahiptir:Erişim reddedildi:
Alternatif olarak, ile IdentityOTP kullanarak 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, 2FA
MFA, bildiğiniz, sahip olduğunuz bir şey veya kullanıcının kimlik doğrulaması için biyometrik doğrulama gibi bir identity şey 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 kanıtlaması identityiçin iki veya daha fazla faktör gerektirebilir.
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 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.
MFA SMS
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 ve Razor Sayfaları ile Identity ASP.NET Core kullanılarak ayarlanır. AddIdentity
yöntemi bir yerine AddDefaultIdentity
kullanılır, bu nedenle başarılı bir oturum açmadan sonra öğesine talep eklemek için identity bir IUserClaimsPrincipalFactory
uygulama kullanılabilir.
Uyarı
Bu makalede bağlantı dizesi kullanımı gösterilmektedir. Yerel bir veritabanıyla kullanıcının kimliğinin doğrulanması gerekmez, ancak üretimde bağlantı dizesi bazen kimlik doğrulaması için bir parola içerir. Kaynak sahibi parola kimlik bilgileri (ROPC), üretim veritabanları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 bkz . Güvenli kimlik doğrulama akışları.
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();
}
sınıfı, AdditionalUserClaimsPrincipalFactory
talebi yalnızca başarılı bir oturum açma sonrasında kullanıcı taleplerine ekler amr
. Talebin değeri veritabanından okunur. Talep buraya eklenir çünkü kullanıcının yalnızca MFA ile oturum açmışsa daha yüksek korumalı görünüme identity 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 sınıfında değiştiğindenStartup
, düzenlerinin Identity güncelleştirilmiş olması gerekir. Identity Sayfaları uygulamaya iskelesi oluşturun. Dosyadaki Identity/Account/Manage/_Layout.cshtml
düzeni tanımlayın.
@{
Layout = "/Pages/Shared/_Layout.cshtml";
}
Ayrıca, sayfalardan tüm yönetme sayfaları için düzeni atayın Identity :
@{
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. yönteminde OnGet
, identity kullanıcı taleplerine erişmek için kullanılır. Talep amr
değeri mfa
için denetlendi. identity bu talep eksikse veya isefalse
, sayfa MFA'yı 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, değerine mfa
sahip talebi gerektiriramr
.
builder.Services.AddAuthorization(options =>
options.AddPolicy("TwoFactorEnabled",
x => x.RequireClaim("amr", "mfa")));
Bu ilke daha sonra görünümde _Layout
yö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
identity 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
parametresi değeriyle mfa
ayarlanır ve 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:
- , Identity MFA gerektiren ancak kullanıcı tarafından içinde Identityetkinleştirilmemiş bir uygulamadan geliyorsa 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 Login
IIdentityServerInteractionService
, 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 set ile mfa
gönderdiğinde, bu daha sonra denetlenebilir.
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.cshtml
yö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 değer için denetlendimfa
. mfa
Değer varsa, oturum açma tamamlanmadan önce MFA zorlanır (örneğin, görünüme ErrorEnable2FA
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
, talebi kullanacak amr
ve değerini mfa
denetleyecek şekilde 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ği doğrulanmış ve identity OpenID Connect sunucu uygulamasına bağlıdır.
gereksinimini AuthorizationHandler
RequireMfa
kullanır ve talebi doğrular amr
. 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;
}
}
yönteminde Startup.ConfigureServices
AddOpenIdConnect
, yöntemi varsayılan sınama şeması olarak kullanılır. Talebi denetlemek amr
için kullanılan yetkilendirme işleyicisi, Inversion of Control kapsayıcısına eklenir. Ardından gereksinimi ekleyen RequireMfa
bir ilke 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 daha sonra sayfada gerektiği gibi kullanılır Razor . İ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şme yetkisine sahip olmayacaktı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ğerepwd
sahiptir:Erişim reddedildi:
Alternatif olarak, ile IdentityOTP kullanarak oturum açma:
Ek kaynaklar
ASP.NET Core