1. 程式人生 > 其它 >.Net Core 使用JWT許可權驗證

.Net Core 使用JWT許可權驗證

什麼是JWT?

它是一種對API的保護方案(防洩漏,防攻擊,防止被人篡改)

一,下載相關NuGet包

  Microsoft.AspNetCore.Authentication.JwtBearer

  dotnet add package Microsoft.AspNetCore.Authentication.JwtBearer

二,建立JwtHelpers.cs(幫助類 生成Token)

  下面是JwtHelpers.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 有要求必須要大於128bits,所以 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; } } }

三,在appsettings.json檔案中寫好配置

{
  "JwtSettings": {
    "Issuer": "JwtAuthDemo",
    "SignKey": "1Zl4h9703IzROikK3@uK&&OEb"
  },
}

四,在Startup.cs中配置相關內容

  1,將類註冊進 .NET Core 的 DI 容器中:

services.AddSingleton<JwtHelpers>();

  2,讓你的 ASP.NET Core 能夠認得使用者傳入的 Bearer Token,這部分只要設定好即可:

services.AddSwaggerGen(c =>
            {
                c.SwaggerDoc("v1", new OpenApiInfo { Title = "jwtlianxi119", Version = "v1" });
                #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
            });

  3,在管道中設定(在 app.UseAuthorization() 之上:

app.UseAuthentication();

五,以下是 Web API 控制器的設計範例:

usingSystem.Linq;
usingJwtAuthDemo.Helpers;

using
Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Mvc; namespace JwtAuthDemo.Controllers { [Authorize] [ApiController] public class TokenController : ControllerBase { private readonly JwtHelpers jwt; public TokenController(JwtHelpers jwt) { this.jwt = jwt; } [AllowAnonymous] [HttpPost("~/signin")] public ActionResult<string> SignIn(LoginViewModel login) { if (ValidateUser(login)) {
          // login.Username使用者名稱
return jwt.GenerateToken(login.Username); } else { return BadRequest(); } }
     //登入 LoginViewModel 使用者登入類 包含Username Psaaword 等屬性
private bool ValidateUser(LoginViewModel login) { return true; // TODO }     
[HttpGet(
"~/claims")] public IActionResult GetClaims() { return Ok(User.Claims.Select(p => new { p.Type, p.Value })); } [HttpGet("~/username")] public IActionResult GetUserName() { return Ok(User.Identity.Name); }        [HttpGet("~/jwtid")] public IActionResult GetUniqueId() { var jti = User.Claims.FirstOrDefault(p => p.Type == "jti"); return Ok(jti.Value); } } }

注:一套連招下來 你的jwt token許可權驗證就配置成功了

[AllowAnonymous]可以取消對方法的驗證