课程链接: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章:认证与授权)--学习笔记的更多相关文章

  1. ASP.NET Core快速入门--学习笔记系列文章索引目录

    课程链接:http://video.jessetalk.cn/course/explore 良心课程,大家一起来学习哈! 抓住国庆假期的尾巴完成了此系列课程的学习笔记输出! ASP.NET Core快 ...

  2. 【笔记目录2】【jessetalk 】ASP.NET Core快速入门_学习笔记汇总

    当前标签: ASP.NET Core快速入门 共2页: 上一页 1 2  任务27:Middleware管道介绍 GASA 2019-02-12 20:07 阅读:15 评论:0 任务26:dotne ...

  3. 【笔记目录1】【jessetalk 】ASP.NET Core快速入门_学习笔记汇总

    当前标签: ASP.NET Core快速入门 共2页: 1 2 下一页  任务50:Identity MVC:DbContextSeed初始化 GASA 2019-03-02 14:09 阅读:16 ...

  4. ASP.NET Core 快速入门(Razor Pages + Entity Framework Core)

    引子 自从 2009 年开始在博客园写文章,这是目前我写的最长的一篇文章了. 前前后后,我总共花了 5 天的时间,每天超过 3 小时不间断写作和代码调试.总共有 8 篇文章,每篇 5~6 个小结,总截 ...

  5. ASP.NET Core快速入门_学习笔记汇总

    第2章 配置管理 任务12:Bind读取配置到C#实例 任务13:在Core Mvc中使用Options 任务14:配置的热更新 任务15:配置框架设计浅析 第3章 依赖注入 任务16:介绍- 任务1 ...

  6. ASP.NET Core快速入门学习笔记(第3章:依赖注入)

    课程链接:http://video.jessetalk.cn/course/explore 良心课程,大家一起来学习哈! 任务16:介绍 1.依赖注入概念详解 从UML和软件建模来理解 从单元测试来理 ...

  7. ASP.NET Core快速入门学习笔记(第2章:配置管理)

    课程链接:http://video.jessetalk.cn/course/explore 良心课程,大家一起来学习哈! 任务9:配置介绍 命令行配置 Json文件配置 从配置文件文本到c#对象实例的 ...

  8. ASP.NET Core快速入门学习笔记(第1章:介绍与引入)

    课程链接:http://video.jessetalk.cn/course/explore 良心课程,大家一起来学习哈! 任务1:课程介绍 任务2:环境安装 下载地址:https://dotnet.m ...

  9. ASP.NET Core快速入门(第2章:配置管理)- 学习笔记(转载)

    原文地址:https://mp.weixin.qq.com/s?__biz=MjM5NjMzMzE2MA==&mid=2451733443&idx=2&sn=6d01721c5 ...

  10. ASP.NET Core快速入门(第1章:介绍与引入)--学习笔记

    课程链接:http://video.jessetalk.cn/course/explore 良心课程,大家一起来学习哈! 任务1:课程介绍 1.介绍与引入 2.配置管理 3.依赖注入 4.ASP.NE ...

随机推荐

  1. 如何将vim改造为python的IDE

    前言 本文的文字及图片来源于网络,仅供学习.交流使用,不具有任何商业用途,版权归原作者所有,如有问题请及时联系我们以作处理. 作者: Jeffrey Wang PS:如有需要Python学习资料的小伙 ...

  2. PHP中设计模式以及魔术方法

    1.设计模式        1.1单例模式        口诀:三私一公 1.私有的静态属性用来保存对象的单例 2.私有的构造方法用来阻止在类的外部实例化 3.私有的__clone阻止在类的外部clo ...

  3. Vue模板语法中数据绑定

    1.单项数据绑定 <div id="di"> <input type="text" :value="input_val"& ...

  4. tinyriscv---一个从零开始写的极简、易懂的开源RISC-V处理器核

    本项目实现的是一个微riscv处理器核(tinyriscv),用verilog语言编写,只求以最简单.最通俗易懂的方式实现riscv指令的功能,因此没有特意去对代码做任何的优化,因此你会看到里面写的代 ...

  5. Eclipse修改JSP文件的默认编码

    Eclipse新建JSP文件,可以看到默认使用的是ISO-8859-1编码,如下图,而这种编码是无法保存中文的,不符合我们的需求 那么应该怎样修改呢?找到菜单Window-Preferences,找到 ...

  6. Python Pyinstaller 打包程序及遇到的问题总结

    一.如何打包py程序 1.安装打包模块 pip install pyinstaller 2.定义保存包的路径 CMD ,CD 比方:把最终*.exe运行文件,保存到H盘 install 文件夹下. 输 ...

  7. for循环结构

    循环结构: 在程序当中总有一些需要反复/重复的执行的代码,假设没有循环结构,那么这段需要重复知心的需要重复执行的代码自然是需要重复编写的,代码无法得到重复使用.所以多数变成语言都是支持循环结构的.将来 ...

  8. pyquery解析库

    这一篇整理一下pyquery这个解析库.还是菜,若有错误的地方,欢迎大家随时指正.......(come on.......) pyquery:是一个css选择器,再使用时,也需要传入HTML文本来初 ...

  9. 改名移动批量文件 shutil.copy

    import glob import os import shutil filePath = 'F:/project/Breast/InBreast/INBreast/imgout/' newFile ...

  10. LeetCode 268. Missing Number缺失数字 (C++/Java)

    题目: Given an array containing n distinct numbers taken from 0, 1, 2, ..., n, find the one that is mi ...