码迷,mamicode.com
首页 > Web开发 > 详细

asp.net core 2.1认证

时间:2018-07-29 23:55:15      阅读:629      评论:0      收藏:0      [点我收藏+]

标签:==   virt   opera   ide   start   cookie   mep   context   login   

asp.net core 2.1认证

这篇文章基于asp.net core的CookieAuthenticationHandler来讲述。

认证和授权很相似,他们的英文也很相似,一个是Authentication认证,一个是Authorization授权。

asp.net core中的认证需要在Startup类中进行配置:

//ConfigureServices方法中:
 services.AddAuthentication(option =>
            {
                option.DefaultScheme = "Cookie";
                option.DefaultChallengeScheme = "Cookie";
                option.DefaultAuthenticateScheme = "Cookie";
                option.DefaultForbidScheme = "Cookie";
                option.DefaultSignInScheme = "Cookie";
                option.DefaultSignOutScheme = "Cookie";
            }).AddCookie("Cookie", option =>
            {
                option.LoginPath = "/Account/Login";
                option.AccessDeniedPath = "/Account/Forbidden";
                //.......
            });
//Configure方法中
 app.UseAuthentication();

看一看到如果需要认证的话是需要分别在ConfigureService方法和Configure方法中分别进行配置的。

我们看到上面在AddAuthentication方法中配置了一个option,这个option是一个Action<AuthenticationOption>,在里面,写了一堆scheme。这个scheme是什么意思呢?我们先解释一下在asp.neet core中发生的这几个动作。在asp.net core中是有几个动作要发生的:

1、登陆(Signin):用户要进行登陆的动作。

2、登出(Signout):用户要进行登出。

3、Challenge:这个不好翻译,意思当用户需要请求一个被保护的资源时,系统要求用户进行登陆。总之他也是一个登陆的动作,但是被动的登陆。

4、认证(Authenticate):认证,系统将用户的信息从token/cookie中读取出来。和登陆这个动作正好相反。

5、Forbid:系统对用户执行了拒绝的操作。

上面这些动作最后都是由一个Handler来执行的,这个handler就是一个IAuthenticationHandler的实现。

我们先给出了上面的总结,再看一下具体的情况。asp.net core2.0开始上面的这些动作的执行都是通过HttpContext的扩展方法来执行的。我们拿登陆来说,其他都大同小异。

先看HttpContext.SigninAsync这个方法:

            var claim = new Claim("name", "wallee");//我的众多信息中的一个信息单元,还有年龄、性别、家庭等等
            var identity = new ClaimsIdentity("身份证");//我的众多身份证件中的一个,还有驾驶证、准考证、会计证、计算机二级证等等
            identity.AddClaim(claim);//将上面那个信息片段添加到我的身份证里面
            var principal=new ClaimsPrincipal(identity);//将身份证作为我这个人的初始化参数,初始化一个ClaimsPrincipal就代表了一个主体。
            HttpContext.SignInAsync(principal);//最后,利用这个主体,调用HttpContext的扩展方法进行登陆。

上面的代码中注释解释了一些和本文无关但又非常重要的信息,我们关键看最后哪一行:HttpContext.SigninAsync(principal);这行代码实现了最终的登陆。现在我们看一下它的实现:

public static Task SignInAsync(this HttpContext context, string scheme, ClaimsPrincipal principal, AuthenticationProperties properties)
    {
      return context.RequestServices.GetRequiredService<IAuthenticationService>().SignInAsync(context, scheme, principal, properties);
}

上面的代码就是SigninAsync这个扩展方法的最终实现,之所以说是最终是因为它一开始调用的是同名的其他重载方法,但是方法内部最终调用到了这里。

可以看到一开始这个方法是从DI里面获取了一个IAuthenticationService,这个东西在services.AddAuthentication()这个方法中被注入到了DI,有兴趣的可以看一下。本文对这个不展开了。

之后,调用IAuthenticationService类型上面的SigninAsync(),这个方法要接收四个参数,都是从HttpContext.SigninAsync()方法中传进来的。

  • 一个是context,表示一个http上下文
  • 一个是scheme,表示一个方案
  • 一个是ClaimsPrincipal,表示一个主体,就是用户
  • 一个是AuthenticationProperties,用来设置一些参数比如Cookie持续时间等等

然后继续看一下IAuthenticationService.SignAsync()方法:

public virtual async Task SignInAsync(HttpContext context, string scheme, ClaimsPrincipal principal, AuthenticationProperties properties)
    {
      if (principal == null)
        throw new ArgumentNullException(nameof (principal));
      if (scheme == null)
      {
        scheme = (await this.Schemes.GetDefaultSignInSchemeAsync())?.Name;
        if (scheme == null)
          throw new InvalidOperationException("No authenticationScheme was specified, and there was no DefaultSignInScheme found.");
      }
      IAuthenticationSignInHandler handlerAsync = await this.Handlers.GetHandlerAsync(context, scheme) as IAuthenticationSignInHandler;
      if (handlerAsync == null)
        throw new InvalidOperationException(string.Format("No IAuthenticationSignInHandler is configured to handle sign in for the scheme: {0}", (object) scheme));
      await handlerAsync.SignInAsync(principal, properties);
    }

这个方法的流程是:

1、判断principal是否为null如果是则抛异常

2、如果scheme为null则从Scheme属性(IAuthenticationSchemeProvider)中找出默认的scheme的名字。

3、如果这个默认的也是null的话,就抛异常

4、利用scheme(string),和context(httpcontext)从Handlers属性(IAuthenticationHandlerProvider)中找出IAuthenticationHandler。

5、如果第四步找出的handler为空,那么抛异常。

6、如果不为空,那么,有最后得到的handler来执行Signin的动作,这个动作需要两个参数,一个是ClaimsPrincipal类型的principal,还有一个是AuthenticationProperties的properties。

总结:上面的登陆方法是从调用HttpContext的扩展方法SigninAsync开始的,最终会调用一个接收三个参数(this HttpContext context, string scheme, ClaimsPrincipal principal, AuthenticationProperties properties,context不算)的扩展方法,这个方法在内部要从DI中拿到一个IAuthenticationSerivce接口类型的对象,这个对象是对IAuthenticationScheme和对IAuthenticationHandler的一个封装。拿到这个IAuthentcationService的对象之后,调用这个对象上的SigninAsync方法,这个方法内部会先对传入的scheme参数进行一些判断,如果shcme为空,那么通过Scheme(IAuthenticationSchemeProvider)属性来查找一个默认的。如果还是空的话抛异常,接着,利用Handlers属性(IAuthenticationHandlerProvider类型)找到最终的handler:IAuthenticationHandler对象,来处理最后的登陆。

asp.net core 2.1认证

标签:==   virt   opera   ide   start   cookie   mep   context   login   

原文地址:https://www.cnblogs.com/pangjianxin/p/9388224.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!