My method is not mainstream, but the control can be more flexible. Friends who like it, why not take some time to learn it?
JWT authentication is divided into two parts. The first part is encryption and decryption, and the second part is flexible to apply to middleware. My processing method is to put the acquisition token in a specific controller of the API, separate the issuance token from verification, and store the token's invalidation time, the issuer, user and other information in the config.
1. Configuration:
Add configuration in
"Jwt": { "Issuer": "issuer",//Define it at will"Audience": "Audience",//Define it at will"SecretKey": "abc",//Define it at will"Lifetime": 20, //Unit minute"ValidateLifetime": true,//Verification expiration time"HeadField": "useless", //Head field"Prefix": "prefix", //Prefix"IgnoreUrls": [ "/Auth/GetToken" ]//Ignore the url of verification}
2: Define the configuration class:
internal class JwtConfig { public string Issuer { get; set; } public string Audience { get; set; } /// <summary> /// Encryption key /// </summary> public string SecretKey { get; set; } /// <summary> /// life cycle /// </summary> public int Lifetime { get; set; } /// <summary> /// Whether to verify the life cycle /// </summary> public bool ValidateLifetime { get; set; } /// <summary> /// Verification header field /// </summary> public string HeadField { get; set; } /// <summary> /// jwt verification prefix /// </summary> public string Prefix { get; set; } /// <summary> /// Ignore the url for verification /// </summary> public List<string> IgnoreUrls { get; set; } }
3. Encryption and decryption interface:
public interface IJwt { string GetToken(Dictionary<string, string> Clims); bool ValidateToken(string Token,out Dictionary<string ,string> Clims); }
4. Encryption and decryption implementation class:
install -package public class Jwt : IJwt { private IConfiguration _configuration; private string _base64Secret; private JwtConfig _jwtConfig = new JwtConfig(); public Jwt(IConfiguration configration) { this._configuration = configration; ("Jwt").Bind(_jwtConfig); GetSecret(); } /// <summary> /// Get the encryption string /// </summary> private void GetSecret() { var encoding = new (); byte[] keyByte = ("salt"); byte[] messageBytes = (this._jwtConfig.SecretKey); using (var hmacsha256 = new HMACSHA256(keyByte)) { byte[] hashmessage = (messageBytes); this._base64Secret= Convert.ToBase64String(hashmessage); } } /// <summary> /// Generate Token /// </summary> /// <param name="Claims"></param> /// <returns></returns> public string GetToken(Dictionary<string, string> Claims) { List<Claim> claimsAll = new List<Claim>(); foreach (var item in Claims) { (new Claim(, )); } var symmetricKey = Convert.FromBase64String(this._base64Secret); var tokenHandler = new JwtSecurityTokenHandler(); var tokenDescriptor = new SecurityTokenDescriptor { Issuer = _jwtConfig.Issuer, Audience = _jwtConfig.Audience, Subject = new ClaimsIdentity(claimsAll), NotBefore = , Expires = (this._jwtConfig.Lifetime), SigningCredentials =new SigningCredentials(new SymmetricSecurityKey(symmetricKey), SecurityAlgorithms.HmacSha256Signature) }; var securityToken = (tokenDescriptor); return (securityToken); } public bool ValidateToken(string Token, out Dictionary<string, string> Clims) { Clims = new Dictionary<string, string>(); ClaimsPrincipal principal = null; if ((Token)) { return false; } var handler = new JwtSecurityTokenHandler(); try { var jwt = (Token); if (jwt == null) { return false; } var secretBytes = Convert.FromBase64String(this._base64Secret); var validationParameters = new TokenValidationParameters { RequireExpirationTime = true, IssuerSigningKey = new SymmetricSecurityKey(secretBytes), ClockSkew = , ValidateIssuer = true,//Whether to verify Issuer ValidateAudience = true,// Whether to verify Audience ValidateLifetime = this._jwtConfig.ValidateLifetime,//Whether to verify the expiration time ValidateIssuerSigningKey = true,//Whether to verify SecurityKey ValidAudience = this._jwtConfig.Audience, ValidIssuer = this._jwtConfig.Issuer }; SecurityToken securityToken; principal = (Token, validationParameters, out securityToken); foreach (var item in ) { (, ); } return true; } catch (Exception ex) { return false; } } }
5. Define the Controller to get the Token:
Inject IJwt in
<IJwt, Jwt>(); // Jwt injection [Route("[controller]/[action]")] [ApiController] public class AuthController : ControllerBase { private IJwt _jwt; public AuthController(IJwt jwt) { this._jwt = jwt; } /// <summary> /// getToken /// </summary> /// <returns></returns> [HttpPost] public IActionResult GetToken() { if (true) { Dictionary<string, string> clims = new Dictionary<string, string>(); ("userName", userName); return new JsonResult(this._jwt.GetToken(clims)); } } }
6. Create middleware:
public class UseJwtMiddleware { private readonly RequestDelegate _next; private JwtConfig _jwtConfig =new JwtConfig(); private IJwt _jwt; public UseJwtMiddleware(RequestDelegate next, IConfiguration configration,IJwt jwt) { _next = next; this._jwt = jwt; ("Jwt").Bind(_jwtConfig); } public Task InvokeAsync(HttpContext context) { if (_jwtConfig.()) { return this._next(context); } else { if ((this._jwtConfig.HeadField, out authValue)) { var authstr = (); if (this._jwtConfig. > 0) { authstr = ().Substring(this._jwtConfig.+1, ().Length -(this._jwtConfig.+1)); } if (this._jwt.ValidateToken(authstr, out Dictionary<string, string> Clims)) { foreach (var item in Clims) { (, ); } return this._next(context); } else { = 401; = "application/json"; return ("{\"status\":401,\"statusMsg\":\"auth vaild fail\"}"); } } else { = 401; = "application/json"; return ("{\"status\":401,\"statusMsg\":\"auth vaild fail\"}"); } } } }
7. Middleware is exposed
public static class UseUseJwtMiddlewareExtensions { /// <summary> /// Permission check /// </summary> /// <param name="builder"></param> /// <returns></returns> public static IApplicationBuilder UseJwt(this IApplicationBuilder builder) { return <UseJwtMiddleware>(); } }
8. Use middleware in:
();
Take the configuration of 1 as an example:
Except for requesting /auth/getToken, no header information is required, other requests must be included in the header information.
userless:prefix (fromAuth/GetTokenObtained intoken)
The above is all the content of this article. I hope it will be helpful to everyone's study and I hope everyone will support me more.