ASP.NET Core快速入门(第5章:认证与授权)
作者:互联网
引用网址:
https://blog.csdn.net/lixiaoer757/article/details/105302750?spm=1001.2101.3001.6650.3&utm_medium=distribute.pc_relevant.none-task-blog-2%7Edefault%7EBlogCommendFromBaidu%7ERate-3.pc_relevant_paycolumn_v3&depth_1-utm_source=distribute.pc_relevant.none-task-blog-2%7Edefault%7EBlogCommendFromBaidu%7ERate-3.pc_relevant_paycolumn_v3&utm_relevant_index=6
-
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
标签:Core,ASP,Claim,System,public,using,new,NET,Microsoft 来源: https://www.cnblogs.com/bruce1992/p/15966485.html