asp.net core3.1cookie和jwt混合认证授权实现多种身份验证方案

 更新时间:2021-09-22 21:45:22   作者:佚名   我要评论(0)

目录认证授权
身份认证
授权
默认授权选择授权总结
开发了一个公司内部系统,使用asp.net core 3.1。在开发用户认证授权使用的是简单的c

开发了一个公司内部系统,使用asp.net core 3.1。在开发用户认证授权使用的是简单的cookie认证方式,然后开发好了要写几个接口给其它系统调用数据。并且只是几个简单的接口不准备再重新部署一个站点,所以就直接在MVC的项目里面加了一个API区域用来写接口。这时候因为是接口所以就不能用cookie方式进行认证,得加一个jwt认证,采用多种身份验证方案来进行认证授权。

认证授权

身份验证是确定用户身份的过程。 授权是确定用户是否有权访问资源的过程。 在 ASP.NET Core 中,身份验证由 IAuthenticationService 负责,而它供身份验证中间件使用。 身份验证服务会使用已注册的身份验证处理程序来完成与身份验证相关的操作。

认证-->授权

关于认证授权我们要区分认证和授权是两个概念,具体可查看MSDN官方文档也可以搜索其它文章看看,讲的很多。其中包括OAuth 2.0 以及jwt的相关知识都有很多资料并且讲解的很好。

身份认证

身份验证方案由 Startup.ConfigureServices 中的注册身份验证服务指定:
方式是在调用 services.AddAuthentication 后调用方案特定的扩展方法(例如 AddJwtBearer 或 AddCookie)。 这些扩展方法使用 AuthenticationBuilder.AddScheme 向适当的设置注册方案。

添加cookie JwtBearer验证方案

public void ConfigureServices(IServiceCollection services)
{
    services.AddSession();
    services.AddMvc(o =>
    {
        o.Filters.Add(typeof(MyExceptionFilterAttribute));// 全局异常Filter  
    }).AddRazorRuntimeCompilation();
    //添加身份认证方案
    var jwtConfig= Configuration.GetSection("Jwt").Get<JwtConfig>();
    services.AddAuthentication
        (authoption =>{
            //指定默认选项
            authoption.DefaultChallengeScheme= CookieAuthenticationDefaults.AuthenticationScheme;
            authoption.DefaultAuthenticateScheme = CookieAuthenticationDefaults.AuthenticationScheme;
            authoption.DefaultSignOutScheme = CookieAuthenticationDefaults.AuthenticationScheme;
            authoption.DefaultSignInScheme= CookieAuthenticationDefaults.AuthenticationScheme;
        })
   .AddCookie(CookieAuthenticationDefaults.AuthenticationScheme, option =>
   {
       option.Cookie.Name = "adCookie";//设置存储用户登录信息(用户Token信息)的Cookie名称
       option.Cookie.HttpOnly = true;//设置存储用户登录信息(用户Token信息)的Cookie,无法通过客户端浏览器脚本(如JavaScript等)访问到
       option.ExpireTimeSpan = TimeSpan.FromDays(3);// 过期时间
       option.SlidingExpiration = true;// 是否在过期时间过半的时候,自动延期
       option.LoginPath = "/Account/Login";
       option.LogoutPath = "/Account/LoginOut";
   })
   .AddJwtBearer(option =>
   {
       option.TokenValidationParameters = new TokenValidationParameters
       {
           ValidIssuer = jwtConfig.Issuer,
           ValidAudience = jwtConfig.Audience,
           ValidateIssuer = true,
           ValidateLifetime = jwtConfig.ValidateLifetime,
           IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(jwtConfig.SigningKey)),
           //缓冲过期时间,总的有效时间等于这个时间加上jwt的过期时间
           ClockSkew = TimeSpan.FromSeconds(0)
       };
   });
}

JwtBearer认证的配置参数类JwtConfig

public class JwtConfig
{
    /// <summary>
    /// 谁颁发的
    /// </summary>
    public string Issuer { get; set; }

    /// <summary>
    /// 颁发给谁
    /// </summary>
    public string Audience { get; set; }

    /// <summary>
    /// 令牌密码
    /// a secret that needs to be at least 16 characters long
    /// </summary>
    public string SigningKey { get; set; }

    /// <summary>
    /// 过期时间(分钟)
    /// </summary>
    public int Expires { get; set; }

    /// <summary>
    /// 是否校验过期时间
    /// </summary>
    public bool ValidateLifetime { get; set; }
}

appsettings.json 配置参数

  "Jwt": {
    "Issuer": "issuer",
    "Audience": "audience",
    "SigningKey": "c0d32c63-z43d-4917-bbc2-5e726d087452",
    //过期时间(分钟)
    "Expires": 10080,
    //是否验证过期时间
    "ValidateLifetime": true
  }

添加身份验证中间件

通过在应用的 IApplicationBuilder 上调用 UseAuthentication 扩展方法,在 Startup.Configure 中添加身份验证中间件。 如果调用 UseAuthentication,会注册使用之前注册的身份验证方案的中间节。 请在依赖于要进行身份验证的用户的所有中间件之前调用 UseAuthentication。 如果使用终结点路由,则必须按以下顺序调用 UseAuthentication:

  • 在 UseRouting之后调用,以便路由信息可用于身份验证决策。
  • 在 UseEndpoints 之前调用,以便用户在经过身份验证后才能访问终结点。
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
    if (env.IsDevelopment())
    {
        app.UseDeveloperExceptionPage();
    }
    else
    {
        app.UseExceptionHandler("/Home/Error");
        app.UseHsts();
    }
    app.UseHttpsRedirection();
    app.UseSession();
    app.UseRouting();

    //开启认证中间件
    app.UseAuthentication();
    //开启授权中间件
    app.UseAuthorization();

    app.UseEndpoints(endpoints =>
    {

        endpoints.MapControllerRoute(
        name: "areas",
        pattern: "{area:exists}/{controller=Home}/{action=Index}/{id?}");

        endpoints.MapControllerRoute(
            name: "default",
            pattern: "{controller=Home}/{action=Index}/{id?}");
    });
}

cookie认证

[HttpPost]
public async Task<NewtonsoftJsonResult> LoginIn(string userName, string userPassword, string code)
{
    AjaxResult objAjaxResult = new AjaxResult();
    var user = _userBll.GetUser(userName, userPassword);
    if (user == null)
    {
        objAjaxResult.Result = DoResult.NoAuthorization;
        objAjaxResult.PromptMsg = "用户名或密码错误";
    }
    else
    {
        var claims = new List<Claim>
        {   
            new Claim("userName", userName),
            new Claim("userID",user.Id.ToString()),
        };
        await HttpContext.SignInAsync(new ClaimsPrincipal(new ClaimsIdentity(claims,CookieAuthenticationDefaults.AuthenticationScheme)));
        objAjaxResult.Result = DoResult.Success;
        objAjaxResult.PromptMsg = "登录成功";
    }
    return new NewtonsoftJsonResult(objAjaxResult);
}

jwt认证

[HttpPost]
public NewtonsoftJsonResult Token([FromBody] UserInfo model)
{
    AjaxResult objAjaxResult = new AjaxResult();
    var user = _userBll.GetUser(model.UserName, model.Password);
    if (user == null)
    {
        objAjaxResult.Result = DoResult.NoAuthorization;
        objAjaxResult.PromptMsg = "用户名或密码错误";
    }
    else
    {
        //jwtTokenOptions 是通过配置获取上面配置的参数信息
        var jwtTokenOptions = BaseConfigModel.jwtConfig;
        var key = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(jwtTokenOptions.SigningKey));
        var credentials = new SigningCredentials(key, SecurityAlgorithms.HmacSha256);
        //身份
        var claims = new List<Claim>
            {
                new Claim("userID",user.Id.ToString()),
                new Claim("userName",user.UserName),
            };
        //令牌
        var expires = DateTime.Now.AddMinutes(jwtTokenOptions.Expires);
        var token = new JwtSecurityToken(
            issuer: jwtTokenOptions.Issuer,
            audience: jwtTokenOptions.Audience,
            claims: claims,
            notBefore: DateTime.Now,
            expires: expires,
            signingCredentials: credentials
            );
        string jwtToken = new JwtSecurityTokenHandler().WriteToken(token);
        objAjaxResult.Result = DoResult.Success;
        objAjaxResult.RetValue = new
        {
            token = jwtToken
        };
        objAjaxResult.PromptMsg = "登录成功";
    }
    return new NewtonsoftJsonResult(objAjaxResult);
}

授权

在授权时,应用指示要使用的处理程序。 选择应用程序将通过以逗号分隔的身份验证方案列表传递到来授权的处理程序 [Authorize] 。 [Authorize]属性指定要使用的身份验证方案或方案,不管是否配置了默认。

默认授权

因为上面认证配置中我们使用cookie作为默认配置,所以前端对应的controller就不用指定验证方案,直接打上[Authorize]即可。

选择授权

对于API接口我们使用Jwt授权,在Controller上打上指定方案。

[Authorize(AuthenticationSchemes = JwtBearerDefaults.AuthenticationScheme)]

总结

关于多种方案混合验证授权的流程:
1、配置认证方案(相关的配置参数可采用配置文件形式)。
2、添加授权验证中间件。
3、提供认证接口。
4、配置需要授权的接口授权方案。

到此这篇关于asp.net core3.1cookie和jwt混合认证授权实现多种身份验证方案的文章就介绍到这了,更多相关asp.net core cookie和jwt认证授权内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

您可能感兴趣的文章:
  • ASP.NET Core如何注入多个服务实现类
  • 理解ASP.NET Core 依赖注入(Dependency Injection)
  • 理解ASP.NET Core 启动类(Startup)
  • 理解ASP.NET Core 中间件(Middleware)
  • 关于Jenkins + Docker + ASP.NET Core自动化部署的问题(避免踩坑)
  • asp.net core MVC之实现基于token的认证
  • ASP.NET Core 集成 React SPA应用的步骤
  • ASP.NET Core 文件响应压缩的常见使用误区
  • ASP.NET Core中间件初始化的实现
  • ASP.NET Core读取Request.Body的正确方法
  • ASP.NET Core Web API 教程Project Configuration

相关文章

  • asp.net core3.1cookie和jwt混合认证授权实现多种身份验证方案

    asp.net core3.1cookie和jwt混合认证授权实现多种身份验证方案

    目录认证授权 身份认证 授权 默认授权选择授权总结 开发了一个公司内部系统,使用asp.net core 3.1。在开发用户认证授权使用的是简单的c
    2021-09-22
  • 详解.NET数据库连接池

    详解.NET数据库连接池

    目录前置知识背景1. .NET数据库连接池的背景2. .NET 数据库连接池的表现3. .NET是如何形成数据库连接池的&#63;4. 连接池中的连接什么时候被移
    2021-09-22
  • .Net Core 之AutoFac的使用

    .Net Core 之AutoFac的使用

    目录Autofac介绍组件的三种注册方式生命周期AutoFac 在asp .net core中的使用本文不介绍IoC和DI的概念,如果你对Ioc之前没有了解的话,建议先
    2021-09-22
  • Asp.net Core 如何设置黑白名单(路由限制)

    Asp.net Core 如何设置黑白名单(路由限制)

    在原有的AspnetMvc中我们会使用到路由访问限制,在AppStart/RouteConfig.cs中写上如下: routes.IgnoreRoute("{resource}.axd/{*pathInfo}
    2021-09-22
  • C#中efcore-ShardingCore呈现“完美”分表

    C#中efcore-ShardingCore呈现“完美”分表

    目录efcore支持情况 数据库支持情况如何开始使用 自定义分表键,自定义分表规则 默认路由 动态添加分表信息 支持select,join,group by等
    2021-09-22
  • .NET Core对象池的应用:编程篇

    .NET Core对象池的应用:编程篇

    目录一、对象的借与还二、依赖注入三、池化对象策略四、对象池的大小五、对象的释放借助于有效的自动化垃圾回收机制,.NET让开发人员不在关心
    2021-09-22
  • .NET Core对象池的应用:设计篇

    .NET Core对象池的应用:设计篇

    目录一、 IPooledObjectPolicy<T>二、ObjectPool<T>DefaultObjectPool<T>DisposableObjectPool<T>三、ObjectPoolProvider《编程篇》已经涉及
    2021-09-22
  • 运用.net core中实例讲解RabbitMQ高可用集群构建

    运用.net core中实例讲解RabbitMQ高可用集群构建

    目录一、集群架构简介二、普通集群搭建2.1 各个节点分别安装RabbitMQ2.2 把节点加入集群2.3 代码演示普通集群的问题三、镜像集群四、HAProxy
    2021-09-22
  • .Net Core 中选项Options的具体实现

    .Net Core 中选项Options的具体实现

    目录由代码开始定义一个用户配置选项定义json配置文件:myconfig.json 创建ServiceCollection 示例代码 代码运行结果 通过运行代码得到的
    2021-09-22
  • .Net Core配置Configuration具体实现

    .Net Core配置Configuration具体实现

    目录核心类 构建ConfigurationBuilder IConfigurationSource ConfigurationProvider ConfigurationRoot 查询 索引器 GetSection DBC
    2021-09-22

最新评论