编程语言
首页 > 编程语言> > ASP.NET Core快速入门(第5章:认证与授权)

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

任务32:Cookie-based认证介绍

任务34:Cookie-based认证实现

dotnet new mvc --name MvcCookieAuthSample

在Controllers文件夹新增AdminController.cs

  1.   using System;
  2.   using System.Collections.Generic;
  3.   using System.Diagnostics;
  4.   using System.Linq;
  5.   using System.Threading.Tasks;
  6.   using Microsoft.AspNetCore.Mvc;
  7.   using MvcCookieAuthSample.Models;
  8.    
  9.   namespace MvcCookieAuthSample.Controllers
  10.   {
  11.   public class AdminController : Controller
  12.   {
  13.   public IActionResult Index()
  14.   {
  15.   return View();
  16.   }
  17.   }
  18.   }

在Views文件夹新增Admin文件夹,在Admin文件夹新增Index.cshtml

  1.   @{
  2.   ViewData["Title"] = "Admin";
  3.   }
  4.   <h2>@ViewData["Title"]</h2>
  5.    
  6.   <p>Admin Page</p>

启动项目,浏览器访问https://localhost:5001/Admin

实际情况不应该直接让用户访问到Admin页面,所以应当跳转到登陆界面

AdminController.cs

  1.   using System;
  2.   using System.Collections.Generic;
  3.   using System.Diagnostics;
  4.   using System.Linq;
  5.   using System.Threading.Tasks;
  6.   using Microsoft.AspNetCore.Mvc;
  7.   using MvcCookieAuthSample.Models;
  8.   // 添加引用
  9.   using Microsoft.AspNetCore.Authorization;
  10.    
  11.   namespace MvcCookieAuthSample.Controllers
  12.   {
  13.   public class AdminController : Controller
  14.   {
  15.   [Authorize]
  16.   public IActionResult Index()
  17.   {
  18.   return View();
  19.   }
  20.   }
  21.   }

startup.cs

  1.   using System;
  2.   using System.Collections.Generic;
  3.   using System.Linq;
  4.   using System.Threading.Tasks;
  5.   using Microsoft.AspNetCore.Builder;
  6.   using Microsoft.AspNetCore.Hosting;
  7.   using Microsoft.AspNetCore.Http;
  8.   using Microsoft.AspNetCore.HttpsPolicy;
  9.   using Microsoft.AspNetCore.Mvc;
  10.   using Microsoft.Extensions.Configuration;
  11.   using Microsoft.Extensions.DependencyInjection;
  12.   // 添加引用
  13.   using Microsoft.AspNetCore.Authorization;
  14.   using Microsoft.AspNetCore.Authentication.Cookies;
  15.    
  16.   namespace MvcCookieAuthSample
  17.   {
  18.   public class Startup
  19.   {
  20.   public Startup(IConfiguration configuration)
  21.   {
  22.   Configuration = configuration;
  23.   }
  24.    
  25.   public IConfiguration Configuration { get; }
  26.    
  27.   // This method gets called by the runtime. Use this method to add services to the container.
  28.   public void ConfigureServices(IServiceCollection services)
  29.   {
  30.   services.Configure<CookiePolicyOptions>(options =>
  31.   {
  32.   // This lambda determines whether user consent for non-essential cookies is needed for a given request.
  33.   options.CheckConsentNeeded = context => true;
  34.   options.MinimumSameSitePolicy = SameSiteMode.None;
  35.   });
  36.    
  37.   // Addmvc之前AddAuthentication,AddCookie
  38.   services.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme)
  39.   .AddCookie();
  40.   services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1);
  41.   }
  42.    
  43.   // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
  44.   public void Configure(IApplicationBuilder app, IHostingEnvironment env)
  45.   {
  46.   if (env.IsDevelopment())
  47.   {
  48.   app.UseDeveloperExceptionPage();
  49.   }
  50.   else
  51.   {
  52.   app.UseExceptionHandler("/Home/Error");
  53.   app.UseHsts();
  54.   }
  55.    
  56.   app.UseHttpsRedirection();
  57.   app.UseStaticFiles();
  58.   app.UseCookiePolicy();
  59.    
  60.   // UseMvc之前UseAuthentication,添加Middleware
  61.   app.UseAuthentication();
  62.   app.UseMvc(routes =>
  63.   {
  64.   routes.MapRoute(
  65.   name: "default",
  66.   template: "{controller=Home}/{action=Index}/{id?}");
  67.   });
  68.   }
  69.   }
  70.   }

再次访问https://localhost:5001/Admin,跳转到登陆界面https://localhost:5001/Account/Login?ReturnUrl=%2FAdmin

在Controllers文件夹新增AccountController.cs

  1.   using System;
  2.   using System.Collections.Generic;
  3.   using System.Diagnostics;
  4.   using System.Linq;
  5.   using System.Threading.Tasks;
  6.   using Microsoft.AspNetCore.Mvc;
  7.   using MvcCookieAuthSample.Models;
  8.   // 添加引用
  9.   using Microsoft.AspNetCore.Authorization;
  10.   using Microsoft.AspNetCore.Authentication;
  11.   using Microsoft.AspNetCore.Authentication.Cookies;
  12.   using System.Security.Claims;
  13.    
  14.   namespace MvcCookieAuthSample.Controllers
  15.   {
  16.   [Authorize]
  17.   public class AccountController : Controller
  18.   {
  19.   public IActionResult MakeLogin()
  20.   {
  21.   var claims = new List<Claim>()
  22.   {
  23.   new Claim(ClaimTypes.Name,"Mingson"),
  24.   new Claim(ClaimTypes.Role,"admin")
  25.   };
  26.    
  27.   var claimIdentity = new ClaimsIdentity(claims,CookieAuthenticationDefaults.AuthenticationScheme);
  28.    
  29.   HttpContext.SignInAsync(CookieAuthenticationDefaults.AuthenticationScheme,new ClaimsPrincipal(claimIdentity));
  30.    
  31.   return Ok();
  32.   }
  33.    
  34.   public IActionResult Logout()
  35.   {
  36.   HttpContext.SignOutAsync(CookieAuthenticationDefaults.AuthenticationScheme);
  37.    
  38.   return Ok();
  39.   }
  40.   }
  41.   }

启动项目

登出: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

  1.   dotnet new webapi --name JwtAuthSample
  2.   dotnet watch run

打开postman调用
http://localhost:5000/api/values

ValuesController.cs

  1.   // 添加引用
  2.   using Microsoft.AspNetCore.Authorization;
  3.    
  4.   // 添加特性
  5.   [Authorize]
  6.   [Route("api/[controller]")]
  7.   [ApiController]
  8.   public class ValuesController : ControllerBase

新增一个Models文件夹,在文件夹中新增JwtSettings.cs

  1.   namespace JwtAuthSample
  2.   {
  3.   public class JwtSettings
  4.   {
  5.   // token颁发者
  6.   public string Issure{get;set;}
  7.   // token使用的客户端
  8.   public string Audience{get;set;}
  9.   // 加密Key
  10.   public string SecretKey="hellokey";
  11.   }
  12.   }

appsettings.json

  1.   {
  2.   "Logging": {
  3.   "LogLevel": {
  4.   "Default": "Warning"
  5.   }
  6.   },
  7.   "AllowedHosts": "*",
  8.   "JwtSettings":{
  9.   "Audience":"http://localhost:5000",
  10.   "Issuer":"http://localhost:5000",
  11.   "SecretKey":"Hello-key"
  12.   }
  13.   }

Startup.cs

  1.   // 添加引用
  2.   using Microsoft.AspNetCore.Authentication.JwtBearer;
  3.   using Microsoft.IdentityModel.Tokens;
  4.   using System.Text;
  5.    
  6.   // 添加在services.AddMvc()之前
  7.   services.Configure<JwtSettings>(Configuration);
  8.   var JwtSettings = new JwtSettings();
  9.   Configuration.Bind("JwtSettings",JwtSettings);
  10.   // 认证MiddleWare配置
  11.   services.AddAuthentication(options=>{
  12.   options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
  13.   options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
  14.   })
  15.   // Jwt配置
  16.   .AddJwtBearer(o=>{
  17.   o.TokenValidationParameters = new Microsoft.IdentityModel.Tokens.TokenValidationParameters{
  18.   ValidIssuer = JwtSettings.Issure,
  19.   ValidAudience = JwtSettings.Audience,
  20.   IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(JwtSettings.SecretKey))// 对称加密
  21.   };
  22.   });
  23.   services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1);
  24.    
  25.   app.UseHttpsRedirection();
  26.   // 添加在app.UseMvc()之前
  27.   app.UseAuthentication();
dotnet watch run

postman调用
http://localhost:5000/api/values
返回401,未授权

任务37:生成 JWT Token

新建文件夹ViewModels,在文件夹中新建LoginViewModel.cs

  1.   using System.ComponentModel.DataAnnotations;
  2.    
  3.   namespace JwtAuthSample
  4.   {
  5.   public class LoginViewModel
  6.   {
  7.   [Required]
  8.   public string User{get;set;}
  9.   [Required]
  10.   public string Password{get;set;}
  11.   }
  12.   }

AuthorizeController.cs

  1.   using System;
  2.   using System.Collections.Generic;
  3.   using System.Linq;
  4.   using System.Threading.Tasks;
  5.   using Microsoft.AspNetCore.Mvc;
  6.   // 添加引用
  7.   using System.Security.Claims;
  8.   using Microsoft.IdentityModel.Tokens;
  9.   using Microsoft.Extensions.Options;
  10.   using System.Text;
  11.   using System.IdentityModel.Tokens.Jwt;
  12.    
  13.   namespace JwtAuthSample.Controllers
  14.   {
  15.   [Route("api/[controller]")]
  16.   [ApiController]
  17.   public class AuthorizeController : ControllerBase
  18.   {
  19.   private JwtSettings _jwtSettings;
  20.    
  21.   public AuthorizeController(IOptions<JwtSettings> _jwtSettingsAccesser)
  22.   {
  23.   _jwtSettings = _jwtSettingsAccesser.Value;
  24.   }
  25.    
  26.   public IActionResult Token(LoginViewModel viewModel)
  27.   {
  28.   if (ModelState.IsValid)
  29.   {
  30.   if (!(viewModel.User == "mingson" && viewModel.Password == "123456"))
  31.   {
  32.   return BadRequest();
  33.   }
  34.    
  35.   var claims = new Claim[]
  36.   {
  37.   new Claim(ClaimTypes.Name, "mingson"),
  38.   new Claim(ClaimTypes.Role, "admin")
  39.   };
  40.    
  41.   var key = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(_jwtSettings.SecretKey));// 对称加密算法
  42.   var creds = new SigningCredentials(key, SecurityAlgorithms.HmacSha256);
  43.    
  44.   // VSCode安装扩展NuGet Package Manager
  45.   // ctrl + shift + p
  46.   // NuGet Package Manager:Add Pcakage
  47.   // Microsoft.AspNetCore.Authentication.JwtBearer
  48.   // 需要FQ才能添加
  49.   // 2.0.0
  50.   // 安装到csproj
  51.   // 安装成功后csproj中出现<PackageReference Include="Microsoft.AspNetCore.Authentication.JwtBearer" Version="2.0.0" />
  52.   // dotnet restore
  53.    
  54.   var token = new JwtSecurityToken(
  55.   _jwtSettings.Issure,
  56.   _jwtSettings.Audience,
  57.   claims,
  58.   DateTime.Now,
  59.   DateTime.Now.AddMinutes(30),
  60.   creds);
  61.    
  62.   return Ok(new {token = new JwtSecurityTokenHandler().WriteToken(token)});
  63.   }
  64.    
  65.   return BadRequest();
  66.   }
  67.   }
  68.   }

Startup.cs

  1.   // 添加在services.AddMvc()之前
  2.   //services.Configure<JwtSettings>(Configuration);// 获取不到JwtSettings配置
  3.   services.Configure<JwtSettings>(Configuration.GetSection("JwtSettings"));// 获取appsettings.json中的配置

appsettings.json

  1.   {
  2.   "Logging": {
  3.   "LogLevel": {
  4.   "Default": "Warning"
  5.   }
  6.   },
  7.   "AllowedHosts": "*",
  8.   "JwtSettings":{
  9.   "Audience":"http://localhost:5000",
  10.   "Issuer":"http://localhost:5000",
  11.   "SecretKey长度必须大于128bit=16字符":"",
  12.   "SecretKey":"Hello-key.jessetalk"
  13.   }
  14.   }
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

  1.   using System;
  2.   using System.Collections.Generic;
  3.   using System.IO;
  4.   using System.Linq;
  5.   using System.Threading.Tasks;
  6.   using Microsoft.AspNetCore;
  7.   using Microsoft.AspNetCore.Hosting;
  8.   using Microsoft.Extensions.Configuration;
  9.   using Microsoft.Extensions.Logging;
  10.   // 添加引用
  11.   using Microsoft.AspNetCore.Authentication.JwtBearer;
  12.   using System.Security.Claims;
  13.   using Microsoft.IdentityModel.Tokens;
  14.    
  15.   namespace JwtAuthSample
  16.   {
  17.   public class MyTokenValidator : ISecurityTokenValidator
  18.   {
  19.   bool ISecurityTokenValidator.CanValidateToken => true;
  20.    
  21.   int ISecurityTokenValidator.MaximumTokenSizeInBytes { get;set; }
  22.    
  23.   bool ISecurityTokenValidator.CanReadToken(string securityToken)
  24.   {
  25.   return true;
  26.   }
  27.    
  28.   ClaimsPrincipal ISecurityTokenValidator.ValidateToken(string securityToken, TokenValidationParameters validationParameters, out SecurityToken validatedToken)
  29.   {
  30.   validatedToken = null;
  31.   var identity = new ClaimsIdentity(JwtBearerDefaults.AuthenticationScheme);
  32.    
  33.   if (securityToken == "abcdefg")
  34.   {
  35.   identity.AddClaim(new Claim("name", "mingson"));
  36.   identity.AddClaim(new Claim("SuperAdminOnly", "true"));
  37.   identity.AddClaim(new Claim(ClaimsIdentity.DefaultNameClaimType, "user"));
  38.   }
  39.    
  40.   var principal = new ClaimsPrincipal(identity);
  41.    
  42.   return principal;
  43.   }
  44.   }
  45.   }

Startup.cs

  1.   // 认证MiddleWare配置
  2.   services.AddAuthentication(options=>{
  3.   options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
  4.   options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
  5.   })
  6.   // Jwt配置
  7.   .AddJwtBearer(o=>{
  8.   // o.TokenValidationParameters = new Microsoft.IdentityModel.Tokens.TokenValidationParameters{
  9.   // ValidIssuer = JwtSettings.Issure,
  10.   // ValidAudience = JwtSettings.Audience,
  11.   // IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(JwtSettings.SecretKey))// 对称加密
  12.   // };
  13.    
  14.   // 修改token来源
  15.   o.SecurityTokenValidators.Clear();// 一个包含验证的数组,先清除
  16.   o.SecurityTokenValidators.Add(new MyTokenValidator());
  17.    
  18.   // 修改token验证方式
  19.   o.Events = new JwtBearerEvents(){
  20.   OnMessageReceived = context => {
  21.   var token = context.Request.Headers["mytoken"];
  22.   context.Token = token.FirstOrDefault();
  23.   return Task.CompletedTask;
  24.   }
  25.   };
  26.   });
  27.    
  28.   services.AddAuthorization(Options=>{
  29.   Options.AddPolicy("SuperAdminOnly", policy => policy.RequireClaim("SuperAdminOnly"));
  30.   });

AuthorizeController.cs

  1.   // var claims = new Claim[]
  2.   // {
  3.   // new Claim(ClaimTypes.Name, "mingson"),
  4.   // new Claim(ClaimTypes.Role, "admin")
  5.   // };
  6.   var claims = new Claim[]
  7.   {
  8.   new Claim(ClaimTypes.Name, "mingson"),
  9.   new Claim(ClaimTypes.Role, "user"),
  10.   new Claim("SuperAdminOnly", "true")
  11.   };

ValuesController.cs

  1.   // [Authorize]// 添加标签
  2.   [Authorize(Policy="SuperAdminOnly")]
dotnet run

输入一个错误的mytoken,返回403 Forbidden,禁止访问

输入一个正确的mytoken,返回200 OK

任务39:Role以及Claims授权

Role授权

AuthorizeController.cs

  1.   var claims = new Claim[]
  2.   {
  3.   new Claim(ClaimTypes.Name, "mingson"),
  4.   new Claim(ClaimTypes.Role, "admin")
  5.   };

ValuesController.cs

    [Authorize(Roles="user")]
dotnet run

带着token访问,返回403 Forbidden,禁止访问

AuthorizeController.cs修改为user,可访问

  1.   var claims = new Claim[]
  2.   {
  3.   new Claim(ClaimTypes.Name, "mingson"),
  4.   new Claim(ClaimTypes.Role, "user")
  5.   };

Claims授权

Startup.cs

  1.   // 认证MiddleWare配置
  2.   services.AddAuthentication(options=>{
  3.   options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
  4.   options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
  5.   })
  6.   // Jwt配置
  7.   .AddJwtBearer(o=>{
  8.   o.TokenValidationParameters = new Microsoft.IdentityModel.Tokens.TokenValidationParameters{
  9.   ValidIssuer = JwtSettings.Issure,
  10.   ValidAudience = JwtSettings.Audience,
  11.   IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(JwtSettings.SecretKey))// 对称加密
  12.   };
  13.   });
  14.    
  15.   services.AddAuthorization(Options=>{
  16.   Options.AddPolicy("SuperAdminOnly", policy => policy.RequireClaim("SuperAdminOnly"));
  17.   });

ValuesController.cs

    [Authorize(Policy="SuperAdminOnly")]

AuthorizeController.cs

  1.   var claims = new Claim[]
  2.   {
  3.   new Claim(ClaimTypes.Name, "mingson"),
  4.   new Claim(ClaimTypes.Role, "user"),
  5.   new Claim("SuperAdminOnly", "true")
  6.   };
dotnet run

带着token访问,返回200 Ok

标签:Core,ASP,Claim,System,public,using,new,NET,Microsoft
来源: https://www.cnblogs.com/bruce1992/p/15966485.html