将 JWT 无状态身份验证从 Nancy 1.4.5 移植到 2.0.0

Porting JWT stateless authentication from Nancy 1.4.5 to 2.0.0

我在 Nancy 1.4.5 中实现了 JWT 无状态身份验证,它曾经运行良好。 将我的项目移植到 Nancy 2.0.0,身份验证机制不再起作用。

在引导程序的 ApplicationStartup 方法中,我有:

    protected override void ApplicationStartup(IKernel container, IPipelines pipelines)
    {
        #region JWT authentication
        // JWT stateless authentication, see: https://foreverframe.net/nancy-meets-jwt-authentication/
        var secretKey = LocalConstants.Authorization.SecretKey;
        string cryptografyAlgorithm = LocalConstants.Authorization.CryptografyAlgorithm;
        string bearerDeclaration = LocalConstants.Authorization.HttpHeaderBearerDeclaration;
        var identityProvider = new IdentityProvider(secretKey, cryptografyAlgorithm, bearerDeclaration);
        var statelessAuthConfig = new StatelessAuthenticationConfiguration(identityProvider.GetUserIdentity);
        StatelessAuthentication.Enable(pipelines, statelessAuthConfig);
        #endregion
        ...

在run-time,客户端可以执行登录并正确获取JWT。他们在后续请求中将 JWT 存储在 HTTP header 中。当后续请求到达服务器时,我的 identityProvider 的 GetUserIdentity 方法读取 JWT 并正确 returns 一个有效的 ClaimsPrincipals。

在我的模块中

 this.RequiresAuthentication();

,不过,抛出 Nancy.ErrorHandling.RouteExecutionEarlyExitException 的原因 "Requires Authentication",原因 "Requires Authentication" 和状态代码 Nancy.HttpStatusCode.Unauthorized.[=12 的响应 "Unauthorized text/html" =]

将无状态身份验证移植到 Nancy 2.0.0 的正确方法是什么?

自己找到解决方案:问题不在配置上,而是在服务器中使用 JWT 的方式上。作为参数传递给 StatelessAuthenticationConfiguration 对象的函数(在我的示例中为 identityProvider.GetUserIdentity)应该 return 一个 ClaimsIdentity,其身份已通过身份验证。

为此,传递 non-null、non-empty 字符串作为 authenticationType 参数,如下所示:

ClaimsIdentity claimsIdentity = new ClaimsIdentity(claims, "CustomAuthenticationType");

在我之前的尝试中,我只是通过了声明,导致 claimsIdentity 的 IsAuthenticated 属性 评估为 False。