开发了一个公司内部系统,使用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 core 3.1多种身份验证方案,cookie和jwt混合认证授权的更多相关文章

  1. 坎坷路:ASP.NET Core 1.0 Identity 身份验证(中集)

    上一篇:<坎坷路:ASP.NET 5 Identity 身份验证(上集)> ASP.NET Core 1.0 什么鬼?它是 ASP.NET vNext,也是 ASP.NET 5,以后也可能 ...

  2. ASP.NET Core 项目简单实现身份验证及鉴权

    ASP.NET Core 身份验证及鉴权 目录 项目准备 身份验证 定义基本类型和接口 编写验证处理器 实现用户身份验证 权限鉴定 思路 编写过滤器类及相关接口 实现属性注入 实现用户权限鉴定 测试 ...

  3. 实践剖析.NET Core如何支持Cookie和JWT混合认证、授权

    前言 为防止JWT Token被窃取,我们将Token置于Cookie中,但若与第三方对接,调用我方接口进行认证.授权此时仍需将Token置于请求头,通过实践并联系理论,我们继续开始整活!首先我们实现 ...

  4. ASP.NET Core WebApi中使用FluentValidation验证数据模型

    原文链接:Common features in ASP.NET Core 2.1 WebApi: Validation 作者:Anthony Giretti 译者:Lamond Lu 介绍 验证用户输 ...

  5. 关于ASP.Net Core Web及API身份认证的解决方案

    6月15日,在端午节前的最后一个工作日,想起有段日子没有写过文章了,倒有些荒疏了.今借夏日蒸蒸之气,偷得浮生半日悠闲.闲话就说到这里吧,提前祝大家端午愉快(屈原听了该不高兴了:))!.NetCore自 ...

  6. HTTP 请求未经客户端身份验证方案“Anonymous”授权。从服务器收到的身份验证标头为“Negotiate,NTLM”

    转自:http://www.cnblogs.com/geqinggao/p/3270499.html 近来项目需要Web Service验证授权,一般有两种解决方案: 1.通过通过SOAP Heade ...

  7. 发布Restful服务时出现IIS 指定了身份验证方案错误时的解决方案(IIS specified authentication schemes)

    发布RESTful服务,当访问.svc文件时出现如下错误时: IIS 指定了身份验证方案“IntegratedWindowsAuthentication, Anonymous”,但绑定仅支持一种身份验 ...

  8. HTTP 请求未经客户端身份验证方案“Anonymous”授权。

    今天调取WebService的时候报: HTTP 请求未经客户端身份验证方案“Anonymous”授权. 解决办法: 配置文件里改: <basicHttpBinding> <bind ...

  9. 定制Asp.NET 5 MVC内建身份验证机制 - 基于自建SQL Server用户/角色数据表的表单身份验证

    背景 在需要进行表单认证的Asp.NET 5 MVC项目被创建后,往往需要根据项目的实际需求做一系列的工作对MVC 5内建的身份验证机制(Asp.NET Identity)进行扩展和定制: Asp.N ...

随机推荐

  1. LintCode笔记 - 8. 旋转字符串

    这一题相对简单,但是代码质量可能不是很好,我分享一下我的做题笔记以及做题过程给各位欣赏,有什么不足望各位大佬指出来 原题目,各位小伙伴也可以试着做一下 . 旋转字符串 中文English 给定一个字符 ...

  2. 爬虫前篇 /https协议原理剖析

    爬虫前篇 /https协议原理剖析 目录 爬虫前篇 /https协议原理剖析 1. http协议是不安全的 2. 使用对称秘钥进行数据加密 3. 动态对称秘钥和非对称秘钥 4. CA证书的应用 5. ...

  3. 盘点JMeter不为人知那一些细节

    Jmeter工作原理 向服务器提交请求,并从服务器取回请求返回的结果.即建立一个线程池,多线程运行取样器产生大量负载,在运行过程中通过断言来验证结果的正确性,通过监听器来记录测试结果. 文章内容以Jm ...

  4. java-把生成的随机数,指定范围(如:100-200),指定打印次数(如:50次),并进行去重。

    package main.demo; public class Demo4 { /** * 随机指定范围内N个不重复的数 * 最简单最基本的方法 * @param min 指定范围最小值 * @par ...

  5. 印象笔记如何使用二次验证码/虚拟MFA/两步验证/谷歌验证器?

    一般点账户名——设置——安全设置中开通虚拟MFA两步验证 具体步骤见链接  印象笔记如何使用二次验证码/虚拟MFA/两步验证/谷歌验证器? 二次验证码小程序于谷歌身份验证器APP的优势 1.无需下载a ...

  6. Zookeeper ----- ZAB算法

    介绍 Zookeeper没有使用Paxos实现,而是使用ZAB(Zookeeper原子消息广播协议)作为数据一致性的核心算法. ZAB是一种专为Zookeeper设计的支持崩溃恢复的原子广播协议. Z ...

  7. JMS微服务开发示例(一)Hello world

    网关部署 1.在网关服务器上,安装.net core 3.1运行环境: 2.到 https://www.cnblogs.com/IWings/p/13354541.html 下载Gateway.zip ...

  8. LeetCode 86 | 链表基础,一次遍历处理链表中所有符合条件的元素

    本文始发于个人公众号:TechFlow,原创不易,求个关注 今天是LeetCode专题第53篇文章,我们一起来看LeetCode第86题,Partition List(链表归并). 本题的官方难度是M ...

  9. 抓取Android崩溃日志

    作为一个测试人员,特别是安卓的测试,由于系统版本的不同和手机本身各个品牌的优化和硬件的不同,会出现各种各样的崩溃. 记录崩溃的方式有很多种,比如使用录屏工具或文档进行记录,但是最简洁明了可以直接定位的 ...

  10. MySQL(二)表的操作与简单数据操作

    六大约束:主键约束.外键约束.非空约束.唯一约束.默认约束.自动增加 1.not null非空 2.defaul默认值,用于保证该字段的默认值 ; 比如年龄:1900-10-10 3.primar k ...