.NET Core Authentication Cookie身份认证 Cookie跨域

ASP.NET Core中的密钥管理 
在 ASP.NET Core 中配置证书身份验证 (TLS,HTTPS 证书)
在 ASP.NET 应用中共享身份验证 cookie  
在 ASP.NET Core 中的密钥存储提供程序  【文件系统、Azure 存储、Redis、注册表、数据库、自定义密钥存储库】
配置 ASP.NET Core 数据保护  
ASP.NET核心中的关键存储格式   【秘钥存储格式】
ASP.NET Core 身份验证及鉴权
1、Startup.cs    AddAuthentication    AddCookie    app.UseAuthentication()    app.UseAuthorization()

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

namespace Web.Test1
{
    public class Startup
    {
        public Startup(IConfiguration configuration)
        {
            Configuration = configuration;
        }

        public IConfiguration Configuration { get; }

        // This method gets called by the runtime. Use this method to add services to the container.
        public void ConfigureServices(IServiceCollection services)
        {
            services.Configure<CookiePolicyOptions>(options =>
            {
                // This lambda determines whether user consent for non-essential cookies is needed for a given request.
                options.CheckConsentNeeded = context => true;
                options.MinimumSameSitePolicy = SameSiteMode.None;
            });

            // 认证
            services.AddAuthentication("MyCookieAuthenticationScheme")
               .AddCookie("MyCookieAuthenticationScheme", options =>
               {
                   options.LoginPath = "/Account/Login";//用户尝试访问资源但尚未认证时,这是请求重定向的相对路径。
                   options.LogoutPath = "/Account/Logout";//指定登出的路径
                   options.AccessDeniedPath = "/Account/AccessDenied";//用户尝试访问资源但没有通过任何授权策略时,这是请求会重定向的相对路径资源。
                   options.ExpireTimeSpan = TimeSpan.FromMinutes(30);//指定Cookie的过期时间
                   options.SlidingExpiration = true;//当Cookie过期时间已达一半时,是否重置为ExpireTimeSpan

                   options.Events = new CookieAuthenticationEvents//可用于拦截和重写Cookie身份验证
                   {
                       OnValidatePrincipal = Filter.LastChangedValidator.ValidateAsync
                   };
                   options.Events.OnRedirectToLogin = z =>//api接口判断
                   {
                       if (z.HttpContext.Request.Path.StartsWithSegments("/api", StringComparison.OrdinalIgnoreCase))
                       {
                           z.HttpContext.Response.Redirect("/api/Login/UnAuth");//未授权错误信息的接口地址,返回json
                       }
                       else
                       {
                           z.HttpContext.Response.Redirect(z.RedirectUri);//其它安装默认处理
                       }
                       return Task.CompletedTask;
                   };
                   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;//谨慎使用
               });

            // 授权
            services.AddAuthorization(options =>
            {
                // options.AddPolicy("MyPolicy", policy => { });
            });

            services.AddSession(options =>
            {
                options.IdleTimeout = TimeSpan.FromMinutes(10); //session活期时间
                options.Cookie.HttpOnly = true;//设为httponly
            });

            services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_2);
        }

        // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
        public void Configure(IApplicationBuilder app, IHostingEnvironment env)
        {
            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
            }
            else
            {
                app.UseExceptionHandler("/Home/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.UseHttpsRedirection();
            app.UseStaticFiles();
            app.UseCookiePolicy();

            app.UseSession();

            //Adds the authentication middleware to the pipeline
            app.UseAuthentication();

            app.UseAuthorization();

            app.UseMvc(routes =>
            {
                routes.MapRoute(
                    name: "default",
                    template: "{controller=Home}/{action=Index}/{id?}");
            });
        }
    }
}

2、Controller(AccountController)

[Authorize]、Claim、ClaimsIdentity、ClaimsPrincipal、

await HttpContext.SignInAsync(claimsPrincipal)  用户登录成功后颁发一个证书(加密的用户凭证),用来标识用户的身份。

await HttpContext.SignOutAsync();   退出登录,如清除Coookie等

using System;
using System.Collections.Generic;
using System.Linq;
using System.Security.Claims;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Authentication;
using Microsoft.AspNetCore.Authentication.Cookies;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;

namespace Web.Test1.Controllers
{
    public class AccountController : Controller
    {
        [Authorize]
        public IActionResult Index()
        {
            ///判断用户是否已经登录,如果已经登录,那么读取登录用户的用户名
            if (HttpContext.User.Identity.IsAuthenticated)
            {
                //这里通过 HttpContext.User.Claims 可以将我们在Login这个Action中存储到cookie中的所有
                //claims键值对都读出来,比如我们刚才定义的UserName的值Wangdacui就在这里读取出来了
                var userName = HttpContext.User.Claims.First().Value;

                var adminAccount = HttpContext.User.Claims.SingleOrDefault(t => t.Type == "UserName");
                string account = adminAccount == null ? "" : adminAccount.Value;

                var adminPwd = HttpContext.User.Claims.SingleOrDefault(t => t.Type == "Password");
                string pwd = adminPwd == null ? "" : adminPwd.Value;

                var rememberMe = HttpContext.User.Claims.SingleOrDefault(t => t.Type == "RememberMe");
                string rem = rememberMe == null ? "" : rememberMe.Value;

            }
            return View();
        }

        public IActionResult Login()
        {
            return View();
        }

        public IActionResult Logout()
        {
            #region 方式1

            HttpContext.SignOutAsync("MyCookieAuthenticationScheme");

            #endregion

            #region 方式2

            Task.Run(async () =>
            {
                //注销登录的用户,相当于ASP.NET中的FormsAuthentication.SignOut  
                await HttpContext.SignOutAsync();
            }).Wait();

            #endregion

            return View();
        }

        public IActionResult AccessDenied()
        {
            return View();
        }

        [HttpPost]
        public async Task<IActionResult> LoginAsync()
        {
            #region 方式1(ClaimsPrincipal)

            ///身份信息
            var claims = new[]
            {
                new Claim("UserName", "Wangdacui"),
                new Claim("Password", "123456"),
                new Claim(ClaimTypes.Sid, "123"),
                new Claim(ClaimTypes.Name, "name"),
            };

            ///身份证
            var claimsIdentity = new ClaimsIdentity(claims, CookieAuthenticationDefaults.AuthenticationScheme);

            ///证件所有者
            ClaimsPrincipal user = new ClaimsPrincipal(claimsIdentity);

            #endregion

            #region 方式2(ClaimsPrincipal)

            var claimIdentity = new ClaimsIdentity("Cookie");
            claimIdentity.AddClaim(new Claim("UserName", "Wangdacui"));
            claimIdentity.AddClaim(new Claim("Password", "123456"));//自己随便写一个名字
            claimIdentity.AddClaim(new Claim("RememberMe", "on"));
            claimIdentity.AddClaim(new Claim(ClaimTypes.Sid, "123"));
            claimIdentity.AddClaim(new Claim(ClaimTypes.NameIdentifier, "1"));
            claimIdentity.AddClaim(new Claim(ClaimTypes.Name, "name"));
            claimIdentity.AddClaim(new Claim(ClaimTypes.Email, "emial"));
            claimIdentity.AddClaim(new Claim(ClaimTypes.MobilePhone, "PhoneNumber"));
            claimIdentity.AddClaim(new Claim(ClaimTypes.DateOfBirth, "2018-7-1"));

            var claimsPrincipal = new ClaimsPrincipal(claimIdentity);

            #endregion

            var options = new CookieOptions
            {
                HttpOnly = true,
                SameSite = Microsoft.AspNetCore.Http.SameSiteMode.None
            };

            #region 方式1(SignInAsync)
            // 在上面注册AddAuthentication时,指定了默认的Scheme,在这里便可以不再指定Scheme。
            await HttpContext.SignInAsync(claimsPrincipal);
            #endregion

            #region 方式2(SignInAsync)
            await HttpContext.SignInAsync("MyCookieAuthenticationScheme", claimsPrincipal);
            #endregion

            #region 方式3(SignInAsync)

            await HttpContext.SignInAsync(
            "MyCookieAuthenticationScheme",
            claimsPrincipal,
            new AuthenticationProperties
            {
                IsPersistent = true,//持久Cookie
                    ExpiresUtc = DateTime.UtcNow.AddMinutes(20),//设置cookie过期时间
                    AllowRefresh = false,
            });

            #region 方式4(SignInAsync)

            Task.Run(async () =>
            {
                //登录用户,相当于ASP.NET中的FormsAuthentication.SetAuthCookie
                await HttpContext.SignInAsync(CookieAuthenticationDefaults.AuthenticationScheme, claimsPrincipal);

            }).Wait();

            #endregion

            #endregion

            return RedirectToAction(nameof(HomeController.Index), "Home");
        }

        public async Task<IActionResult> LogoutAsync()
        {
            await HttpContext.SignOutAsync(CookieAuthenticationDefaults.AuthenticationScheme);
            return RedirectToAction(nameof(HomeController.Index), "Home");
        }
    }
}

3、Controller(HomeController)[Authorize]

using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using Web.Test1.Models;

namespace Web.Test1.Controllers
{
    [Authorize]
    public class HomeController : Controller
    {
        public IActionResult Index()
        {
            return View();
        }

        public IActionResult Privacy()
        {
            return View();
        }

        [ResponseCache(Duration = 0, Location = ResponseCacheLocation.None, NoStore = true)]
        public IActionResult Error()
        {
            return View(new ErrorViewModel { RequestId = Activity.Current?.Id ?? HttpContext.TraceIdentifier });
        }
    }
}

4、LastChangedValidator   可用于拦截和重写Cookie身份验证

using System;
using System.Collections.Generic;
using System.Linq;
using System.Security.Claims;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Authentication;
using Microsoft.AspNetCore.Authentication.Cookies;
using Microsoft.Extensions.DependencyInjection;

namespace Web.Test1.Filter
{
    public interface IUserRepository
    {
        bool ValidateLastChanged(ClaimsPrincipal claims, string lastChanged);
    }

    public class UserRepository : IUserRepository
    {
        public bool ValidateLastChanged(ClaimsPrincipal claims, string lastChanged)
        {
            return false;
        }
    }

    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");
            }
        }
    }
}

设置

HttpContext.Response.Cookies.Append("password","123456");

获取

string value = "";
HttpContext.Request.Cookies.TryGetValue("password", out value);

string auth = "";
HttpContext.Request.Cookies.TryGetValue("AuthCookie", out auth);

var sid = HttpContext.User.FindFirst(ClaimTypes.Sid);
var userName = HttpContext.User.Claims.First().Value;
var adminAccount = HttpContext.User.Claims.SingleOrDefault(t => t.Type == "UserName");
string account = adminAccount == null ? "" : adminAccount.Value;

if (HttpContext.User.Identity.IsAuthenticated)
{
    var uName = HttpContext.User.Claims.First().Value;
}
else
{
    string a = "";
}

删除

HttpContext.Response.Cookies.Delete("password");

Cookie 跨域
1、是否在CookiePolicyOptions中设置了SameSite为No
2、AllowCredentials是否配置了
*
*
*
*
*
*
*
*
*

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值