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 ...
随机推荐
- Java生鲜电商平台-电商会员体系系统的架构设计与源码解析
Java生鲜电商平台-电商会员体系系统的架构设计与源码解析 说明:Java生鲜电商平台中会员体系作为电商平台的基础设施,重要性不容忽视.我去年整理过生鲜电商中的会员系统,但是比较粗,现在做一个最好的整 ...
- Java生鲜电商平台-深入订单拆单架构与实战
Java生鲜电商平台-深入订单拆单架构与实战 Java生鲜电商中在做拆单的需求,细思极恐,思考越深入,就会发现里面涉及的东西越来越多,要想做好订单拆单的功能,还是相当有难度, 因此总结了一下拆单功能细 ...
- Java生鲜电商平台-App系统架构开发与设计
Java生鲜电商平台-App系统架构开发与设计 说明:阅读此文,你可以学习到以下的技术分享 1.Java生鲜电商平台-App架构设计经验谈:接口的设计2.Java生鲜电商平台-App架构设计经验谈:技 ...
- Javase之集合泛型
集合泛型知识 泛型 是一种把类型明确工作推迟到创建对象或者调用方法的时候才明确的特殊类型. 也称参数化类型,把类型当成参数传递. 在jdk1.5中出现.一般来说经常在集合中使用. 格式 <数据类 ...
- 查看UNDO 表空间使用情况
Select Sum(bytes / (1024 * 1024)), a.status From dba_undo_extents a Group By a.status Select fi ...
- centos 7下配置阿里yum源
1.打开centos的yum文件夹 cd /etc/yum.repos.d/ 2.用wget下载repo文件 wget http://mirrors.aliyun.com/repo/Centos-7. ...
- 七、数据提取之JSON与JsonPATH
JSON(JavaScript Object Notation) 是一种轻量级的数据交换格式,它使得人们很容易的进行阅读和编写.同时也方便了机器进行解析和生成.适用于进行数据交互的场景,比如网站前台与 ...
- SpringBoot+Mybatis多模块项目搭建教程
一.前言 框架为SpringBoot+Mybatis,本篇主要记录了在IDEA中搭建SpringBoot多模块项目的过程. 1.开发工具及系统环境 IDE:IntelliJ IDEA 2018.2 系 ...
- nginx典型官方模块解释
模块名称 作用 语法 默认 配置位置 配置举例 结果验证 备注 1 --with-http_stub_status_module 监控Nginx的服务器连接状态 stub_status serve ...
- Ambari 大数据集群管理
最近做了一个大数据项目,研究了下集群的搭建,现在将集群搭建整理的资料与大家分享一下!如有疑问可在评论区回复. 1前置配置 Centos7系统,每台系统都有java运行环境 全程使用root用户,避免安 ...