如何在websocket请求期间validationJWT。 .net核心

我正在开发一个使用JWT身份validation和websockets的小型.net核心应用程序。

我已经成功实现了为标准web api控制器生成和validation令牌。 但是,我还想validationWebSocket请求的令牌,这当然不适用于[Authorize]属性。

我已经设置了我的中间件管道,如下所示:

 app.UseWebSockets(); app.Use(async (http, next) => { if (http.WebSockets.IsWebSocketRequest == false) { await next(); return; } /// Handle websocket request here. How to check if token is valid? }); // secretKey contains a secret passphrase only your server knows var secretKey = .....; var signKey = new SigningCredentials ( new SymmetricSecurityKey(Encoding.ASCII.GetBytes(secretKey)), SecurityAlgorithms.HmacSha256 ); var tokenValidationParameters = new TokenValidationParameters { ValidateIssuer = false, ValidateAudience = false, // The signing key must match! ValidateIssuerSigningKey = true, IssuerSigningKey = signKey.Key, // Validate the token expiry ValidateLifetime = true, // If you want to allow a certain amount of clock drift, set that here: ClockSkew = TimeSpan.FromMinutes(1), }; app.UseJwtBearerAuthentication(new JwtBearerOptions { AutomaticAuthenticate = true, AutomaticChallenge = true, TokenValidationParameters = tokenValidationParameters }); 

我希望这可以帮助某人,即使这篇文章有点陈旧。

我找到了答案,不是谷歌搜索后,而是Binging ! 我从这个官方代码中获得灵感。

您可以使用JwtBearerOptions的魔力编写自己的类来处理授权。 这个类(希望如此)包含您自己validationJWT所需的一切。

因此,您必须将其作为服务注入,并使用它来配置您的身份validation。 你的Startup.ConfigureServices有类似的东西:

 this.JwtOptions = new JwtBearerOptions { AutomaticAuthenticate = true, AutomaticChallenge = true, TokenValidationParameters = yourTokenValidationParameters }; services.AddSingleton(this.JwtOptions); 

然后,您必须创建一个将validation您的令牌的类( 这是我的代码受到启发的地方 )。 我们称之为支持者,因为他已经得到了你的回复!:

 public class JwtBearerBacker { public JwtBearerOptions Options { get; private set; } public JwtBearerBacker(JwtBearerOptions options) { this.Options = options; } public bool IsJwtValid(string token) { List validationFailures = null; SecurityToken validatedToken; foreach (var validator in Options.SecurityTokenValidators) { if (validator.CanReadToken(token)) { ClaimsPrincipal principal; try { principal = validator.ValidateToken(token, Options.TokenValidationParameters, out validatedToken); } catch (Exception ex) { // Refresh the configuration for exceptions that may be caused by key rollovers. The user can also request a refresh in the event. if (Options.RefreshOnIssuerKeyNotFound && Options.ConfigurationManager != null && ex is SecurityTokenSignatureKeyNotFoundException) { Options.ConfigurationManager.RequestRefresh(); } if (validationFailures == null) validationFailures = new List(1); validationFailures.Add(ex); continue; } return true; } } return false; } } 

然后,在您的中间件中,只需访问请求标头, JwtOptions依赖项并调用Backer

  protected string ObtainAppTokenFromHeader(string authHeader) { if (string.IsNullOrWhiteSpace(authHeader) || !authHeader.Contains(" ")) return null; string[] authSchemeAndJwt = authHeader.Split(' '); string authScheme = authSchemeAndJwt[0]; if (authScheme != "Bearer") return null; string jwt = authSchemeAndJwt[1]; return jwt; } protected async Task AuthorizeUserFromHttpContext(HttpContext context) { var jwtBearerOptions = context.RequestServices.GetRequiredService() as JwtBearerOptions; string jwt = this.ObtainAppTokenFromHeader(context.Request.Headers["Authorization"]); if (jwt == null) return false; var jwtBacker = new JwtBearerBacker(jwtBearerOptions); return jwtBacker.IsJwtValid(jwt); } public async Task Invoke(HttpContext context) { if (!context.WebSockets.IsWebSocketRequest) return; if (!await this.AuthorizeUserFromHttpContext(context)) { context.Response.StatusCode = 401; await context.Response.WriteAsync("The door is locked, dude. You're not authorized !"); return; } //... Whatever else you're doing in your middleware } 

此外, AuthenticationTicket和有关auth的任何其他信息已经由框架的JwtBearerMiddleware处理,并且无论如何都将被返回。

最后,客户端。 我建议您使用实际支持其他HTTP标头的客户端库。 例如,据我所知,W3C Javascript客户端不提供此function。

这个给你! 感谢Microsoft的开源代码库。