AspNetAuthenticationWorkshop

2025-12-07 0 861

ASP.NET核心身份验证实验室

https://g*ithu*b.*com/dotnet-presentations

这是针对针对ASP.NET Core 2.1和VS2017/VS代码的ASP.NET Core Authentication Lab进行的。

该实验室使用模型视图控制器模板,因为这是每个人到现在一直在使用的,这是绝大多数人的最熟悉的起点。

官方身份验证文档在https://docs.m*i**crosoft.com/en-us/aspnet/core/security/authentication/。

授权实验室可从https://*git*hu*b.com/blowdart/aspnetauthorizationworkshop/tree/core2

步骤0:准备

先决条件

  • Visual Studio 2017(社区版是免费的)或
  • Visual Studio代码(免费代码)和
  • .NET Core 2.1 SDK。

创建一个新的空白项目。

我们将从命令行开始。

  • 在某个地方的计算机上创建一个目录,称其为AuthenticationLab
  • 打开命令行/外壳,然后更改为您创建的目录
  • 在命令行类型dotnet new console
  • 完成类型的dotnet run后,您将看到“ Hello World”

让我们检查一下创建的内容。该目录包含两个文件

  • authenticationlab.csproj
  • Program.cs

类型code . VS代码将打开目录。它可能会安装一些缺少的东西。探索两个文件。

  • CS Proj文件是项目文件,它包含有关如何构建项目以及应包括的指令
  • program.cs包含输出“ Hello World”的说明。

让我们将其转变为Web应用程序。 .NET Core是核心库和运行时。 ASP.NET Core增加了对Web应用程序的支持,包括Kestrel A Web服务器。

首先,让我们在应用程序中添加ASP.NET核心。

  • 编辑csproj文件并在关闭PropertyGroup元素之后添加以下内容
  < ItemGroup >
    < PackageReference Include = \" Microsoft.AspNetCore.All \" Version = \" 2.1 \" />
  </ ItemGroup >
  • 您的csproj现在应该看起来像这样
< Project Sdk = \" Microsoft.NET.Sdk \" >

  < PropertyGroup >
    < OutputType >Exe</ OutputType >
    < TargetFramework >netcoreapp2.1</ TargetFramework >
  </ PropertyGroup >

  < ItemGroup >
    < PackageReference Include = \" Microsoft.AspNetCore.All \" Version = \" 2.1 \" />
  </ ItemGroup >

</ Project >
  • 保存csproj文件。如果您使用的是Visual Studio或VS代码,则可能会提示还原软件包,请选择“是”。如果您使用的是命令行和编辑器,该编辑器会使您重新考虑诸如vim Enter dotnet restore在命令行中)的生活选择。不,我无法帮助您退出VIM。
  • 现在,将编辑器切换到program.cs文件。更改此文件的内容如下
 using System ;
using Microsoft . AspNetCore ;
using Microsoft . AspNetCore . Hosting ;

namespace authenticationlab
{
    class Program
    {
        public static void Main ( string [ ] args )
        {
            CreateWebHostBuilder ( args ) . Build ( ) . Run ( ) ;
        }

        public static IWebHostBuilder CreateWebHostBuilder ( string [ ] args ) =>
            WebHost . CreateDefaultBuilder ( args )
                . UseStartup < Startup > ( ) ;
    }
}
  • 请注意, .UseStartup<Startup>()时间糟糕,它正在寻找一个名为startup类。因此,让我们补充一点;创建一个名为startup.cs的新文件,然后将以下文件粘贴到其中
 using System ;
using Microsoft . AspNetCore . Builder ;
using Microsoft . AspNetCore . Hosting ;
using Microsoft . AspNetCore . Http ;
using Microsoft . Extensions . DependencyInjection ;

namespace authenticationlab
{
    public class Startup
    {
        public void ConfigureServices ( IServiceCollection services )
        {
        }

        public void Configure ( IApplicationBuilder app , IHostingEnvironment env )
        {
            app . Run ( async ( context ) =>
            {
                await context . Response . WriteAsync ( \"Hello World!\" ) ;
            } ) ;
        }
    }
}
  • 使用您的IDE dotnet build构建应用程序
  • 使用您的IDE或使用dotnet run运行应用程序
  • 打开浏览器和浏览器http:// localhost:5000/
  • 惊讶地看到Hello World!
  • 恭喜您在.NET Core中具有Web应用程序。

步骤1:设置身份验证

对于此实验室,我们将设置一个使用Google登录的应用程序。

首先,我们需要配置HTTPS。

  • 检查您的命令行中是否有开发人员证书运行dotnet dev-certs https -c -v 。如果您有证书,则会看到“找到有效的证书”。

  • 如果没有证书是基金运行dotnet dev-certs https --trust 。您会看到Windows的弹出窗口询问您是否想信任localhost的证书。单击是,您现在将拥有证书。如果您使用Linux Trust不会在证书生成时间工作,则必须在使用的任何浏览器中信任它。如果您使用的是Firefox,则还必须在浏览器中信任它,因为Firefox不符合OS证书设置。

  • 再次运行您的应用程序,但是这次浏览器访问https:// localhost:5001,您应该能够通过HTTPS连接。

  • 您可以通过添加app.UseHttpsRedirection();在您的Configure()方法的开头。

  • 接下来,我们将使用Google创建一个应用程序,以支持Google登录

  • 导航到https://developers.*go**ogle.com/identity/sign-in/web/sign-in,然后单击Configure A Project按钮。创建一个称为coreeytenticationlab的新项目。

  • 在配置您的OAuth客户端Web Server上,从Where are you calling from?下拉并输入https:// localhost:5001/signin-google作为授权重定向的URI。

  • 单击Create

  • 从结果屏幕上记下您的客户端ID和客户端秘密,然后单击API控制台链接。

  • 单击Enable APIs and services按钮,然后在搜索框中输入Google+ API ,然后选择它。单击Enable

  • 导航到https://console.deve*lopers.g**oogle.com/apis/dashboard,在屏幕顶部的下拉

  • 返回您的代码,然后用以下代码替换startup.cs ,将客户ID和秘密放在选项属性中。

 using System ;
using System . Collections . Generic ;
using System . Linq ;
using System . Threading . Tasks ;
using Microsoft . AspNetCore . Authentication ;
using Microsoft . AspNetCore . Authentication . Cookies ;
using Microsoft . AspNetCore . Authentication . Google ;
using Microsoft . AspNetCore . Builder ;
using Microsoft . AspNetCore . Hosting ;
using Microsoft . AspNetCore . Http ;
using Microsoft . Extensions . DependencyInjection ;

namespace authenticationlab
{
    public class Startup
    {
        public void ConfigureServices ( IServiceCollection services )
        {
            services
                . AddAuthentication ( options =>
                {
                    options . DefaultAuthenticateScheme = CookieAuthenticationDefaults . AuthenticationScheme ;
                    options . DefaultSignInScheme = CookieAuthenticationDefaults . AuthenticationScheme ;
                    options . DefaultChallengeScheme = GoogleDefaults . AuthenticationScheme ;
                } )
                . AddCookie ( )
                . AddGoogle ( options =>
                {
                    options . ClientId = \"**CLIENT ID**\" ;
                    options . ClientSecret = \"**CLIENT SECRET**\" ;
                } ) ;
        }

        public void Configure ( IApplicationBuilder app , IHostingEnvironment env )
        {
            app . UseHttpsRedirection ( ) ;
            app . UseAuthentication ( ) ;
            app . Run ( async ( context ) =>
            {
                if ( ! context . User . Identity . IsAuthenticated )
                {
                    await context . ChallengeAsync ( ) ;
                }
                await context . Response . WriteAsync ( \"Hello \" + context . User . Identity . Name + \"! \\r \" ) ;
            } ) ;
        }
    }
}
  • 运行代码,浏览Google登录屏幕,您应该看到“ Hello YourGoogleUsername !”
  • 如果浏览器确定页面为HTML, WriteAsync样品中有XSS攻击
 context . Response . Headers . Add ( \"Content-Type\" , \"text/plain\" ) ;

步骤2:身份验证事件和记录

  • 让我们添加一些记录以查看发生了什么。
  • Startup类中创建一个名为_loggerILogger类型的私有类级变量。
  • 添加一个构造函数,该构造函数采用ILoggerFactory的参数,并为_logger创建并分配一个记录器。 (您需要添加对Microsoft.Extensions.Logging using引用,如果您的编辑不适合您。)
  • 这应该看起来像以下内容;
        private ILogger _logger ;

        public Startup ( ILoggerFactory loggerFactory )
        {
            _logger = loggerFactory . CreateLogger < Startup > ( ) ;
        }
  • 现在,让我们通过在身份验证启动的事件中添加一些登录方式来查看Google身份验证服务上的事件。
  • 事件是选项类的一部分(您可能需要using Microsoft.AspNetCore.Authentication.OAuth;如果您的编辑器不提示您执行此操作)。
 options . Events = new OAuthEvents ( )
{
    OnRedirectToAuthorizationEndpoint = context =>
    {
        _logger . LogInformation ( \"Redirecting to {0}\" , context . RedirectUri ) ;
       return Task . CompletedTask ;
    } ,
    OnRemoteFailure = context =>
    {
        _logger . LogInformation ( \"Something went horribly wrong.\" ) ;
        return Task . CompletedTask ;
    } ,
    OnTicketReceived = context =>
    {
        _logger . LogInformation ( \"Ticket received.\" ) ;
        return Task . CompletedTask ;
    } ,
    OnCreatingTicket = context =>
    {
        _logger . LogInformation ( \"Creating tickets.\" ) ;
        return Task . CompletedTask ;
    }
} ;
  • 确保您的身份验证cookie已删除(关闭浏览器或手动挖掘),然后再次浏览到网站,然后观看控制台中的登录。
  • 您注意到有什么区别吗?为什么您的用户名不再向您打招呼?
  • 有些事件需要返回的东西。查看事件或来源的文档。
  • 请注意, OnRedirectToAuthorizationEndpoint默认实现将调用重定向 – 这不再在代码中发生,因此请添加回去;
 OnRedirectToAuthorizationEndpoint = context =>
{
    _logger . LogInformation ( \"Redirecting to {0}\" , context . RedirectUri ) ;
    context . Response . Redirect ( context . RedirectUri ) ;
    return Task . CompletedTask ;
} ,
  • 现在,查看OnCreatingTicket()内的上下文属性。其中有一些有用的内容,例如Google Access令牌。如果我想保存该怎么办?
  • 让我们存储访问令牌和刷新令牌Google为我们提供的身份,因为我们正在创建Insern OnCreatingTicket声明。
  • 首先,我们需要索赔的名称,因此在Startup类中定义一些const
 private const string AccessTokenClaim = \"urn:tokens:google:accesstoken\" ;
  • 现在,在OnCreatingTicket事件中,让我们使用这些名称创建一些新的主张,并具有适当的值
 OnCreatingTicket = context =>
{
    var identity = ( ClaimsIdentity ) context . Principal . Identity ;
    identity . AddClaim ( new Claim ( AccessTokenClaim , context . AccessToken ) ) ;
    _logger . LogInformation ( \"Creating tickets.\" ) ;
    return Task . CompletedTask ;
}
  • 最后,要检查他们在问候后持续添加app.Run() lambda中的一些代码;
 var claimsIdentity = ( ClaimsIdentity ) context . User . Identity ;
var accessTokenClaim = claimsIdentity . Claims . FirstOrDefault ( x => x . Type == AccessTokenClaim ) ;

if ( accessTokenClaim != null )
{
    await context . Response . WriteAsync ( \"Google access claims have persisted \\r \" ) ;
}
  • 确保已清除饼干,运行应用程序并浏览。
  • 这有多安全?您能从cookie中弄清楚访问令牌的详细信息是什么?
  • 让我们对Google发送的东西做一些有趣的事情。
  • 返回到Google API仪表板,确保选择您的项目,然后单击“凭据”。
  • 下拉创建凭据下拉并选择API密钥。复制您在安全的地方给出的价值。
  • 用以下内容替换app.Run() lambda,在适当的位置添加您的API键;
 app . UseHttpsRedirection ( ) ;
app . UseAuthentication ( ) ;
app . Run ( async ( context ) =>
{
    if ( ! context . User . Identity . IsAuthenticated )
    {
        await context . ChallengeAsync ( ) ;
    }
    context . Response . Headers . Add ( \"Content-Type\" , \"text/html\" ) ;

    await context . Response . WriteAsync ( \"<html><body> \\r \" ) ;

    var claimsIdentity = ( ClaimsIdentity ) context . User . Identity ;
    var nameIdentifier = claimsIdentity . Claims . FirstOrDefault ( x => x . Type == ClaimTypes . NameIdentifier ) . Value ;
    var googleApiKey = \"**API KEY**\" ;

    if ( ! string . IsNullOrEmpty ( nameIdentifier ) )
    {
        string jsonUrl = $ \"https://www.go*og**leapis.com/plus/v1/people/ { nameIdentifier } ?fields=image&key= { googleApiKey } \" ;
        using ( var httpClient = new HttpClient ( ) )
        {
            var s = await httpClient . GetStringAsync ( jsonUrl ) ;
            dynamic deserializeObject = JsonConvert . DeserializeObject ( s ) ;
            var thumbnailUrl = ( string ) deserializeObject . image . url ;
            if ( thumbnailUrl != null && ! string . IsNullOrWhiteSpace ( thumbnailUrl ) )
            {
                await context . Response . WriteAsync (
                    string . Format ( $ \"<img src= \\\" { thumbnailUrl } \\\" ></img>\" ) ) ;
            }
        }
    }
    await context . Response . WriteAsync ( \"</body></html> \\r \" ) ;
} ) ;
        }
    }
}
  • 重新运行应用程序,并查看您的Google个人资料图像的精彩。

步骤3:方案,动词

  • 这一切如何悬挂在一起?

    • 为什么Google身份验证也需要Cookie身份验证?
    • 什么是计划?
  • 远程身份验证就是这样。偏僻的。没有持续的机制可以重复使用。

  • 持续的身份验证是身份验证,其信息是随着每个请求发送的,例如基本身份验证,摘要身份验证,证书身份验证或基于cookie的令牌。

  • 检查ConfigureServices()中的身份验证配置

 services
    . AddAuthentication ( options =>
    {
        options . DefaultAuthenticateScheme = CookieAuthenticationDefaults . AuthenticationScheme ;
        options . DefaultSignInScheme = CookieAuthenticationDefaults . AuthenticationScheme ;
        options . DefaultChallengeScheme = GoogleDefaults . AuthenticationScheme ;
    } )
  • AuthenticationService配置上有多个Default*选项;
    • DefaultAuthenticatesCheme
    • Defaultchallengescheme
    • Defaultforbidscheme
    • 默认设备
    • DefaultSignInscheme
    • DefaultSignoutscheme
  • 当您拥有多种身份验证类型时,您会使用这些配置设置来决定哪种身份验证类型负责什么
  • 一切都基于计划。一个方案只是一个字符串,您将在配置时提供身份验证提供商。
    • DefaultScheme ,默认值是默认值。除非您覆盖其他事件,否则它提供每个活动处理程序。
    • AuthenticationScheme是在每个请求上运行的提供商,并试图从请求中的信息中构建身份。
    • ChallengeScheme是将应对挑战的提供商,即需要授权时发生的事件,并且请求没有身份。
    • ForbidScheme是处理禁止事件的提供商,当授权发生时会起火,并且当前身份失败了授权检查。
    • DefaultSignInSchemeDefaultSignOutScheme指示提供者将处理SignInSignOut调用。
  • 那么您的应用程序中的配置会做什么?会有所不同吗?

步骤4:配置cookie身份验证

  • 启动您的浏览器,查看已发出的asp.net cookie,\’aspnetcore.cookies\’

  • 饼干包含什么?

  • 饼干的到期是什么?

  • 您认为饼干如何受到保护?

  • 让我们配置那个cookie;首先,让我们在其上设置一个永久到期日期,以便在浏览器上持续关闭

 . AddCookie ( options =>
{
    options . Cookie . Expiration = new System . TimeSpan ( 0 , 15 , 0 ) ;
} )
  • Cookie Builder中还有哪些其他选项?为什么还可以选择期权? (它要走了)
  • 那滑动到期呢?滑动到期在饼干构建器之外;请注意,我们需要从cookie构建器中删除到期时间板
 . AddCookie ( options =>
{
    options . ExpireTimeSpan = new System . TimeSpan ( 0 , 15 , 0 ) ;
    options . SlidingExpiration = true ;
} )
  • 为什么我不能在选项中设置Cookie Builder中的到期? (Cookie Authentication服务有其自己的设置以支持滑动到期,还可以将到期嵌入到Cookie值本身中。为什么它将其嵌入值?)
  • 将cookie从会话cookie更改为持续的cookie后,您现在会注意到您不会再次通过Google身份验证反弹,cookie身份验证是真实的单一来源。那么,如果您从数据库中填充cookie并且值会发生变化,该怎么办?为此,我们举行了OnValidatePrincipal事件。
  • 在您的startup.cs中创建验证器
 private static int RequestCount = 0 ;

public static async Task ValidateAsync ( CookieValidatePrincipalContext context )
{
    if ( context . Request . Path . HasValue && context . Request . Path == \"/\" )
    {
        System . Threading . Interlocked . Increment ( ref RequestCount ) ;
    }

    if ( RequestCount % 5 == 0 )
    {
        context . RejectPrincipal ( ) ;
        await context . HttpContext . SignOutAsync ( CookieAuthenticationDefaults . AuthenticationScheme ) ;
    }
}
  • 每5个请求 /将拒绝当前本金并触发登录。如果您只想更改校长,则可以使用
    context.ReplacePrincipal(newPrincipal);
    context.ShouldRenew = true;
  • 现在,让我们谈谈如何保护饼干,因为该值不是纯文本。
  • ASP.NET Core具有数据保护服务,该服务可创建和旋转整个堆栈中使用的密钥。
  • 数据保护有两个概念,即密钥持久性和关键保护。
 public void ConfigureServices ( IServiceCollection services )
{
    services . AddDataProtection ( )
        . PersistKeysToFileSystem ( new DirectoryInfo ( @\"\\\\server\\share\\directory\\\" ) )
        . ProtectKeysWithCertificate ( \"thumbprint\" ) ;
}
  • 在某些环境中,我们可以自动弄清楚该做什么。检查您的启动日志以查看我们要做什么。
  • Linux和MacOS需要特定的选择。
  • 默认情况下,应用程序获得隔离,共享cookie共享键盘并设置静态应用程序名称
 public void ConfigureServices ( IServiceCollection services )
{
    services . AddDataProtection ( )
        . SetApplicationName ( \"shared app name\" ) ;
}

步骤5:声称转型

  • 索赔转换使您可以添加,删除甚至替换在AuthenticateAsync()中构建的主体。
  • 索赔转换是一项服务,实施了IClaimsTransformation
  • 让我们写一个在身份验证过程中向资源添加索赔的一个,而不必使用特定于身份验证的事件。
 class ClaimsTransformer : IClaimsTransformation
{
   public Task < ClaimsPrincipal > TransformAsync ( ClaimsPrincipal principal )
   {
     ( ( ClaimsIdentity ) principal . Identity ) . AddClaim (
        new Claim ( \"transformedOn\" , DateTime . Now . ToString ( ) ) ) ;
     return Task . FromResult

下载源码

通过命令行克隆项目:

git clone https://github.com/blowdart/AspNetAuthenticationWorkshop.git

收藏 (0) 打赏

感谢您的支持,我会继续努力的!

打开微信/支付宝扫一扫,即可进行扫码打赏哦,分享从这里开始,精彩与您同在
点赞 (0)

申明:本文由第三方发布,内容仅代表作者观点,与本网站无关。对本文以及其中全部或者部分内容的真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。本网发布或转载文章出于传递更多信息之目的,并不意味着赞同其观点或证实其描述,也不代表本网对其真实性负责。

左子网 开发教程 AspNetAuthenticationWorkshop https://www.zuozi.net/31877.html

HL7
上一篇: HL7
HTML5
下一篇: HTML5
常见问题
  • 1、自动:拍下后,点击(下载)链接即可下载;2、手动:拍下后,联系卖家发放即可或者联系官方找开发者发货。
查看详情
  • 1、源码默认交易周期:手动发货商品为1-3天,并且用户付款金额将会进入平台担保直到交易完成或者3-7天即可发放,如遇纠纷无限期延长收款金额直至纠纷解决或者退款!;
查看详情
  • 1、描述:源码描述(含标题)与实际源码不一致的(例:货不对板); 2、演示:有演示站时,与实际源码小于95%一致的(但描述中有”不保证完全一样、有变化的可能性”类似显著声明的除外); 3、发货:不发货可无理由退款; 4、安装:免费提供安装服务的源码但卖家不履行的; 5、收费:价格虚标,额外收取其他费用的(但描述中有显著声明或双方交易前有商定的除外); 6、其他:如质量方面的硬性常规问题BUG等。 注:经核实符合上述任一,均支持退款,但卖家予以积极解决问题则除外。
查看详情
  • 1、左子会对双方交易的过程及交易商品的快照进行永久存档,以确保交易的真实、有效、安全! 2、左子无法对如“永久包更新”、“永久技术支持”等类似交易之后的商家承诺做担保,请买家自行鉴别; 3、在源码同时有网站演示与图片演示,且站演与图演不一致时,默认按图演作为纠纷评判依据(特别声明或有商定除外); 4、在没有”无任何正当退款依据”的前提下,商品写有”一旦售出,概不支持退款”等类似的声明,视为无效声明; 5、在未拍下前,双方在QQ上所商定的交易内容,亦可成为纠纷评判依据(商定与描述冲突时,商定为准); 6、因聊天记录可作为纠纷评判依据,故双方联系时,只与对方在左子上所留的QQ、手机号沟通,以防对方不承认自我承诺。 7、虽然交易产生纠纷的几率很小,但一定要保留如聊天记录、手机短信等这样的重要信息,以防产生纠纷时便于左子介入快速处理。
查看详情

相关文章

猜你喜欢
发表评论
暂无评论
官方客服团队

为您解决烦忧 - 24小时在线 专业服务