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


点“在看”给我一朵小黄花

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/312900.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Java HashSet的实现原理详解

HashSet是Java Map类型的集合类中最常使用的&#xff0c;本文基于Java1.8&#xff0c;对于HashSet的实现原理做一下详细讲解。 &#xff08;Java1.8源码&#xff1a;http://docs.oracle.com/javase/8/docs/api/&#xff09; 一、HashSet实现原理总结 HashSet的实现原理总结如下…

asp.net mvc 自定义 pager 封装与优化

asp.net mvc 自定义 pager 封装与优化Intro之前做了一个通用的分页组件&#xff0c;但是有些不足&#xff0c;从翻页事件和分页样式都融合在后台代码中&#xff0c;到翻页事件可以自定义&#xff0c;再到翻页和样式都和代码分离&#xff0c; 自定义分页 pager 越来越容易扩展了…

Java LinkedHashMap的实现原理详解

1. LinkedHashSet概述&#xff1a; LinkedHashSet是具有可预知迭代顺序的Set接口的哈希表和链接列表实现。此实现与HashSet的不同之处在于&#xff0c;后者维护着一个运行于所有条目的双重链接列表。此链接列表定义了迭代顺序&#xff0c;该迭代顺序可为插入顺序或是访问顺序…

.net core 中通过 PostConfigure 验证 Options 参数

.net core 中通过 PostConfigure 验证 Options 参数Intro在 .net core 中配置项推荐用 Options 来实现&#xff0c;有一些参数可能必须是用由用户来配置&#xff0c;不能直接写成默认值的参数&#xff0c;这样就需要就 Options 中的参数做一些校验&#xff0c;否则程序内部可能…

Spring配置错误java.lang.NoClassDefFoundError: org/springframework/jdbc/datasource/TransactionAwareDataS

在对Spring数据源dataSource配置之后&#xff0c;运行程序出现如下错误&#xff1a; java.lang.NoClassDefFoundError: org/springframework/jdbc/datasource/TransactionAwareDataSourceProxy 原因是项目没有导入spring-jdbc的jar包。 如果使用maven&#xff0c;可以直接在pom…

.NET做人脸识别并分类

前言在游乐场、玻璃天桥、滑雪场等娱乐场所&#xff0c;经常能看到有摄影师在拍照片&#xff0c;令这些经营者发愁的一件事就是照片太多了&#xff0c;客户在成千上万张照片中找到自己可不是件容易的事。在一次游玩等活动或家庭聚会也同理&#xff0c;太多了照片导致挑选十分困…

Java连接Mysql数据库警告:Establishing SSL connection without server's identity verification is not recommend

Java使用mysql-jdbc连接MySQL出现如下警告&#xff1a; Establishing SSL connection without servers identity verification is not recommended. According to MySQL 5.5.45, 5.6.26 and 5.7.6 requirements SSL connection must be established by default if explicit opt…

.NET Core 3.0中用 Code-First 方式创建 gRPC 服务与客户端

.NET Core ❤ gRPC千呼万唤的 .NET Core 3.0 终于在 9 月份正式发布&#xff0c;在它的众多新特性中&#xff0c;除了性能得到了大大提高&#xff0c;比较受关注的应该是 ASP.NET Core 3.0 对 gRPC 的集成了。它的源码托管在 grpc-dotnet 这个 Github 库中&#xff0c;由微软 .…

Spring集成Mybatis错误Result Maps collection already contains value for XXX

Spring在集成Mybatis出现如下错误&#xff1a; SpringResult Maps collection already contains value for com.guowei.maven.framework.dao.UserMapper.resultUser at org.mybatis.spring.SqlSessionFactoryBean.buildSqlSessionFactory(SqlSessionFactoryBean.java:468) at o…

dotnet Blazor 用 C# 控制界面行为

微软很久就在做 Blazor 但是我现在才开始创建一个测试项目&#xff0c;我想用 C# 去控制 HTML 界面。小伙伴也许会问现在前端不是烂大街么&#xff0c;为什么还需要 Blazor 来做。可能原因只有一个&#xff0c;就是可以使用 C# 写脚本&#xff0c;代码比较清真用 VisualStudio …

Spring集成Mybatis配置映射文件方法详解

Spring ORM模块集成Mybatis使用到了mybatis-spring&#xff0c;在配置mybatis映射文件的时候&#xff0c;一般不直接在Mybatis的配置文件里进行配置&#xff0c;而会在Spring的配置文件里使用MapperScannerConfigurer来配置。MapperScannerConfigurer会自动扫描basePackage指定…

2019年该学习哪门语言?建议学习C#语言

世界上只有少数几种语言是多功能的&#xff0c;而没有一个像C#那样干净整洁。作者 | Arctek译者 | 谭开朗&#xff0c;责编 | 郭芮出品 | CSDN&#xff08;ID&#xff1a;CSDNnews&#xff09;以下为译文&#xff1a;最直接的答案是&#xff1a;值得。但我想你不是来找这样的答…

Spring连接mysql数据库错误:Cannot load JDBC driver class '${driver}'

在用Spring使用连接mysql数据库时出现如下错误&#xff1a; Cause: org.springframework.jdbc.CannotGetJdbcConnectionException: Could not get JDBC Connection; nested exception isjava.sql.SQLException: Cannot load JDBC driver class ${driver} 错误详细信息如下&…

不一样的 SQL Server 日期格式化

不一样的 SQL Server 日期格式化Intro最近统计一些数据&#xff0c;需要按天/按小时/按分钟来统计&#xff0c;涉及到一些日期的格式化&#xff0c;网上看了一些文章大部分都是使用 CONVERT 来转换的&#xff0c;SQL Server 从 2012 开始增加了 FORMAT 方法&#xff0c;可以使用…

怕被政治烧到,RISC-V基金会决定迁址瑞士

由于政治影响&#xff0c;RISC-V 基金会决定迁址瑞士。FILE PHOTO: Technology on display at Huaweis headquarters in Shenzhen, Guangdong province, China May 29, 2019. REUTERS/Jason Lee去年 12 月份&#xff0c;RISC-V 基金会在一次会议上宣布&#xff0c;它将迁址到一…

进程和线程的状态

一、进程的基本状态 进程经常讨论的基本状态为&#xff1a;就绪状态&#xff08;Ready&#xff09;、运行状态&#xff08;Running&#xff09;、阻塞状态&#xff08;Blocked&#xff09;。此外&#xff0c;还包括不常讨论的创建和结束。 就绪状态&#xff1a;当进程已分配到除…

ASP.NET Core快速入门(第6章:ASP.NET Core MVC)--学习笔记

点击蓝字关注我们课程链接&#xff1a;http://video.jessetalk.cn/course/explore良心课程&#xff0c;大家一起来学习哈&#xff01;任务40&#xff1a;介绍1.Individual authentication 模板2.EF Core Migration3.Identity MVC&#xff1a;UI4.Identity MVC&#xff1a;EF I…

进程间通信的方式总结

进程间通信就是在不同进程之间传播或交换信息。 进程间通信的目的如下&#xff1a; ①数据传输&#xff1a;一个进程需要将它的数据发送给另一个进程&#xff0c;发送的数据量在一个字节到几兆字节之间。 ②共享数据&#xff1a;多个进程想要操作共享数据&#xff0c;一个进程对…

EF Core For MySql查询中使用DateTime.Now作为查询条件的一个小问题

背景最近一直忙于手上澳洲线上项目的整体迁移和升级的准备工作&#xff0c;导致博客和公众号停更。本周终于艰难的完成了任务&#xff0c;借此机会&#xff0c;总结一下项目中遇到的一些问题。EF Core 一直是我们团队中中小型项目常用的 ORM 框架&#xff0c;在使用 SQL Server…

操作系统进程(作业)调度常见算法详解

一、进程调度的原因 在操作系统中&#xff0c;由于进程综述多于处理机&#xff0c;它们必然竞争处理机。为了充分利用计算机系统中的CPU资源&#xff0c;让计算机系统能够多快好省地完成我们让它做的各种任务&#xff0c;所以需要进行进程调度。 二、进程调度的定义 进程调度&a…