标签:let http image 设置 identity 验证方式 类型 源码 param
上两篇(asp.net core 3.x 身份验证-1涉及到的概念、asp.net core 3.x 身份验证-2启动阶段的配置)介绍了身份验证相关概念以及启动阶段的配置,本篇以cookie身份验证为例来大致说明asp.net core中的身份验证原理。如果我们的应用只考虑浏览器使用,且不考虑前后端分离,cookie是最简单的身份验证方式。虽然这样命名,但我们的用户标识并非一定要存到cookie里,asp.net core允许我们存储到任何地方,如:session、自定义基于内存的存储、redis等等。身份验证与asp.net core Identity结合会更简单,它提供了用户管理功能,以及更身份验证相关的辅助类,如:SignManager,不过暂时不将这东东。
还是以宏观上的理解和使用为主。主要涉及如下流程:
其中步骤1、3差别很小。总体流程大致如下图:
先在Startup中做如下配置:
1 public void ConfigureServices(IServiceCollection services) 2 { 3 services.AddAuthentication().AddCookie(); 4 services.AddControllersWithViews(); 5 } 6 7 // This method gets called by the runtime. Use this method to configure the HTTP request pipeline. 8 public void Configure(IApplicationBuilder app, IWebHostEnvironment env) 9 { 10 if (env.IsDevelopment()) 11 { 12 app.UseDeveloperExceptionPage(); 13 } 14 else 15 { 16 app.UseExceptionHandler("/Home/Error"); 17 } 18 app.UseStaticFiles(); 19 20 app.UseRouting(); 21 app.UseAuthentication(); 22 app.UseAuthorization(); 23 24 app.UseEndpoints(endpoints => 25 { 26 endpoints.MapControllerRoute( 27 name: "default", 28 pattern: "{controller=Home}/{action=Index}/{id?}"); 29 }); 30 }
当我们在Startup.Configre中 app.UseAuthentication(); 将注册身份验证中间AuthenticationMiddleware,它负责在请求阶段尝试从请求中获取用户标识,若获取到则赋值给HttpContext.User属性,否则以匿名用户身份继续执行下一个中间件。
流程大致如下:
步骤1中允许AuthenticationHandler在特定情况下终止请求,如果我们将来自定义AuthenticationHandler时实现IAuthenticationRequestHandler可以达到这种目的
步骤3是核心,httpContext.AuthenticateAsync是扩展方法,内部从IOC容器中获取AuthenticationService并调用其同名方法
疑惑:AuthenticationMiddleware始终获取默认身份验证方案然后尝试从请求中获取用户标识,这个默认是通过Startup.ConfigreService中 services.AddAuthentication(默认方案名) 来配置的。但一个系统中可以注册多个身份验证方案(如:同时支持Cookie和JWTBearerToken方式),所以咋处理呢?我目前能想到的是要么纯网站直接用cookie,前后端分离或移动端app默认方案设置为JWTBearerToken;另一种方式再自定义一个AuthenticationMiddleware;但是感觉都很别扭,所以你有好的想法请指教下,不胜感激!
大致执行如下步骤:
步骤2针对Cookie身份验证来说最终体现为CookieAuthenticationHandler.HandleAuthenticateAsync()
步骤3在将用户标识设置到httpContext.User之前允许我们添加修改用户标识的某些数据。实现方式是定义类实现IClaimsTransformation并将其(推荐单例)注册到依赖注入容器。
大致流程如下:
上述步骤多次用到了Options,它是CookieAuthenticationOptions类型的,专门针对基于cookie的身份验证处理器的选项对象,参考:《asp.net core 3.x 身份验证-2启动阶段的配置》,此选项对象的默认赋值行为在PostConfigureCookieAuthenticationOptions.PostConfigre中定义,我们也可以在启动配置时进行定制,
比如我们想直接将票证存储到自定义的存储中时可以参考下面的配置:
在CookieAuthenticationHandler的其它多个步骤中都可能使用到此选项对象。使用方式都类似。
在前一步骤AuthenticationService.AuthenticateAsync的步骤3中允许我们的代码替换/修改用户标识,在这里的步骤4也允许做类似的事,区别在于前者是针对所有身份验证方案有效的,如默认身份验证方案为JwtBeaerToken时也有效。而后者只是针对cookie身份验证有效。
由于首次请求用户尚未登录,所以context.User为空。授权中间件最终会执行 context.ChallengeAsync(); 最终会执行CookieAuthenticationHandler.HandleChallengeAsync
默认大致流程如下:
默认登录页地址"/Account/Login",参考PostConfigureCookieAuthenticationOptions.PostConfigre
默认处理流程如下:
1 public Func<RedirectContext<CookieAuthenticationOptions>, Task> OnRedirectToLogin { get; set; } = context => 2 { 3 if (IsAjaxRequest(context.Request)) 4 { 5 context.Response.Headers[HeaderNames.Location] = context.RedirectUri; 6 context.Response.StatusCode = 401; 7 } 8 else 9 { 10 context.Response.Redirect(context.RedirectUri); 11 } 12 return Task.CompletedTask; 13 };
我们也可以通过在应用启动时通过选项对象来修改。
1 services.AddAuthentication().AddCookie(opt => 2 { 3 opt.LoginPath = "account/mylogin"; 4 opt.Events.OnRedirectToLogin = context => 5 { 6 context.Response.Redirect(context.RedirectUri); 7 return Task.CompletedTask; 8 }; 9 });
前端提交用户名密码,Action去数据库对比,若成功则以用户id(或一些非常常用的和与授权相关的属性)作为用户标识。然后调用HttpContext.SignInAsync(ClaimsPrincipal),所以最终会执行CookieAuthenticationHandler.HandleSignInAsync
大致步骤如下:
在Action中调用Context.SingOutAsync可以实现注销,在为传入方案名的情况下使用默认身份验证方案进行注销,假设默认是cookie身份验证,则CookieAuthenticationHandler.HandleSignOutAsync将被执行。大致流程如下:
若选项对象配置了Options.SessionStore则从其清空用户标识
回调Events.SigningOut
清除cookie(可能是含sessionKey或包含用户标识的cookie)
通过回调Events.RedirectToReturnUrl跳转到Options.ReturnUrlParameter页面
本篇只是从大方向说了下基于cookie的身份验证原理,对于我们开发者来说只要记住如下几个点就行了,将来有特殊需求时再去看源码。
暂时就想到这么多,以后想到再补充吧。
asp.net core 3.x 身份验证-3cookie身份验证原理
标签:let http image 设置 identity 验证方式 类型 源码 param
原文地址:https://www.cnblogs.com/jionsoft/p/12304479.html