ASP.NET Core快速入门(第5章:认证与授权)--学习笔记
课程链接:http://video.jessetalk.cn/course/explore
良心课程,大家一起来学习哈!
任务31:课时介绍
- 1.Cookie-based认证与授权
- 2.Cookie-based认证实现
- 3.Jwt认证与授权介绍
- 4.Jwt认证与授权实现
- 5.Jwt认证与授权
- 6.Role based授权
- 7.Claims-based授权
任务32:Cookie-based认证介绍
任务34:Cookie-based认证实现
dotnet new mvc --name MvcCookieAuthSample
在Controllers文件夹新增AdminController.cs
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using MvcCookieAuthSample.Models;
namespace MvcCookieAuthSample.Controllers
{
public class AdminController : Controller
{
public IActionResult Index()
{
return View();
}
}
}
在Views文件夹新增Admin文件夹,在Admin文件夹新增Index.cshtml
@{
ViewData["Title"] = "Admin";
}
<h2>@ViewData["Title"]</h2>
<p>Admin Page</p>
启动项目,浏览器访问https://localhost:5001/Admin
实际情况不应该直接让用户访问到Admin页面,所以应当跳转到登陆界面
AdminController.cs
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using MvcCookieAuthSample.Models;
// 添加引用
using Microsoft.AspNetCore.Authorization;
namespace MvcCookieAuthSample.Controllers
{
public class AdminController : Controller
{
[Authorize]
public IActionResult Index()
{
return View();
}
}
}
startup.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
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;
// 添加引用
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Authentication.Cookies;
namespace MvcCookieAuthSample
{
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;
});
// Addmvc之前AddAuthentication,AddCookie
services.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme)
.AddCookie();
services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1);
}
// 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");
app.UseHsts();
}
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseCookiePolicy();
// UseMvc之前UseAuthentication,添加Middleware
app.UseAuthentication();
app.UseMvc(routes =>
{
routes.MapRoute(
name: "default",
template: "{controller=Home}/{action=Index}/{id?}");
});
}
}
}
再次访问https://localhost:5001/Admin,跳转到登陆界面https://localhost:5001/Account/Login?ReturnUrl=%2FAdmin
在Controllers文件夹新增AccountController.cs
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using MvcCookieAuthSample.Models;
// 添加引用
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Authentication;
using Microsoft.AspNetCore.Authentication.Cookies;
using System.Security.Claims;
namespace MvcCookieAuthSample.Controllers
{
[Authorize]
public class AccountController : Controller
{
public IActionResult MakeLogin()
{
var claims = new List<Claim>()
{
new Claim(ClaimTypes.Name,"Mingson"),
new Claim(ClaimTypes.Role,"admin")
};
var claimIdentity = new ClaimsIdentity(claims,CookieAuthenticationDefaults.AuthenticationScheme);
HttpContext.SignInAsync(CookieAuthenticationDefaults.AuthenticationScheme,new ClaimsPrincipal(claimIdentity));
return Ok();
}
public IActionResult Logout()
{
HttpContext.SignOutAsync(CookieAuthenticationDefaults.AuthenticationScheme);
return Ok();
}
}
}
启动项目
登出:localhost:5000/account/logout
访问admin:localhost:5000/admin,跳转到account/login
登陆:localhost:5000/account/makelogin
再次访问admin:localhost:5000/admin,登陆成功访问admin
任务35:JWT 认证授权介绍
可在官网解密:https://jwt.io
任务36:应用Jwtbearer Authentication
dotnet new webapi --name JwtAuthSample
dotnet watch run
打开postman调用
http://localhost:5000/api/values
ValuesController.cs
// 添加引用
using Microsoft.AspNetCore.Authorization;
// 添加特性
[Authorize]
[Route("api/[controller]")]
[ApiController]
public class ValuesController : ControllerBase
新增一个Models文件夹,在文件夹中新增JwtSettings.cs
namespace JwtAuthSample
{
public class JwtSettings
{
// token颁发者
public string Issure{get;set;}
// token使用的客户端
public string Audience{get;set;}
// 加密Key
public string SecretKey="hellokey";
}
}
appsettings.json
{
"Logging": {
"LogLevel": {
"Default": "Warning"
}
},
"AllowedHosts": "*",
"JwtSettings":{
"Audience":"http://localhost:5000",
"Issuer":"http://localhost:5000",
"SecretKey":"Hello-key"
}
}
Startup.cs
// 添加引用
using Microsoft.AspNetCore.Authentication.JwtBearer;
using Microsoft.IdentityModel.Tokens;
using System.Text;
// 添加在services.AddMvc()之前
services.Configure<JwtSettings>(Configuration);
var JwtSettings = new JwtSettings();
Configuration.Bind("JwtSettings",JwtSettings);
// 认证MiddleWare配置
services.AddAuthentication(options=>{
options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
})
// Jwt配置
.AddJwtBearer(o=>{
o.TokenValidationParameters = new Microsoft.IdentityModel.Tokens.TokenValidationParameters{
ValidIssuer = JwtSettings.Issure,
ValidAudience = JwtSettings.Audience,
IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(JwtSettings.SecretKey))// 对称加密
};
});
services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1);
app.UseHttpsRedirection();
// 添加在app.UseMvc()之前
app.UseAuthentication();
dotnet watch run
postman调用
http://localhost:5000/api/values
返回401,未授权
任务37:生成 JWT Token
新建文件夹ViewModels,在文件夹中新建LoginViewModel.cs
using System.ComponentModel.DataAnnotations;
namespace JwtAuthSample
{
public class LoginViewModel
{
[Required]
public string User{get;set;}
[Required]
public string Password{get;set;}
}
}
AuthorizeController.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
// 添加引用
using System.Security.Claims;
using Microsoft.IdentityModel.Tokens;
using Microsoft.Extensions.Options;
using System.Text;
using System.IdentityModel.Tokens.Jwt;
namespace JwtAuthSample.Controllers
{
[Route("api/[controller]")]
[ApiController]
public class AuthorizeController : ControllerBase
{
private JwtSettings _jwtSettings;
public AuthorizeController(IOptions<JwtSettings> _jwtSettingsAccesser)
{
_jwtSettings = _jwtSettingsAccesser.Value;
}
public IActionResult Token(LoginViewModel viewModel)
{
if (ModelState.IsValid)
{
if (!(viewModel.User == "mingson" && viewModel.Password == "123456"))
{
return BadRequest();
}
var claims = new Claim[]
{
new Claim(ClaimTypes.Name, "mingson"),
new Claim(ClaimTypes.Role, "admin")
};
var key = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(_jwtSettings.SecretKey));// 对称加密算法
var creds = new SigningCredentials(key, SecurityAlgorithms.HmacSha256);
// VSCode安装扩展NuGet Package Manager
// ctrl + shift + p
// NuGet Package Manager:Add Pcakage
// Microsoft.AspNetCore.Authentication.JwtBearer
// 需要FQ才能添加
// 2.0.0
// 安装到csproj
// 安装成功后csproj中出现<PackageReference Include="Microsoft.AspNetCore.Authentication.JwtBearer" Version="2.0.0" />
// dotnet restore
var token = new JwtSecurityToken(
_jwtSettings.Issure,
_jwtSettings.Audience,
claims,
DateTime.Now,
DateTime.Now.AddMinutes(30),
creds);
return Ok(new {token = new JwtSecurityTokenHandler().WriteToken(token)});
}
return BadRequest();
}
}
}
Startup.cs
// 添加在services.AddMvc()之前
//services.Configure<JwtSettings>(Configuration);// 获取不到JwtSettings配置
services.Configure<JwtSettings>(Configuration.GetSection("JwtSettings"));// 获取appsettings.json中的配置
appsettings.json
{
"Logging": {
"LogLevel": {
"Default": "Warning"
}
},
"AllowedHosts": "*",
"JwtSettings":{
"Audience":"http://localhost:5000",
"Issuer":"http://localhost:5000",
"SecretKey长度必须大于128bit=16字符":"",
"SecretKey":"Hello-key.jessetalk"
}
}
dotnet watch run
postman调用
http://localhost:5000/Authorize/Token
返回Token
加上token调用
http://localhost:5000/api/values
token可在官网解密:https://jwt.io
输入正确的SecretKey:Hello-key.jessetalk
任务38:JWT 设计解析及定制
新建文件MyTokenValidator.cs
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Logging;
// 添加引用
using Microsoft.AspNetCore.Authentication.JwtBearer;
using System.Security.Claims;
using Microsoft.IdentityModel.Tokens;
namespace JwtAuthSample
{
public class MyTokenValidator : ISecurityTokenValidator
{
bool ISecurityTokenValidator.CanValidateToken => true;
int ISecurityTokenValidator.MaximumTokenSizeInBytes { get;set; }
bool ISecurityTokenValidator.CanReadToken(string securityToken)
{
return true;
}
ClaimsPrincipal ISecurityTokenValidator.ValidateToken(string securityToken, TokenValidationParameters validationParameters, out SecurityToken validatedToken)
{
validatedToken = null;
var identity = new ClaimsIdentity(JwtBearerDefaults.AuthenticationScheme);
if (securityToken == "abcdefg")
{
identity.AddClaim(new Claim("name", "mingson"));
identity.AddClaim(new Claim("SuperAdminOnly", "true"));
identity.AddClaim(new Claim(ClaimsIdentity.DefaultNameClaimType, "user"));
}
var principal = new ClaimsPrincipal(identity);
return principal;
}
}
}
Startup.cs
// 认证MiddleWare配置
services.AddAuthentication(options=>{
options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
})
// Jwt配置
.AddJwtBearer(o=>{
// o.TokenValidationParameters = new Microsoft.IdentityModel.Tokens.TokenValidationParameters{
// ValidIssuer = JwtSettings.Issure,
// ValidAudience = JwtSettings.Audience,
// IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(JwtSettings.SecretKey))// 对称加密
// };
// 修改token来源
o.SecurityTokenValidators.Clear();// 一个包含验证的数组,先清除
o.SecurityTokenValidators.Add(new MyTokenValidator());
// 修改token验证方式
o.Events = new JwtBearerEvents(){
OnMessageReceived = context => {
var token = context.Request.Headers["mytoken"];
context.Token = token.FirstOrDefault();
return Task.CompletedTask;
}
};
});
services.AddAuthorization(Options=>{
Options.AddPolicy("SuperAdminOnly", policy => policy.RequireClaim("SuperAdminOnly"));
});
AuthorizeController.cs
// var claims = new Claim[]
// {
// new Claim(ClaimTypes.Name, "mingson"),
// new Claim(ClaimTypes.Role, "admin")
// };
var claims = new Claim[]
{
new Claim(ClaimTypes.Name, "mingson"),
new Claim(ClaimTypes.Role, "user"),
new Claim("SuperAdminOnly", "true")
};
ValuesController.cs
// [Authorize]// 添加标签
[Authorize(Policy="SuperAdminOnly")]
dotnet run
输入一个错误的mytoken,返回403 Forbidden,禁止访问
输入一个正确的mytoken,返回200 OK
任务39:Role以及Claims授权
Role授权
AuthorizeController.cs
var claims = new Claim[]
{
new Claim(ClaimTypes.Name, "mingson"),
new Claim(ClaimTypes.Role, "admin")
};
ValuesController.cs
[Authorize(Roles="user")]
dotnet run
带着token访问,返回403 Forbidden,禁止访问
AuthorizeController.cs修改为user,可访问
var claims = new Claim[]
{
new Claim(ClaimTypes.Name, "mingson"),
new Claim(ClaimTypes.Role, "user")
};
Claims授权
Startup.cs
// 认证MiddleWare配置
services.AddAuthentication(options=>{
options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
})
// Jwt配置
.AddJwtBearer(o=>{
o.TokenValidationParameters = new Microsoft.IdentityModel.Tokens.TokenValidationParameters{
ValidIssuer = JwtSettings.Issure,
ValidAudience = JwtSettings.Audience,
IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(JwtSettings.SecretKey))// 对称加密
};
});
services.AddAuthorization(Options=>{
Options.AddPolicy("SuperAdminOnly", policy => policy.RequireClaim("SuperAdminOnly"));
});
ValuesController.cs
[Authorize(Policy="SuperAdminOnly")]
AuthorizeController.cs
var claims = new Claim[]
{
new Claim(ClaimTypes.Name, "mingson"),
new Claim(ClaimTypes.Role, "user"),
new Claim("SuperAdminOnly", "true")
};
dotnet run
带着token访问,返回200 Ok
本作品采用知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议进行许可。
欢迎转载、使用、重新发布,但务必保留文章署名 郑子铭 (包含链接: http://www.cnblogs.com/MingsonZheng/ ),不得用于商业目的,基于本文修改后的作品务必以相同的许可发布。
如有任何疑问,请与我联系 (MingsonZheng@outlook.com) 。
ASP.NET Core快速入门(第5章:认证与授权)--学习笔记的更多相关文章
- ASP.NET Core快速入门--学习笔记系列文章索引目录
课程链接:http://video.jessetalk.cn/course/explore 良心课程,大家一起来学习哈! 抓住国庆假期的尾巴完成了此系列课程的学习笔记输出! ASP.NET Core快 ...
- 【笔记目录2】【jessetalk 】ASP.NET Core快速入门_学习笔记汇总
当前标签: ASP.NET Core快速入门 共2页: 上一页 1 2 任务27:Middleware管道介绍 GASA 2019-02-12 20:07 阅读:15 评论:0 任务26:dotne ...
- 【笔记目录1】【jessetalk 】ASP.NET Core快速入门_学习笔记汇总
当前标签: ASP.NET Core快速入门 共2页: 1 2 下一页 任务50:Identity MVC:DbContextSeed初始化 GASA 2019-03-02 14:09 阅读:16 ...
- ASP.NET Core 快速入门(Razor Pages + Entity Framework Core)
引子 自从 2009 年开始在博客园写文章,这是目前我写的最长的一篇文章了. 前前后后,我总共花了 5 天的时间,每天超过 3 小时不间断写作和代码调试.总共有 8 篇文章,每篇 5~6 个小结,总截 ...
- ASP.NET Core快速入门_学习笔记汇总
第2章 配置管理 任务12:Bind读取配置到C#实例 任务13:在Core Mvc中使用Options 任务14:配置的热更新 任务15:配置框架设计浅析 第3章 依赖注入 任务16:介绍- 任务1 ...
- ASP.NET Core快速入门学习笔记(第3章:依赖注入)
课程链接:http://video.jessetalk.cn/course/explore 良心课程,大家一起来学习哈! 任务16:介绍 1.依赖注入概念详解 从UML和软件建模来理解 从单元测试来理 ...
- ASP.NET Core快速入门学习笔记(第2章:配置管理)
课程链接:http://video.jessetalk.cn/course/explore 良心课程,大家一起来学习哈! 任务9:配置介绍 命令行配置 Json文件配置 从配置文件文本到c#对象实例的 ...
- ASP.NET Core快速入门学习笔记(第1章:介绍与引入)
课程链接:http://video.jessetalk.cn/course/explore 良心课程,大家一起来学习哈! 任务1:课程介绍 任务2:环境安装 下载地址:https://dotnet.m ...
- ASP.NET Core快速入门(第2章:配置管理)- 学习笔记(转载)
原文地址:https://mp.weixin.qq.com/s?__biz=MjM5NjMzMzE2MA==&mid=2451733443&idx=2&sn=6d01721c5 ...
- ASP.NET Core快速入门(第1章:介绍与引入)--学习笔记
课程链接:http://video.jessetalk.cn/course/explore 良心课程,大家一起来学习哈! 任务1:课程介绍 1.介绍与引入 2.配置管理 3.依赖注入 4.ASP.NE ...
随机推荐
- Python超详细的字符串用法大全
字符串拼接 实际场景:把列表中的数据拼接成一个字符串 解决方案:使用 str.join() 方法 >>> li = ['cxk', 'cxk', 'kk', 'caibi'] > ...
- 易优CMS:小白学代码之notempty
[基础用法] 名称:notempty 功能:判断某个变量是否为空,可以嵌套到任何标签里面使用,比如:channel.type等 语法: {eyou:notempty name='$eyou.field ...
- AppBoxFuture(九): 组织结构与权限体系
权限体系是用于约束用户访问或操作资源的权利,这里的"资源"可以指数据,也可以指特定的功能(如审核订单).通常的权限体系设计是基于角色的访问控制方式,用户通过角色与权限进行关联. ...
- Spring/Spring boot正确集成Quartz及解决@Autowired失效问题
周五检查以前Spring boot集成Quartz项目的时候,发现配置错误,因此通过阅读源码的方式,探索Spring正确集成Quartz的方式. 问题发现 检查去年的项目代码,发现关于QuartzJo ...
- 记录Flex布局的属性
容器属性 flex-dirextion(主轴的方向):>>row(水平) | row-reverse(水平取反) | column(垂直) | column-reverse(垂直取反) f ...
- bayaim_java_入门到精通_听课笔记bayaim_20181120
------------------java_入门到精通_听课笔记bayaim_20181120--------------------------------- Java的三种技术架构: JAVAE ...
- CodeForces - 1251B (思维+贪心)
题意 https://vjudge.net/problem/CodeForces-1251B n个01串,可以任意交换任意两个字符串的字符任意次,问最多能有多少个回文串. 思路 分类讨论可以发现规律: ...
- softmax求导、cross-entropy求导及label smoothing
softmax求导 softmax层的输出为 其中,表示第L层第j个神经元的输入,表示第L层第j个神经元的输出,e表示自然常数. 现在求对的导数, 如果j=i, 1 如果ji, 2 cross-e ...
- hibernate之主键生成策略
1. hibernate的主键生成器: generator元素:表示了一个主键生成器,它用来为持久化类实例生成唯一的标识 . 连接数据库的xml hibernate.cfg.xml <?xml ...
- 04-align-content 它对于当单行是没有效果的
/* 运用在父级元素上 align-content: 它通产与子元素的div{margin:10px 一起联合使用 }*/ ps==>用在子项出现换行的情况下,并是多行的情况下哦.运用在子 ...