zoukankan      html  css  js  c++  java
  • Asp.net Core认证和授权:Cookie认证

    关于asp.net core 的文章,博客园已经有很多大牛写过了。

    这里我只是记录下自己在学习中的点滴和一些不懂的地方

    Cookie一般是用户网站授权,当用户访问需要授权(authorization)的页面,程序会判断是否已经授权,并认证

    添加认证代码:
    引入命名空间:Microsoft.AspNetCore.Authentication.Cookies;

    添加服务

    public void ConfigureServices(IServiceCollection services)
            {
               
    
                services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_2);
    
                services.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme) .AddCookie();
            }

    注册中间件,添加到管道

     app.UseAuthentication();

    注意:一定要在app.UseMvc之前添加

    我们通过源码可以看到cookie的一些默认配置

    // Copyright (c) .NET Foundation. All rights reserved.
    // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
    
    using Microsoft.AspNetCore.Http;
    
    namespace Microsoft.AspNetCore.Authentication.Cookies
    {
        /// <summary>
        /// Default values related to cookie-based authentication handler
        /// </summary>
        public static class CookieAuthenticationDefaults
        {
            /// <summary>
            /// The default value used for CookieAuthenticationOptions.AuthenticationScheme
            /// </summary>
            public const string AuthenticationScheme = "Cookies";
    
            /// <summary>
            /// The prefix used to provide a default CookieAuthenticationOptions.CookieName
            /// </summary>
            public static readonly string CookiePrefix = ".AspNetCore.";
    
            /// <summary>
            /// The default value used by CookieAuthenticationMiddleware for the
            /// CookieAuthenticationOptions.LoginPath
            /// </summary>
            public static readonly PathString LoginPath = new PathString("/Account/Login");
    
            /// <summary>
            /// The default value used by CookieAuthenticationMiddleware for the
            /// CookieAuthenticationOptions.LogoutPath
            /// </summary>
            public static readonly PathString LogoutPath = new PathString("/Account/Logout");
    
            /// <summary>
            /// The default value used by CookieAuthenticationMiddleware for the
            /// CookieAuthenticationOptions.AccessDeniedPath
            /// </summary>
            public static readonly PathString AccessDeniedPath = new PathString("/Account/AccessDenied");
    
            /// <summary>
            /// The default value of the CookieAuthenticationOptions.ReturnUrlParameter
            /// </summary>
            public static readonly string ReturnUrlParameter = "ReturnUrl";
        }
    }

    我们可以自己修改:

      services.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme)
                    .AddCookie(option =>
                    {
                        option.LoginPath = "/Login"; //没有授权,跳转的url
                        option.LogoutPath = "/Login"; //退出,的url
                    });

    因为cookie在有效期内都是有效的,如果用户资料修改了,客户端的Cookie是不知道的

    网上有人提出了解决方案,如果用户修改了资料,在数据库用一个字段记录,cookie有个事件,在每次请求都会访问

    option.Events.OnValidatePrincipal = ValidatePrincipal

    想添加多个可以这样写:

     option.Events = new CookieAuthenticationEvents
                        {
                            OnValidatePrincipal = ValidatePrincipal,
                            //OnRedirectToLogin =
                        };

     public async Task ValidatePrincipal(CookieValidatePrincipalContext context)
            {
                var _Context = context.HttpContext.RequestServices.GetRequiredService<EFContext>();
                var s = context.HttpContext.RequestServices.GetService<EFContext>();
    
                var principal = context.Principal;
    
                var u = principal.Claims.Select(c => c.Type == "isEdit").FirstOrDefault();
    
                if (u)
                {
                    //更新数据库状态
                    //
    
                    // 1. 验证失败 等同于 Principal = principal;
                    context.RejectPrincipal();
    
                    //登出
                   await AuthenticationHttpContextExtensions.SignOutAsync(context.HttpContext, CookieAuthenticationDefaults.AuthenticationScheme);
                    // 2. 验证通过,并会重新生成Cookie。
                    //context.ShouldRenew = true;
    
                }
            }

    用户登陆,网上有人这里解释的

     ClaimsIdentity(身份证),Claims(身份信息)
               ClaimsPrinciple (证件所有者)

    这个也很恰当

    https://www.cnblogs.com/dudu/p/6367303.html

      [HttpPost]
            public async Task<IActionResult> Login(string ReturnUrl, User model)
            {
                if (model.UserName=="cnblogs" && model.PassWord == "pwd")
                {
                    /*
                 ClaimsIdentity(身份证),Claims(身份信息)
               ClaimsPrinciple (证件所有者)
                 */
    
                    //身份信息
                    var claims = new List<Claim> {
                        new Claim(ClaimTypes.Name,"sky"),
                        new Claim("Address","北京海淀"),
                    };
    
                    //身份证
                    var claimsIdentity = new ClaimsIdentity(claims, CookieAuthenticationDefaults.AuthenticationScheme);
    
                    //证件所有者
                    var claimsPrinciple = new ClaimsPrincipal(claimsIdentity);
    
                    /*
                     如果登陆选择了记住我,则将cookie持久化
                     这里默认持久化
                     */
                    var properties = new AuthenticationProperties
                    {
                        IsPersistent = true,
                        ExpiresUtc = DateTimeOffset.UtcNow.AddDays(1),
                        //ExpiresUtc = DateTime.Now.AddDays(1)
    
                    };
                    await HttpContext.SignInAsync(CookieAuthenticationDefaults.AuthenticationScheme, claimsPrinciple, properties);
    
                    return Redirect(ReturnUrl);
                }
                else
                    return View("index");
            }

    博客园的大神文章,很多。就放几个参考吧

    https://www.cnblogs.com/RainingNight/p/7587194.html

    https://www.cnblogs.com/tdfblog/p/7416589.html

  • 相关阅读:
    树的一些操作
    线程池的概念
    线程池
    BLOB字段来保存fastreport的报表模板
    D7调用XE2 中间层注意事项
    xe2 datasnap中间层+d7客户端调用
    关于延迟时间的一点智慧

    插件
    phpstorm clone 码云项目到本地 Version Control 不显示
  • 原文地址:https://www.cnblogs.com/nsky/p/10311450.html
Copyright © 2011-2022 走看看