Asp.net-Mvc
JWT 身份驗證 ASP.NET Core MVC 應用程序
我已經看到了許多關於如何將 JWT 身份驗證與 Angular、React、Vue 等客戶端一起使用的範例,但找不到任何將 JWT 身份驗證與 ASP.NET Core(特別是 2.2)Web App Mvc 一起使用的範例。
有沒有人有任何關於如何做到這一點的例子或建議?
謝謝,
您可以使用基於 nuget 包 JWT 3.0.3 的此類
using JWT; using JWT.Algorithms; using JWT.Serializers; using Newtonsoft.Json; using System; namespace Common.Utils { public class JwtToken { private IJwtEncoder encoder; private IJwtDecoder decoder; /// <remarks> /// This requires a key value randomly generated and stored in your configuration settings. /// Consider that it is a good practice use keys as at least long as the output digest bytes /// length produced by the hashing algorithm used. Since we use an HMAC-SHA-512 algorithm, /// then we can provide it a key at least 64 bytes long. /// <see cref="https://tools.ietf.org/html/rfc4868#page-7"/> /// </remarks> public string SecretKey { get; set; } public JwtToken() { IJwtAlgorithm algorithm = new HMACSHA512Algorithm(); IJsonSerializer serializer = new JsonNetSerializer(); IDateTimeProvider datetimeProvider = new UtcDateTimeProvider(); IJwtValidator validator = new JwtValidator(serializer, datetimeProvider); IBase64UrlEncoder urlEncoder = new JwtBase64UrlEncoder(); encoder = new JwtEncoder(algorithm, serializer, urlEncoder); decoder = new JwtDecoder(serializer, validator, urlEncoder); SecretKey = ""; } public JwtToken(string secretKey) : this() { SecretKey = secretKey; } public bool IsTokenValid(string token) { return !string.IsNullOrWhiteSpace(DecodeToken(token)); } public string GetToken(object payload) { try { return encoder.Encode(payload, SecretKey); } catch (Exception) { return encoder.Encode(new DataModel(payload), SecretKey); } } public string DecodeToken(string token) { try { if (string.IsNullOrWhiteSpace(token) || token == "null") { return null; } return decoder.Decode(token, SecretKey, true); } catch (TokenExpiredException) { return null; } catch (SignatureVerificationException) { return null; } } public T DecodeToken<T>(string token) where T : class { try { if (string.IsNullOrWhiteSpace(token)) { return null; } return decoder.DecodeToObject<T>(token, SecretKey, true); } catch (TokenExpiredException) { return null; } catch (SignatureVerificationException) { return null; } catch (Exception) { var data = decoder.DecodeToObject<DataModel>(token, SecretKey, true).Data; return JsonConvert.DeserializeObject<T>(JsonConvert.SerializeObject(data)); } } } public class DataModel { public DataModel(object data) { Data = data; } public object Data { get; set; } } }然後在您的
Startup類Configure方法中設置 jwt 中間件以檢查每個請求的身份驗證狀態:app.Use((context, next) => { // verify app access token if not another service call var appAccessToken = context.Request.Headers["Authorization"]; if (appAccessToken.Count == 0) { context.Items["User"] = null; } else { var token = appAccessToken.ToString().Replace("Bearer ", ""); var jwtToken = new JwtToken(config.JwtTokenSecret); //you need a secret (with requirements specified above) in your configuration (db, appsettings.json) if (string.IsNullOrWhiteSpace(token) || !jwtToken.IsTokenValid(token)) { context.Response.StatusCode = 401; return Task.FromResult(0); } dynamic user = jwtToken.DecodeToken<dynamic>(token); var cachedToken = cache.Get(user.Id); //you need some cache for store your token after login success and so can check against if (cachedToken == null || cachedToken.ToString() != token) { context.Response.StatusCode = 401; return Task.FromResult(0); } context.Items["User"] = new Dictionary<string, string>() { { "FullName",user.Name?.ToString()}, { "FirstName",user.FirstName?.ToString()}, { "LastName",user.LastName?.ToString()}, { "Role",user.Role?.ToString()}, { "Email",user.Email?.ToString()} }; } return next(); });最後,您需要生成令牌並在身份驗證後返回它:
[AllowAnonymous] public IActionResult Login(string username, string password) { User user = null; //you need some User class with the structure of the previous dictionary if (checkAuthenticationOK(username, password, out user)) //chackAuthenticationOk sets the user against db data after a succesfull authentication { var token = new JwtToken(_config.JwtTokenSecret).GetToken(user); //_config is an object to your configuration _cache.Set(user.id, token); //store in the cache the token for checking in each request return Ok(token); } return StatusCode(401, "User is not authorized"); }