了解Blazor和ASP.NET Core中的身份验证

目录

介绍

什么是身份验证?

什么是Blazor?

建立环境

添加身份验证

创建登录页面

指定无法访问其他页面

ASP.NET Core中的身份验证操作机制是什么?

ASP.NET如何辨别身份验证的必要性?

那么,如何配置身份验证呢?

完成身份验证过程

如何登录 ?

如何注销?


介绍

身份验证是每个应用程序中的首要考虑因素。因此,ASP.NET Cor本身就提供了简化这一过程的机制,使我们能够根据我们的特定需求和要求进行定制。

遗憾的是,在整个开发生命周期中,利益相关者经常低估这一关键流程,这主要是因为开发人员倾向于优先考虑业务需求并努力满足需求。此外,关于这一主题的文档往往是零散的,或者狭隘地集中在特定需求上。因此,在本系列中,我们的目标是全面概述ASP.NET身份验证,并对其复杂性和重要性提供连贯的理解。

随后的教科书被证明对结束这个系列很有用。

Blazor在行动(Sainty)

Pro ASP.NET Core Identity(Freeman)

ASP.NET Core in Action(Lock)

这篇文章最初发布在这里:了解 Blazor和ASP.NET Core中的身份验证

什么是身份验证?

身份验证是验证尝试访问资源或服务的用户或系统的身份的过程。它确保请求访问的实体是他们声称的实体。此验证通常涉及提供凭据(如用户名和密码),并根据安全存储的一组已知凭据进行验证。身份验证机制通过确保只有授权用户才能访问受保护的资源来帮助保护系统并保护敏感信息。

我们将避免深入研究这个话题,因为读者已经熟悉它的细节。

什么是Blazor?

Blazor是使用C#和.NET生成交互式Web应用程序的框架。它允许开发人员完全用C#创建Web应用程序,而无需依赖JavaScript来实现客户端功能(如React或Angular)。再一次,我们将避免进一步阐述这个主题,并鼓励读者探索专门的书籍或博客,以获得更高级的概念。

信息
坦率地说,我们不是Blazor专家。我们在这里的重点只是探索此框架提供的身份验证功能。

建立环境

现在,我们将继续在Visual Studio 2022 IDE中配置标准Blazor环境。这个基本应用程序将作为我们逐步阐明基本概念的基础。

  • 创建名为EOCS的新解决方案。例如,BlazorAuthentication 以及其中一个名为EOCS的新Blazor Web App项目。BlazorAuthentication.Main

  • 添加信息时,请确保选择“None”作为身份验证类型,选择“服务器”作为交互式渲染模式,并选中“包括示例页面”。

  • 运行程序并验证是否可以访问所有路由,而无需进行身份验证。

信息
在本系列中,我们将使用.NET Framework的.NET 8版本。

我们现在的目标是演示如何将身份验证无缝集成到此应用程序中,确保只有经过身份验证的用户才能访问其各个页面。

添加身份验证

合并身份验证需要创建一个登录页面,用户可以在其中通过提供凭据来验证其身份。此外,它还涉及指定除非验证提供的凭据正确,否则无法访问其他页面。让我们详细探讨这两个方面。

创建登录页面

  • 将名为Login.razor 的新Razor组件添加到应用程序,并在其中添加以下代码。
@page "/login"

<h3>Login</h3>

<form action="" method="post">
    <button type="submit" class="btn btn-primary">Login</button>
</form>
  • 运行程序。

我们可以很容易地观察到一个新页面已经无缝集成到我们的应用程序中,可以通过/login URL访问。

指定无法访问其他页面

到目前为止,所有现有路线仍可公开访问。我们现在将实施访问限制,以确保只有经过身份验证的用户才能查看我们的页面。

  • 打开Routes.razor 文件,向其添加[Authorize]属性,然后使用以下代码编辑内容。
@inject NavigationManager navigationManager

<Router AppAssembly="@typeof(Program).Assembly">
    <Found Context="routeData">
        <AuthorizeRouteView RouteData="@routeData" DefaultLayout="@typeof(Layout.MainLayout)">
            <NotAuthorized>
                @{
                    navigationManager.NavigateTo("/login", true);
                }
            </NotAuthorized>
        </AuthorizeRouteView>        
        <FocusOnNavigate RouteData="@routeData" Selector="h1" />
    </Found>
    <NotFound>
        @{
            navigationManager.NavigateTo("/login", true);
        }
    </NotFound>
</Router>

信息
在以前版本的框架中,可能需要调整上述配置,尤其是在Routes.razor文件不存在的情况下。

建立此设置后,必须使用Authorize属性对每个需要身份验证的文件进行批注。

@page "/"
@attribute [Authorize]

<PageTitle>Home</PageTitle>

<h1>Hello, world!</h1>

Welcome to your new app.

信息
若要确保可识别Authorize属性,请验证是否在_Imports.razor文件中导入了正确的命名空间。

@using Microsoft.AspNetCore.Authorization
@using Microsoft.AspNetCore.Components.Authorization

此代码中有几个值得注意的方面值得注意:

  • 只有经过身份验证的用户才能访问的文件必须使用[Authorize]属性进行全局修饰。它表示默认情况下,身份验证处于启用状态,并且必须在加载页面时进行验证。
  • 我们在Routes.cs 类中使用AuthorizeRouteView组件来定义请求页面时的行为:在我们的方案中,任何未经身份验证的用户都应重定向到登录页面,而经过身份验证的用户将被定向到请求的页面。
  • 值得注意的是,如果恶意用户尝试访问确实存在的URL,他们也会被重定向到登录页面。

但是,在运行程序时,会发生错误。是什么原因导致了这种差异?

实际上,我们尚未通知Blazor必须在应用程序中使用身份验证功能。

重要
我们必须承认,Microsoft在框架的每个新版本中修改ASP.NET应用程序的配置设置,这确实非常乏味。难道他们保持稳定的Program.cs和Startup.cs类不可行吗?

在本文中,我们依赖于.NET 8。

ASP.NET Core中的身份验证操作机制是什么?

不可否认,ASP.NET Core或Blazor中的身份验证是一个复杂的主题,我们的目标是以最易于理解的方式呈现它。此外,请务必注意,根据解决方案启动时选择的配置,可能会出现某些差异。

ASP.NET如何辨别身份验证的必要性?

答案相当简单:我们通过使用[Authorize]属性装饰页面来指定需要身份验证的页面,并在Routes.cs 类中指示应使用AuthorizeRouteView标记对某些路由进行身份验证。

@page "/"
@attribute [Authorize]

<PageTitle>Home</PageTitle>

<h1>Hello, world!</h1>

Welcome to your new app.

<Router AppAssembly="@typeof(Program).Assembly">
    <Found Context="routeData">
        <AuthorizeRouteView RouteData="@routeData" DefaultLayout="@typeof(Layout.MainLayout)">
            <NotAuthorized>
                @{
                    navigationManager.NavigateTo("/login", true);
                }
            </NotAuthorized>
        </AuthorizeRouteView>        
        <FocusOnNavigate RouteData="@routeData" Selector="h1" />
    </Found>
    <NotFound>
        @{
            navigationManager.NavigateTo("/login", true);
        }
    </NotFound>
</Router>

这些配置将指示ASP.NET采用一种机制,通过身份验证过程验证当前用户的身份。但是,它选择哪种工艺呢?有许多可能性:可以使用cookie、JWT令牌、SAML协议或其他方法对用户进行身份验证。再一次,答案相当简单:ASP.NET选择我们配置的方法!

那么,如何配置身份验证呢?

重要
提示:ASP.NET Core中的身份验证过程在Microsoft术语中称为身份验证方案。

因此,我们需要定义一个或多个身份验证方案(为用户提供多个登录选项是完全可以接受的)。好消息是,Microsoft已经提供了本机方案,并简化了自定义方案的开发。

例如,在这里,我们将应用程序配置为当用户浏览器中存在名为“Auth”的cookie时需要身份验证。如果此cooki不存在,则用户将被重定向到登录页面。我们不需要编写复杂或复杂的代码来获取和解密cookie ASP.NET因为Core本身提供了此功能。

C#中的等效代码如下(将其添加到Program.cs文件中)。

public static void Main(string[] args)
{
    // ...

    // Add authentication options
    builder.Services.AddAuthentication("Auth")
        .AddCookie("Auth", options =>
        {            
            options.ExpireTimeSpan = TimeSpan.FromMinutes(20);
            options.SlidingExpiration = true;
            options.LoginPath = "/login";
        });
    builder.Services.AddCascadingAuthenticationState();

    // ...

    app.UseAuthentication();
    app.UseAuthorization();
    
    app.UseStaticFiles();
    app.UseAntiforgery();

    app.MapRazorComponents<App>().AddInteractiveServerRenderMode();

    app.Run();
}

请注意,在此代码片段中,如何:

  • 我们根据cookie定义一个名为“Auth”的身份验证方案
  • 我们将其指定为默认身份验证方案

以这种方式配置,ASP.NET引擎可以理解身份验证是必需的,并且可以使用浏览器中的cookie执行身份验证。

当然,在这个阶段,我们会被重定向到登录页面,因为cookie不存在。现在,我们需要建立一种方法来创建它。

完成身份验证过程

如何登录 ?

在这里,我们将构建一个过于简化的登录页面来验证用户身份。在实际场景中,我们需要从数据存储中检索数据以验证凭据的准确性。但是,出于说明目的,我们将直接创建必要的cookie,而无需执行任何验证。

登录按钮会触发POST方法,因此我们将创建一个控制器来响应此请求并在其中生成所需的cookie。

  • 在项目中添加一个新文件夹,将其命名为Authentication,并在其中添加一个名为AuthController 的控制器。

  • 在AuthController.cs中添加以下代码。
public class AuthController : Controller
{
    [HttpPost]
    [AllowAnonymous]
    public async Task<IActionResult> CookieLogin()
    {
        // Generate the claims
        var claims = new List<Claim>();
        claims.Add(new Claim(ClaimTypes.Name, "John Patton"));
        claims.Add(new Claim(ClaimTypes.Role, "Contributor"));

        var principal = new ClaimsPrincipal(new ClaimsIdentity(claims, "Auth"));

        await HttpContext.SignInAsync("Auth", principal).ConfigureAwait(false);
        
        return Redirect("/");
    }
}

信息
HttpContext的SignInAsync方法是一种本机方法,它允许我们登录默认身份验证方案的主体。

在我们的例子中,由于身份验证方案依赖于cookie,因此此方法将为我们处理cookie的创建,同时考虑加密、过期等底层代码。

  • 编辑Login.razor 类。
@page "/login"

<form action="Auth/CookieLogin" method="post">
    <button type="submit" class="btn btn-primary">Login</button>
</form>
  • 同时编辑 Program.cs 类。
public static void Main(string[] args)
{
    var builder = WebApplication.CreateBuilder(args);

    // Add services to the container.
    builder.Services.AddControllersWithViews();
    builder.Services.AddRazorComponents().AddInteractiveServerComponents();

    // Add authentication options
    builder.Services.AddAuthentication("Auth")
        .AddCookie("Auth", options =>
        {
            
            options.ExpireTimeSpan = TimeSpan.FromMinutes(20);
            options.SlidingExpiration = true;
            options.LoginPath = "/login";
        });
    builder.Services.AddCascadingAuthenticationState();

    var app = builder.Build();

    // Configure the HTTP request pipeline.
    if (!app.Environment.IsDevelopment())
    {
        app.UseExceptionHandler("/Error");
        // The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
        app.UseHsts();
    }

    app.UseRouting();

    app.UseAuthentication();
    app.UseAuthorization();

    app.UseStaticFiles();
    app.UseAntiforgery();

    app.MapRazorComponents<App>().AddInteractiveServerRenderMode();
    app.UseEndpoints(endpoints =>
    {
        endpoints.MapControllerRoute("default", "{controller}/{action}");
    });

    app.Run();
}

现在,当我们单击“登录”时,会生成一个cookie,我们可以在应用程序中导航。

如何注销?

同样,我们可以通过调用HttpContext的SignOutAsync方法来实现注销过程。

public class AuthController : Controller
{
    [HttpPost]
    [AllowAnonymous]
    public async Task<IActionResult> CookieLogin()
    {
        //...
    }
    
    [HttpPost]
    public async Task<IActionResult> CookieLogout()
    {
        await HttpContext.SignOutAsync("Auth").ConfigureAwait(false);
        
        return Redirect("/login");
    }
}

这里介绍的逻辑相当基本,现在我们将深入研究一个更复杂的主题,即基于SAML协议的身份验证。但为了避免本文过载,对此实现感兴趣的读者可以在此处找到续篇。

https://www.codeproject.com/Articles/5381231/Understanding-authentication-in-Blazor-and-ASP-NET

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值