课程链接: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. 15个Python面试问题

    引言 想找一份Python开发工作吗?那你很可能得证明自己知道如何使用Python.下面这些问题涉及了与Python相关的许多技能,问题的关注点主要是语言本身,不是某个特定的包或模块.每一个问题都可以 ...

  2. Nginx+keepalived(高可用主备模式)

    Nginx+keepalived(高可用主备模式) 环境:centos6.7 准备:两台服务器(虚拟机).两台应用(Tomcat).Nginx.keepalived server1:192.168.2 ...

  3. 开源项目Telegram源码 Telegram for Android Source

    背景介绍 Telegram 是一款跨平台的即时通信软件,它的客户端是自由及开放源代码软件.用户可以相互交换加密与自毁消息,发送照片.影片等所有类型文件.官方提供手机版.桌面版和网页版等多种平台客户端. ...

  4. kettle教程---增量更新

    以下操作都在5.0.1版本下进行开发,其余版本可以进行自动比对 在平时工作当中,会遇到这种情况,而且很常见.比如:增量抽取(每隔2个小时抽取截至到上次抽取时间的记录) 一.操作前提: 存在3张表,源表 ...

  5. 【BZOJ1443】[JSOI2009]游戏Game(二分图+博弈)

    BZOJ 题意: 给出一个\(n*m\)的网格,其中有一些障碍点. 现在两个人玩游戏,首先先手选定一个点,然后从后手开始轮流移动,不能移动者即输掉这次游戏. 规定不能移动到那些之前已经到过的格子上. ...

  6. 压力测试中tps上不去的原因

    PS (transaction per second)代表每秒执行的事务数量,可基于测试周期内完成的事务数量计算得出.例如,用户每分钟执行6个事务,TPS为6 / 60s = 0.10 TPS. 同时 ...

  7. python 绘制词云图

    1. 先下载并安装nltk包,准备一张简单的图片存入代码所在文件目录,搜集英文停用词表 import nltk nltk.download() 2. 绘制词云图 import re import nu ...

  8. CF358D Dima and Hares

    CF358D Dima and Hares 洛谷评测传送门 题目描述 Dima liked the present he got from Inna very much. He liked the p ...

  9. 编译安装nmap

    官方编译文档 参考 安装对应的库,并编译安装.

  10. DRF--介绍和安装

    前后端不分离 在前后端不分离的应用模式中,前端页面看到的效果都是由后端控制,由后端渲染页面或重定向,也就是后端需要控制前端的展示,前端与后端的耦合度很高.这种应用模式比较适合纯网页应用,但是当后端对接 ...