您的位置:首页 > 编程语言 > ASP

ASP.NET Core 使用Cookie验证身份

2017-08-26 08:28 666 查看
ASP.NET Core 1.x提供了通过Cookie 中间件将用户主体序列化为一个加密的Cookie,然后在后续请求中验证Cookie并重新创建主体,并将其分配给
HttpContext.User
属性。如果您要提供自己的登录界面和用户数据库,可以使用作为独立功能的Cookie中间件。
ASP.NET Core 2.x的一个主要变化是不再存在Cookie中间件。取而代之的是在Startup.cs文件中的
Configure
方法中的调用
UseAuthentication
方法会添加设置
HttpContext.User
属性的 AuthenticationMiddleware 中间件。

添加配置

ASP.NET Core 1.x

按下列步骤操作:
在您的项目中安装
Microsoft.AspNetCore.Authentication.Cookies
NuGet包。此包包含Cookie中间件。

在Startup.cs文件中的
Configure
方法中添加下面的行,在
app.UseMvc()
语句之前:
   app.UseCookieAuthentication(new CookieAuthenticationOptions()
   {
       AccessDeniedPath = "/Account/Forbidden/",
       AuthenticationScheme = "MyCookieAuthenticationScheme",
       AutomaticAuthenticate = true,
       AutomaticChallenge = true,
       LoginPath = "/Account/Unauthorized/"
   });


ASP.NET Core 2.x

按下列步骤操作:
如果不使用
Microsoft.AspNetCore.All
 元包,则在您的项目中安装2.0版的
Microsoft.AspNetCore.Authentication.Cookies
NuGet包。

在Startup.cs文件中的
Configure
方法中调用
UseAuthentication
方法:
   app.UseAuthentication();


在Startup.cs文件中的
ConfigureServices
方法中调用
AddAuthentication
AddCookie
方法:
   services.AddAuthentication("MyCookieAuthenticationScheme")
           .AddCookie("MyCookieAuthenticationScheme", options => {
               options.AccessDeniedPath = "/Account/Forbidden/";
               options.LoginPath = "/Account/Unauthorized/";
           });


上面的代码片段配置了以下部分或全部选项:
AccessDeniedPath
 - 当用户尝试访问资源但没有通过任何授权策略时,这是请求会重定向的相对路径资源。

AuthenticationScheme
 - 这是一个已知的特定Cookie认证方案的值。当有多个Cookie验证实例,并且您想限制对一个实例的授权时,这就非常有用。

AutomaticAuthenticate
 - 此标识仅适用于ASP.NET Core 1.x。它表示Cookie身份验证应在每个请求上运行,并尝试验证和重建序列化主体。

AutomaticChallenge
 - 此标识仅适用于ASP.NET Core 1.x。这表示当授权失败时,1.x Cookie认证应将浏览器重定向到
LoginPath
AccessDeniedPath


LoginPath
 - 当用户尝试访问资源但尚未认证时,这是请求重定向的相对路径。

其它选项包括为Cookie认证创建的设置选项,身份验证的Cookie的名称,Cookie的域和Cookie各种安全属性。默认情况下,Cookie身份验证为其创建的任何Cookie使用适当的安全选项,例如:
设置HttpOnly标志以防止客户端JavaScript中访问Cookie

如果请求是通过HTTPS访问,则将Cookie限制为HTTPS

创建身份认证Cookie

要创建一个保存用户信息的cookie,您必须构建一个ClaimsPrincipal 保存您希望序列化到Cookie中的信息。

ASP.NET Core 1.x

   await HttpContext.Authentication.SignInAsync("MyCookieAuthenticationScheme", principal);

ASP.NET Core 2.x

   await HttpContext.SignInAsync("MyCookieAuthenticationScheme", principal);

这将创建一个加密的Cookie并将其添加到当前响应中。在调用
SignInAsync
时,必须在配置中指定的
AuthenticationScheme

顺便提一下,使用的加密方式是ASP.NET Core的Data Protection系统。如果您在多台机器上进行托管、负载平衡或使用Web集群,则需要配置Data Protection才能使用相同的密钥和应用程序标识符。

Signing out(登出)

要退出当前用户并删除其Cookie,请在控制器中调用以下方法:

ASP.NET Core 1.x

   await HttpContext.Authentication.SignOutAsync("MyCookieAuthenticationScheme");

ASP.NET Core 2.x

   await HttpContext.SignOutAsync("MyCookieAuthenticationScheme");

服务端变化反馈

警告: 一旦创建了认证的Cookie,它将成为唯一的身份来源。即使您在服务系统中禁用用户,Cookie身份验证也无法了解此信息,只要Cookie有效,用户仍可登录。

Cookie认证在其选项中提供了一系列事件。
ValidateAsync()
事件可用于拦截和重写Cookie身份验证。
可以考虑在后端用户数据库中增加
LastChanged
列。为了在数据库更改时使Cookie无效,您应该首先在创建Cookie时添加一个
LastChanged
包含当前值的声明。数据库更改时,更新
LastChanged
例的值。
要重写
ValidateAsync()
事件的实现,您必须编写一个具有以下签名的方法:
   Task ValidateAsync(CookieValidatePrincipalContext context);

ASP.NET Core Identity 在
SecurityStampValidator
实现了这一逻辑,链接地址。示例如下所示:

ASP.NET Core 1.x

   public static class LastChangedValidator
   {      
     public static async Task ValidateAsync(CookieValidatePrincipalContext context)        {            // Pull database from registered DI services.
         
      var userRepository = context.HttpContext.RequestServices.GetRequiredService<IUserRepository>();            var userPrincipal = context.Principal;    
           // Look for the last changed claim.
           string lastChanged;
           lastChanged = (from c in userPrincipal.Claims                            where c.Type == "LastUpdated"
                           select c.Value).FirstOrDefault();    
           if (string.IsNullOrEmpty(lastChanged) ||
               !userRepository.ValidateLastChanged(userPrincipal, lastChanged))
           {
               context.RejectPrincipal();                await context.HttpContext.Authentication.SignOutAsync("MyCookieAuthenticationScheme");
           }
       }
   }

然后,在Startup.cs文件中的
Configure
方法中将Cokie认证配置进行重写:
   app.UseCookieAuthentication(new CookieAuthenticationOptions
   {
       Events = new CookieAuthenticationEvents
       {
           OnValidatePrincipal = LastChangedValidator.ValidateAsync
       }
   });

ASP.NET Core 2.x

   public static class LastChangedValidator
   {    
      public static async Task ValidateAsync(CookieValidatePrincipalContext context)        {            // Pull database from registered DI services.
         
       var userRepository = context.HttpContext.RequestServices.GetRequiredService<IUserRepository>();          
        var userPrincipal = context.Principal;    
           // Look for the last changed claim.
           string lastChanged;
           lastChanged = (from c in userPrincipal.Claims                            where c.Type == "LastUpdated"
                           select c.Value).FirstOrDefault();    
           if (string.IsNullOrEmpty(lastChanged) ||
               !userRepository.ValidateLastChanged(userPrincipal, lastChanged))
           {
               context.RejectPrincipal();                await context.HttpContext.SignOutAsync("MyCookieAuthenticationScheme");
           }
       }
   }

然后,将在Startup.cs的
ConfigureServices
方法中将Cookie服务注册进行配置:
   services.AddAuthentication("MyCookieAuthenticationScheme")
           .AddCookie(options =>
           {
               options.Events = new CookieAuthenticationEvents
               {
                   OnValidatePrincipal = LastChangedValidator.ValidateAsync
               };
           });

如果要非破坏性地更新用户主体,可以调用
context.ReplacePrincipal()
,并将
context.ShouldRenew
属性设置为
true


Cookie设置选项

CookieAuthenticationOptions类提供了各种配置选项,在创建时调整Cookie的配置。

ASP.NET Core 1.x

ClaimsIssuer
是由中间件创建的任何声明时使用的Issuer属性。

CookieDomain
是提供Cookie的域名。默认情况下,这是发送请求的主机名。浏览器仅将Cookie提供给匹配的主机名。您可能希望对此进行调整,以便您的域中的任何主机都可以使用Cookie。例如,将Cookie域名设置为
.contoso.com
,可以使用Cookie的域名有
contoso.com
www.contoso.com
staging.www.contoso.com
等。

CookieHttpOnly
是一个标识,指定Cookie是否只能由服务器访问。默认为
true
。如果您的应用程序具有Cross-Site Scripting(XSS)的问题,更改此值可能会导致Cookie被盗用。

CookiePath
可用于隔离在相同主机名上运行的应用程序。如果你有一个应用程序在
/app1
中运行,并希望限制发送的Cookie只发送到该应用程序,那么您应该将
CookiePath
属性设置为
/app1
。通过这样做,Cookie只适用于对
/app1
或其下任何内容的请求。

CookieSecure
是一个标识,表示创建的Cookie是否应该被限制为HTTPS,HTTP或HTTPS,或与请求相同的协议。默认为
SameAsRequest


ExpireTimeSpan
TimeSpan
类型,在此时间段之后Cookie将过期。将当前日期加上此时间段为创建Cookie的到期日期。

SlidingExpiration
是一个标识,指示当超过一半的
ExpireTimeSpan
间隔时,Cookie到期日期是否复位。新的到期日是当前时间加上
ExpireTimespan
。调用
SignInAsync
时,可以使用
AuthenticationProperties
类设置绝对到期时间。绝对到期时间可以通过限制认证Cookie有效的时间来提高应用程序的安全性。

在Startup.cs文件中的
Configure
方法中使用
CookieAuthenticationOptions
的例子如下:
   app.UseCookieAuthentication(new CookieAuthenticationOptions
   {
       CookieName = "AuthCookie",
       CookieDomain = "contoso.com",
       CookiePath = "/",
       CookieHttpOnly = true,
       CookieSecure = CookieSecurePolicy.Always
   });

ASP.NET Core 2.x

ASP.NET Core 2.x 统一了用于配置Cookie的API。1.x API已被标记为过时,并且在
CookieAuthenticationOptions
类中引入了一种类型为
CookieBuilder
新的
Cookie
属性。建议您迁移到2.x API。
ClaimsIssuer
是由Cookie认证创建的任何声明时使用的Issuer属性。

CookieBuilder.Domain
是提供Cookie的域名。默认情况下,这是发送请求的主机名。浏览器仅将Cookie提供给匹配的主机名。您可能希望对此进行调整,以便您的域中的任何主机都可以使用Cookie。例如,将Cookie域名设置为
.contoso.com
,可以使用Cookie的域名有
contoso.com
www.contoso.com
staging.www.contoso.com


CookieBuilder.HttpOnly
是一个标识,指定Cookie是否只能由服务器访问。默认为
true
。如果您的应用程序具有Cross-Site Scripting(XSS)的问题,更改此值可能会导致Cookie被盗用。

CookieBuilder.Path
可用于隔离在相同主机名上运行的应用程序。如果你有一个应用程序在
/app1
中运行,并希望限制发送的Cookie只发送到该应用程序,那么您应该将
CookiePath
属性设置为
/app1
。通过这样做,Cookie只适用于对
/app1
或其下任何内容的请求。

CookieBuilder.SameSite
表示浏览器是否允许Cookie被附加到同一站点或跨站点的请求。默认为
SameSiteMode.Lax


CookieBuilder.SecurePolicy
是一个标识,表示创建的Cookie是否应该被限制为HTTPS,HTTP或HTTPS,或与请求相同的协议。默认为
SameAsRequest


ExpireTimeSpan
TimeSpan
类型,在此时间段之后Cookie将过期。将当前日期加上此时间段为创建Cookie的到期日期。

SlidingExpiration
是一个标识,指示当超过一半的
ExpireTimeSpan
间隔时,Cookie到期日期是否复位。新的到期日是当前时间加上
ExpireTimespan
。调用
SignInAsync
时,可以使用
AuthenticationProperties
类设置绝对到期时间。绝对到期时间可以通过限制认证Cookie有效的时间来提高应用程序的安全性。

在Startup.cs的
ConfigureServices
方法中使用
CookieAuthenticationOptions
的例子如下:
   services.AddAuthentication()
       .AddCookie(options =>
       {
           options.Cookie.Name = "AuthCookie";
           options.Cookie.Domain = "contoso.com";
           options.Cookie.Path = "/";
           options.Cookie.HttpOnly = true;
           options.Cookie.SameSite = SameSiteMode.Lax;
           options.Cookie.SecurePolicy = CookieSecurePolicy.Always;
       });

持久Cookie和绝对到期时间

您可能希望Cookie在浏览器会话中持续存在,并希望设置身份和Cookie传输的绝对过期时间。这种持久性应该只能是用户显示同意,在登录时的“记住我”复选框或类似的机制启用。您可以通过在创建身份认证Cookie时调用的
SignInAsync
方法中使用
AuthenticationProperties
参数来执行这些操作。例如:

ASP.NET Core 1.x

   await HttpContext.Authentication.SignInAsync(        "MyCookieAuthenticationScheme",
       principal,      
    new AuthenticationProperties
       {
           IsPersistent = true
       });

上述代码片段中使用的
AuthenticationProperties
类,位于
Microsoft.AspNetCore.Http.Authentication
命名空间中。

ASP.NET Core 2.x

   await HttpContext.SignInAsync(      
     "MyCookieAuthenticationScheme",
       principal,    
        new AuthenticationProperties
       {
           IsPersistent = true
       });

上述代码片段中使用的
AuthenticationProperties
类,位于
Microsoft.AspNetCore.Authentication
命名空间中。
上面的代码段创建一个身份和相应的Cookie,直到浏览器关闭。以前通过Cookie设置选项配置的任何滑动过期设置仍然有效。如果Cookie在浏览器关闭时过期,浏览器会在重新启动后清除它。如果Cookie在浏览器关闭时过期,浏览器会在重新启动后清除它。

ASP.NET Core 1.x

   await HttpContext.Authentication.SignInAsync(        "MyCookieAuthenticationScheme",
       principal,      
    new AuthenticationProperties
       {
           ExpiresUtc = DateTime.UtcNow.AddMinutes(20)
       });

ASP.NET Core 2.x

   await HttpContext.SignInAsync(    
      "MyCookieAuthenticationScheme",
       principal,      
       new AuthenticationProperties
       {
           ExpiresUtc = DateTime.UtcNow.AddMinutes(20)
       });

上述代码段创建一个持续20分钟的身份和相应的cookie。这将忽略以前通过Cookie设置选项配置的任何滑动过期设置。
ExpiresUtc
IsPersistent
属性是互斥的。

原文:《Using Cookie Authentication without ASP.NET Core Identity》https://docs.microsoft.com/en-us/aspnet/core/security/authentication/cookie?tabs=aspnetcore2x
翻译:Sweet Tang
本文地址:<http://www.cnblogs.com/tdfblog/p/aspnet-core-security-authentication-cookie.html >

相关文章: 
.NET Core 2.0 正式发布信息汇总

.NET Standard 2.0 特性介绍和使用指南

.NET Core 2.0 的dll实时更新、https、依赖包变更问题及解决

.NET Core 2.0 特性介绍和使用指南

Entity Framework Core 2.0 新特性

体验 PHP under .NET Core

.NET Core 2.0使用NLog

升级项目到.NET Core 2.0,在Linux上安装Docker,并成功部署

解决Visual Studio For Mac Restore失败的问题

ASP.NET Core 2.0 特性介绍和使用指南

.Net Core下通过Proxy 模式 使用 WCF

.NET Core 2.0 开源Office组件 NPOI

ASP.NET Core Razor页面 vs MVC

Razor Page–Asp.Net Core 2.0新功能  Razor Page介绍

原文地址:http://www.cnblogs.com/inday/p/razor-page-in-asp-net-core-2.html
.NET社区新闻,深度好文,微信中搜索dotNET跨平台或扫描二维码关注

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: