• .net core 认证与授权(二)


    前言

    这篇紧接着一来写的,在第一篇中介绍了认证与授权,同时提出了这套机制其实就是模拟现实中的认证与授权。
    同样这篇介绍在这套机制下,用户信息管理机制?这里就会问了,上一篇中认证和授权不是都ok了吗,怎么会有一个管理机制呢?当然并不一定要使用下面这套机制,但是给了我们很大的启发。
    在上一结中我们颁发证书是这样的:

    public IActionResult Authenticate()
    {
        var SchoolClaims = new List<Claim>()
        {
            new Claim(ClaimTypes.Name,"Jack"),
            new Claim(ClaimTypes.Email,"Jack@fmail.com")
        };
    
        var LicensClaims = new List<Claim>()
        {
            new Claim(ClaimTypes.Name,"Jack.li"),
            new Claim(ClaimTypes.Email,"Jack@fmail.com"),
            new Claim("begin","2000.10.1")
        };
        var SchoolIdentity = new ClaimsIdentity(SchoolClaims,"Student Identity");
        var CarManagerIdentity = new ClaimsIdentity(LicensClaims, "Licens Identity");
        var userPrincipal = new ClaimsPrincipal(new[] { SchoolIdentity, CarManagerIdentity });
        
        HttpContext.SignInAsync(userPrincipal);
        return RedirectToAction("Index");
    }
    

    有没有发现new Claim(ClaimTypes.Name,"Jack") 写死了?我的信息是要从数据库里面查啊。
    这时候微软的框架就跳出来了,说用我的这套机制,帮你搞定,到底是什么机制呢?请看正文。小声逼逼一句,微软就喜欢搞全包工程。
    正文均为个人理解,如有不对请指出。

    正文

    首先提及到一个结构,IdentityUser,这东西是真的博大精深,但是感觉有点臃肿,这很微软。
    IdentityUser 这里可以简单说明一下,就是存储用户信息的地方。
    既然说到用户存储,那么就要提及到数据库了。
    创建了一个AppDbContext:

    public class AppDbContext:IdentityDbContext
    {
    	public AppDbContext(DbContextOptions<AppDbContext> options):base(options)
    	{
    
    	}
    }
    

    以前我们一般是继承DbContext,DbContext是Ef的上下文。
    这里IdentityDbContext,是Ef的扩展,看下我添加了什么。

    红色框内是我添加的。
    在这里我为了演示使用内存数据库memory,所以我多加了一个库。
    然后我在startup中配置使用memory数据库。

     services.AddDbContext<AppDbContext>(config =>{
                    config.UseInMemoryDatabase("Memery");
                });
    

    这样就配置了,现在就解决了数据库的问题。
    同样需要配置identity:

    services.AddIdentity<IdentityUser, IdentityRole>(config=> {
                    config.Password.RequiredLength = 4;
                    config.Password.RequireDigit = false;
                    config.Password.RequireNonAlphanumeric = false;
                    config.Password.RequireLowercase = false;
                    config.Password.RequireUppercase = false;
                }).AddEntityFrameworkStores<AppDbContext>().AddDefaultTokenProviders();
    

    有几个关键的地方,就是config.Password.RequiredLength = 4;等几个password的配置,
    因为identetyUser 有默认的机制就是密码必须要大写,然后不小于6位密码等,我们在这里全部去掉。
    AddEntityFrameworkStores() 添加EF 存储实现。
    AddDefaultTokenProviders() 默认提供生成token。这种token 用来干啥呢?当然是用来证明用户的了。比如我们修改密码的时候,我们发现链接上有一个token,异曲同工之妙哈。

    services.ConfigureApplicationCookie(config =>
    {
    	config.Cookie.Name = "Identity.Cooke";
    	config.LoginPath = "/Home/Login";
    });
    

    加上验证,当没有登陆的时候去到登陆页面。
    好的配置我们基本完成了。
    接下来就是去实现登陆与注册。

    public IActionResult Index()
    {
    	return View();
    }
    public IActionResult Secret()
    {
    	return View();
    }
    
    public IActionResult Login()
    {
    	return View();
    }
    
    public IActionResult Register()
    {
    	return View();
    }
    [HttpPost]
    public async Task<IActionResult> Login(string username, string password)
    {
    	var user = await _userManager.FindByNameAsync(username);
    	if (user != null)
    	{
    		//sign in
    	   var Signresult= await  _signInManager.PasswordSignInAsync(user,password,false,false);
    		if (Signresult.Succeeded)
    		{
    			return RedirectToAction("Secret");
    		}
    	}
    	return RedirectToAction("Index");
    }
    [HttpPost]
    public async Task<IActionResult>  Register(string username,string password)
    {
    
    	var user = new IdentityUser
    	{
    		UserName = username,
    		Email = ""
    	};
    
    	var result=await _userManager.CreateAsync(user,password);
    	if (result.Succeeded)
    	{
    		var Signresult = await _signInManager.PasswordSignInAsync(user, password, false, false);
    		if (Signresult.Succeeded)
    		{
    			return RedirectToAction("Index");
    		}
    	}
    	return RedirectToAction("Index");
    }
    

    看到两个http post:
    先看Register:
    创建了IdentityUser,用来存储用户信息。
    _userManager 是用来管理user用户的,比如说创建,删除,修改,是identetyUser 内部机制。
    创建过程如下:

    public HomeController(UserManager<IdentityUser> userManager,SignInManager<IdentityUser> signInManager)
    {
    	_userManager = userManager;
    	_signInManager = signInManager;
    }
    

    var result=await _userManager.CreateAsync(user,password); 如果创建用户成功,那么就进行登陆如下:

    var Signresult = await _signInManager.PasswordSignInAsync(user, password, false, false);
    

    注意PasswordSignInAsync登陆的话会产生token,用于验证我们是否登陆。
    当我注册后,产生了token,如下:

    看下登陆,其实我们在注册部分就已经介绍了登陆了。
    我重新把代码放下了:

    var user = await _userManager.FindByNameAsync(username);
    if (user != null)
    {
    	//sign in
       var Signresult= await  _signInManager.PasswordSignInAsync(user,password,false,false);
    	if (Signresult.Succeeded)
    	{
    		return RedirectToAction("Secret");
    	}
    }
    return RedirectToAction("Index");
    

    发现就多了一步,根据名字去查找user,如果有这个user,然后去比较密码。和平时写code 差不多。
    然后登陆后就可以进入了我们想进入的页面。
    如果我们想loginout:

    public async Task<IActionResult> Logout()
    {
    	await _signInManager.SignOutAsync();
    	return RedirectToAction("Index");
    }
    

    把登陆和注册的页面贴下:
    login:

    <form action="/Home/Login" method="post">
        <input type="text" name="username" value="" />
        <input type="password" name="password" value="" />
        <button type="submit">登陆</button>
    </form>
    

    注册:

    <form action="/Home/Register" method="post">
        <input type="text" name="username" value="" />
        <input type="password" name="password" value="" />
        <button type="submit">注册</button>
    </form>
    

    在上一篇中,就很疑问了,上一篇没有登录啊。
    真的没有登录吗?只是用证书去登录了,不然怎么能过的了检查呢。

    HttpContext.SignInAsync("CookieAuth", userPrincipal);
    

    总结

    现在我们的流程更加的明显了,先要验证用户信息,比如说是否登录了,这个过程相当于什么呢?我们用我们的名字和指纹(password),去获取到了我们的身份证。有了这张身份证后我们才有其他的证书,然后才有根据证书去获取一些权限。
    后续介绍基本的配置,与原理。

  • 相关阅读:
    angularjs 过滤器
    angularjs 工具方法
    angularjs 模块化
    angularjs ng-app
    angularjs作用域和函数调用
    Android sdk版本以及兼容性问题
    跟谁鼠标移动
    事件捕获,事件冒泡,事件取消
    netsh 转发 5000 端口到 80端口的命令和删除方法
    [微软官网]windows server 内存限制
  • 原文地址:https://www.cnblogs.com/aoximin/p/12271471.html
Copyright © 2020-2023  润新知