Moderna applikationer går allt mer bort från traditionella lösenord och mot lösenordslösa autentiseringsmetoder som är både säkrare och enklare för användarna. I det här inlägget kommer jag att visa hur man autentiserar användare i en ASP.NET Core-applikation med FoxIDs med OpenID Connect och möjliggör en helt lösenordslös inloggningsupplevelse med en e-postkod.
Vi utgår från en ren FoxIDs miljö, skapar en ny ASP.NET Core-webbapp, ansluter den till OpenID Connect och aktiverar slutligen passwordless-inloggning med e-postbaserad OTP.
Skapa en FoxIDs Dev Environment
Jag började med att skapa en ny tom dev-miljö i FoxIDs. En ren miljö gör det enkelt att ställa in autentisering från början och säkerställer att du kan replikera dessa steg i din egen tenant.
Om du inte har använt FoxIDs tidigare kan du skapa en gratis tenant på:
Varje tenant kommer med två färdiga att använda miljöer så att du kan experimentera fritt.
Konfigurera autentisering
Börja med att konfigurera hur användare ska logga in. I det här fallet vill vi att användare ska logga in utan lösenord, med endast sin e-postadress och ett engångslösenord (OTP) som skickas till dem.
- Välj fliken Autentiseringar i din FoxIDs miljö.
- Klicka på Default — User Login UI.
- I avsnittet Autentisering inaktiverar du Lösenordsautentisering och aktiverar Lösenlös med e-post (engångslösenord).
- Klicka på Uppdatera för att spara ändringarna.
Detta gör det möjligt för användare att skapa ett nytt konto och ger en lösenordslös upplevelse där de autentiseras helt enkelt genom att ange sin e-postadress och OTP de får.
Skapar applikationen ASP.NET Core
Därefter behöver vi en applikation för att autentisera. Du kan använda antingen Visual Studio eller VS Code - allt som stöder standard ASP.NET Core-utveckling.
Läs inlägget "Lösenordslös autentisering i en AI-genererad ASP.NET Core-app med FoxIDs och e-postbaserad OTP" om du vill generera ASP.NET Core-applikationen med en AI-prompt.
För den här genomgången skapar jag en enkel ASP.NET Core Razor Pages-applikation inriktad på .NET 10 i Visual Studio, men samma tillvägagångssätt fungerar för MVC, en Blazor Web App eller något annat ASP.NET Core-projekt.
Kör appen; exempelappen körs lokalt på https://localhost:7283/
Du kan hitta exempelkoden i: https://github.com/ITfoxtec/dotnet.samples/tree/main/WebAppPasswordLessEmail
Konfigurera webbapplikationen i FoxIDs
Nu när vi känner till webbapplikationens lokala adress kan vi registrera den i FoxIDs så att den kan autentisera användare genom OpenID Connect.
- Välj fliken Program i din FoxIDs miljö.
- Välj Ny applikation och välj sedan Webbapplikation — OpenID Connect.
- I Namn anger du ett namn, till exempel: ASP.NET webbapplikation.
- I Redirect URI lägger du till programmets basadress: https://localhost:7283/ Som standard tillåter FoxIDs omdirigering till valfri efterföljande sida under denna bas-URL. Om du föredrar striktare validering kan du kräva absoluta omdirigerings-URI:er.
- Klicka på Skapa.
FoxIDs visar nu anslutningsdetaljerna för din nya applikation, inklusive:
- Authority
- Kund-ID
- Kundhemlighet
Kopiera Authority och klient-ID till projektets IdentitySettings-sektion. Lagra Client Secret i .NET användarhemligheter lokalt eller i en säker miljövariabel eller hemlig butik i produktion.
Konfigurera autentisering i ASP.NET applikationen
Med FoxIDs applikationen skapad är nästa steg att konfigurera autentisering i ASP.NET Core-projektet. Vi kommer att använda cookie-autentisering för den lokala sessionen och OpenID Connect för att kommunicera med FoxIDs.
Öppna Program.cs och lägg till autentiseringskonfigurationen med (builder.Services.AddAuthentication... och app.UseAuthentication()😉:
using Microsoft.AspNetCore.Authentication.Cookies;
using Microsoft.AspNetCore.Authentication.OpenIdConnect;
using Microsoft.IdentityModel.Protocols.OpenIdConnect;
using Microsoft.IdentityModel.Logging;
var builder = WebApplication.CreateBuilder(args);
// Detailed authentication errors can help locally, but must not be enabled in production.
if (builder.Environment.IsDevelopment())
{
IdentityModelEventSource.ShowPII = true;
}
// Add authentication with cookie and OpenID Connect
builder.Services.AddAuthentication(options =>
{
options.DefaultScheme = CookieAuthenticationDefaults.AuthenticationScheme;
options.DefaultChallengeScheme = OpenIdConnectDefaults.AuthenticationScheme;
})
.AddCookie(CookieAuthenticationDefaults.AuthenticationScheme)
.AddOpenIdConnect(OpenIdConnectDefaults.AuthenticationScheme, options =>
{
options.Authority = builder.Configuration["IdentitySettings:Authority"];
options.ClientId = builder.Configuration["IdentitySettings:ClientId"];
options.ClientSecret = builder.Configuration["IdentitySettings:ClientSecret"];
options.ResponseType = OpenIdConnectResponseType.Code;
options.SaveTokens = true;
options.Scope.Add("email");
options.Scope.Add("profile");
options.Scope.Add("offline_access");
options.MapInboundClaims = false;
options.TokenValidationParameters.NameClaimType = "sub";
options.TokenValidationParameters.RoleClaimType = "role";
options.Events = new OpenIdConnectEvents
{
OnTokenValidated = async context =>
{
// Custom claims transformation or other logic can be added here.
await Task.CompletedTask;
},
OnAuthenticationFailed = context =>
{
if (!builder.Environment.IsDevelopment())
{
return Task.CompletedTask;
}
context.HandleResponse();
context.Response.StatusCode = 500;
context.Response.ContentType = "text/plain";
return context.Response.WriteAsync(context.Exception.ToString());
}
};
});
// Add services to the container.
builder.Services.AddRazorPages();
builder.Services.AddControllers();
var app = builder.Build();
// Configure the HTTP request pipeline.
if (!app.Environment.IsDevelopment())
{
app.UseExceptionHandler("/Error");
// The default HSTS value is 30 days.
app.UseHsts();
}
app.UseHttpsRedirection();
app.UseRouting();
app.UseAuthentication();
app.UseAuthorization();
app.MapStaticAssets();
app.MapControllers();
app.MapRazorPages()
.WithStaticAssets();
app.Run();
Lägg till den icke-hemliga FoxIDs anslutningsinformationen till appsettings.json. Håll klienthemligheten utanför källkontroll och ladda den från .NET användarhemligheter under lokal utveckling eller från en säker miljövariabel eller hemlig butik i produktion.
{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft.AspNetCore": "Warning"
}
},
"AllowedHosts": "*",
"IdentitySettings": {
"Authority": "https://foxids.com/{tenant}/{environment}/{application}/",
"ClientId": "your-client-id"
}
}
Lagra klientens hemlighet lokalt utan att skriva den till appsettings.json:
dotnet user-secrets init
dotnet user-secrets set "IdentitySettings:ClientSecret" "your-client-secret"
Ersätt exempelvärdena med Authority, klient-ID och klienthemlighet från din egen FoxIDs miljö. Begå aldrig den verkliga hemligheten.
Visa claims på huvudsidan
För detta exempel, visa claims på huvudsidan. Öppna Index.cshtml ändra innehållet:
@page
@model IndexModel
@{
ViewData["Title"] = "Home page";
}
@if (User.Identity?.IsAuthenticated == true)
{
<h2 class="mt-4">Claims</h2>
<table class="table table-striped table-bordered">
<thead>
<tr>
<th>Type</th>
<th>Value</th>
</tr>
</thead>
<tbody>
@foreach (var claim in User.Claims)
{
<tr>
<td>@claim.Type</td>
<td>@claim.Value</td>
</tr>
}
</tbody>
</table>
}
else
{
<p class="mt-4 text-muted">Not signed in.</p>
}
Lägg till en inloggningsmeny till applikationen
För att låta användare logga in lägger vi till en delvy för inloggnings- och utloggningskontroller.
Skapa en ny fil:Pages/Shared/_LoginPartial.cshtml med innehållet:
@if (User.Identity?.IsAuthenticated == true)
{
<ul class="navbar-nav">
<li class="nav-item">
<form class="form-inline" asp-controller="Auth" asp-action="Logout" method="post">
@Html.AntiForgeryToken()
<button type="submit" class="nav-link btn btn-link text-dark">Log off</button>
</form>
</li>
</ul>
}
else
{
<ul class="navbar-nav navbar-right">
<li class="nav-item">
<a class="nav-link text-dark" asp-controller="Auth" asp-action="Login">Log in</a>
</li>
</ul>
}
Inkludera sedan inloggningsdelen i navigeringsmenyn. I Pages/Shared/_Layout.cshtml lägg till det partiella inloggningselementet i slutet av navigeringsfältet:
<div class="navbar-collapse collapse d-sm-inline-flex justify-content-between">
<ul class="navbar-nav flex-grow-1">
<li class="nav-item">
<a class="nav-link text-dark" asp-area="" asp-page="/Index">Home</a>
</li>
<li class="nav-item">
<a class="nav-link text-dark" asp-area="" asp-page="/Privacy">Privacy</a>
</li>
</ul>
<partial name="_LoginPartial" />
</div>
Lägg sedan till en målsida för inloggnings- och utloggningsförfrågningar. Skapa en Controller-mapp och skapa en ny controller-fil i mappen: Controllers/AuthController.cs med innehållet:
using Microsoft.AspNetCore.Authentication;
using Microsoft.AspNetCore.Authentication.Cookies;
using Microsoft.AspNetCore.Authentication.OpenIdConnect;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
namespace WebAppPasswordLessEmail.Controllers
{
[AllowAnonymous]
[Route("[controller]/[action]")]
public class AuthController : Controller
{
[HttpGet]
public IActionResult Login()
{
var redirectUri = Url.Content("~/");
if (User.Identity?.IsAuthenticated == true)
{
return LocalRedirect(redirectUri);
}
return Challenge(new AuthenticationProperties { RedirectUri = redirectUri },
OpenIdConnectDefaults.AuthenticationScheme);
}
[HttpPost]
[ValidateAntiForgeryToken]
public IActionResult Logout()
{
var redirectUri = Url.Content("~/");
if (User.Identity?.IsAuthenticated != true)
{
return LocalRedirect(redirectUri);
}
return SignOut(new AuthenticationProperties { RedirectUri = redirectUri },
CookieAuthenticationDefaults.AuthenticationScheme, OpenIdConnectDefaults.AuthenticationScheme);
}
}
}
Kör och ladda om programmet och du kommer nu att se ett Logga in-alternativ i toppmenyn.
Logga in
Klicka på Logga in och du omdirigeras till FoxIDs inloggningsskärmen.
Välj Skapa användare.
Fyll i formuläret Skapa användare med din e-post (eller ett testmeddelande som du har tillgång till), förnamn och efternamn och klicka sedan på Skapa.
Ange engångslösenordet (OTP) som du fick via e-post och klicka sedan på Logga in.
Du är inloggad och din testanvändares claims visas.
Försök sedan att logga ut och logga in igen för att uppleva det lösenordslösa inloggningsflödet med e-post OTP.