• 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

    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

  • 相关阅读:
    IIS“服务没有及时响应启动或控制请求”错误解决
    CSS Overflow属性详解
    访问二维数组的实例ActionScript
    mailto语法
    IIS重新注册asp.net
    flash 动态文本 html
    C++继承中构造函数、析构函数调用顺序及虚析构函数
    根据指定两个日期计算出这些时间内有多少天是周末 php程序函数代码
    计算一段日期内的周末天数(星期六,星期日总和)(
    计算一段日期内的周末天数(星期六,星期日总和
  • 原文地址:https://www.cnblogs.com/bruce1992/p/15966485.html
Copyright © 2020-2023  润新知