霹雳小郭

JWT配置过程

1.添加NuGet包

        Microsoft.AspNetCore.Authentication.JwtBearer

2.添加JwtHelpres.cs类

  内容为以下

  using Microsoft.Extensions.Configuration;
  using Microsoft.IdentityModel.Tokens;
  using System;
  using System.Collections.Generic;
  using System.Security.Claims;
  using System.Text;
  using System.IdentityModel.Tokens.Jwt;

  namespace JwtAuthDemo.Helpers
  {
    public class JwtHelpers
  {
  private readonly IConfiguration Configuration;

  public JwtHelpers(IConfiguration configuration)
  {
    this.Configuration = configuration;
  }
  public string GenerateToken(string userName, int expireMinutes = 30)
  {
    var issuer = Configuration.GetValue<string>("JwtSettings:Issuer");
    var signKey = Configuration.GetValue<string>("JwtSettings:SignKey");

    // 設定要加入到 JWT Token 中的聲明資訊(Claims)
    var claims = new List<Claim>();

    // 在 RFC 7519 規格中(Section#4),總共定義了 7 個預設的 Claims,我們應該只用的到兩種!
    //claims.Add(new Claim(JwtRegisteredClaimNames.Iss, issuer));
    claims.Add(new Claim(JwtRegisteredClaimNames.Sub, userName)); // User.Identity.Name
    //claims.Add(new Claim(JwtRegisteredClaimNames.Aud, "The Audience"));
    //claims.Add(new Claim(JwtRegisteredClaimNames.Exp, DateTimeOffset.UtcNow.AddMinutes(30).ToUnixTimeSeconds().ToString()));
    //claims.Add(new Claim(JwtRegisteredClaimNames.Nbf, DateTimeOffset.UtcNow.ToUnixTimeSeconds().ToString())); // 必須為數字
    //claims.Add(new Claim(JwtRegisteredClaimNames.Iat, DateTimeOffset.UtcNow.ToUnixTimeSeconds().ToString())); // 必須為數字
    claims.Add(new Claim(JwtRegisteredClaimNames.Jti, Guid.NewGuid().ToString())); // JWT ID

    // 網路上常看到的這個 NameId 設定是多餘的
    //claims.Add(new Claim(JwtRegisteredClaimNames.NameId, userName));

    // 這個 Claim 也以直接被 JwtRegisteredClaimNames.Sub 取代,所以也是多餘的
    //claims.Add(new Claim(ClaimTypes.Name, userName));

    // 你可以自行擴充 "roles" 加入登入者該有的角色
    claims.Add(new Claim("roles", "Admin"));
    claims.Add(new Claim("roles", "Users"));

    var userClaimsIdentity = new ClaimsIdentity(claims);

    // 建立一組對稱式加密的金鑰,主要用於 JWT 簽章之用
    var securityKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(signKey));

    // HmacSha256 有要求必須要大於 128 bits,所以 key 不能太短,至少要 16 字元以上
    // https://stackoverflow.com/questions/47279947/idx10603-the-algorithm-hs256-requires-the-securitykey-keysize-to-be-greater
    var signingCredentials = new SigningCredentials(securityKey, SecurityAlgorithms.HmacSha256Signature);

    // 建立 SecurityTokenDescriptor
    var tokenDescriptor = new SecurityTokenDescriptor
    {
      Issuer = issuer,
      //Audience = issuer, // 由於你的 API 受眾通常沒有區分特別對象,因此通常不太需要設定,也不太需要驗證
      //NotBefore = DateTime.Now, // 預設值就是 DateTime.Now
      //IssuedAt = DateTime.Now, // 預設值就是 DateTime.Now
      Subject = userClaimsIdentity,
      Expires = DateTime.Now.AddMinutes(expireMinutes),
      SigningCredentials = signingCredentials
    };

    // 產出所需要的 JWT securityToken 物件,並取得序列化後的 Token 結果(字串格式)
    var tokenHandler = new JwtSecurityTokenHandler();
    var securityToken = tokenHandler.CreateToken(tokenDescriptor);
    var serializeToken = tokenHandler.WriteToken(securityToken);

    return serializeToken;
    }
  }
}

3.调整appsettings.json设定档

    "JwtSettings": {
    "Issuer": "JwtAuthDemo(随便定义)",
    "SignKey": "ABCDSDSDFGHNGFESDFSDF2902SDFGFDHGVCBCV(随便定义)"
    }

4.在startup.cs里注入

    services.AddSingleton<JwtHelpers>();

5.创建控制器

    (1).构造函数

    private readonly JwtHelpers _jwtHelpers;
    public LoginController(JwtHelpers jwtHelpers)
    {
      _jwtHelpers = jwtHelpers;
    }

    (2).创建方法测试JWT

    

 

 

6.开启验证

#region 开启Swagger认证
  c.AddSecurityDefinition("Bearer", new OpenApiSecurityScheme()
  {

    Description = "在下框中输入请求头中需要添加Jwt授权Token:Bearer Token",
    Name = "Authorization",
    In = ParameterLocation.Header,
    Type = SecuritySchemeType.ApiKey,
    BearerFormat = "JWT",
    Scheme = "Bearer"
  });

    c.AddSecurityRequirement(new OpenApiSecurityRequirement
    {
    {
    new OpenApiSecurityScheme
    {
    Reference = new OpenApiReference {
    Type = ReferenceType.SecurityScheme,
    Id = "Bearer"
    }
    },
    new string[] { }
    }
  });
#endregion

 

7.验证加授权

//验证
app.UseAuthentication();
//授权
app.UseAuthorization();

 

8.

services
.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
.AddJwtBearer(options =>
{
// 當驗證失敗時,回應標頭會包含 WWW-Authenticate 標頭,這裡會顯示失敗的詳細錯誤原因
options.IncludeErrorDetails = true; // 預設值為 true,有時會特別關閉

options.TokenValidationParameters = new TokenValidationParameters
{
// 透過這項宣告,就可以從 "sub" 取值並設定給 User.Identity.Name
NameClaimType = "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/nameidentifier",
// 透過這項宣告,就可以從 "roles" 取值,並可讓 [Authorize] 判斷角色
RoleClaimType = "http://schemas.microsoft.com/ws/2008/06/identity/claims/role",

// 一般我們都會驗證 Issuer
ValidateIssuer = true,
ValidIssuer = Configuration.GetValue<string>("JwtSettings:Issuer"),

// 通常不太需要驗證 Audience
ValidateAudience = false,
//ValidAudience = "JwtAuthDemo", // 不驗證就不需要填寫

// 一般我們都會驗證 Token 的有效期間
ValidateLifetime = true,

// 如果 Token 中包含 key 才需要驗證,一般都只有簽章而已
ValidateIssuerSigningKey = false,

// "1234567890123456" 應該從 IConfiguration 取得
IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(Configuration.GetValue<string>("JwtSettings:SignKey")))
};
});

posted on 2021-11-09 15:06  霹雳小郭  阅读(99)  评论(0)    收藏  举报

导航