尝试将 JWT 用于 ASP NET Owin 身份验证时出错?

Error when trying to use JWT for ASP NET Owin Authentication?

我有以下配置:

var oAuthServerOptions = new OAuthAuthorizationServerOptions()
        {
            AllowInsecureHttp = true,
            TokenEndpointPath = new PathString("/api/token"),
            AuthorizeEndpointPath = new PathString("/api/authorize_endpoint"),
            AccessTokenExpireTimeSpan = TimeSpan.FromMinutes(int.Parse(ConfigurationManager.AppSettings["AccessTokenTimeSpanInMinutes"])),
            AuthorizationCodeExpireTimeSpan = TimeSpan.FromMinutes(5),
            Provider = new ApiAuthorizationServerProvider(userRepository, externalAppRepository),
            RefreshTokenProvider = new ApiRefreshTokenProvider(),
            AuthorizationCodeProvider = new ApiExternalAuthenticationTokenProvider(externalAppRepository)
        };

        // Token Generation
        app.UseOAuthAuthorizationServer(oAuthServerOptions);
        app.UseOAuthBearerAuthentication(new OAuthBearerAuthenticationOptions());

我在某处读到他们添加了一个 JwtFormat 对象,我可以通过设置 AccessTokenFormat 在选项中使用,但是当我这样做时,我的选项看起来像这样:

var oAuthServerOptions = new OAuthAuthorizationServerOptions()
        {
            AllowInsecureHttp = true,
            TokenEndpointPath = new PathString("/api/token"),
            AccessTokenFormat = new JwtFormat(new TokenValidationParameters
            {
                ValidateIssuerSigningKey = true,
                IssuerSigningKey = new SymmetricSecurityKey(Encoding.ASCII.GetBytes("secretkey")),
                ValidateLifetime = false,
                ValidateIssuer = false,
                ValidateAudience = false
            }),
            AuthorizeEndpointPath = new PathString("/api/authorize_endpoint"),
            AccessTokenExpireTimeSpan = TimeSpan.FromMinutes(int.Parse(ConfigurationManager.AppSettings["AccessTokenTimeSpanInMinutes"])),
            AuthorizationCodeExpireTimeSpan = TimeSpan.FromMinutes(5),
            Provider = new ApiAuthorizationServerProvider(userRepository, externalAppRepository),
            RefreshTokenProvider = new ApiRefreshTokenProvider(),
            AuthorizationCodeProvider = new ApiExternalAuthenticationTokenProvider(externalAppRepository)
        };

        // Token Generation
        app.UseOAuthAuthorizationServer(oAuthServerOptions);
        app.UseOAuthBearerAuthentication(new OAuthBearerAuthenticationOptions());

我的OnGrantResourceOwnerCredentials方法抛出异常MethodNotSupported

堆栈跟踪:

[NotSupportedException: Specified method is not supported.]
   Microsoft.Owin.Security.Jwt.JwtFormat.Protect(AuthenticationTicket data) +40
   Microsoft.Owin.Security.OAuth.<InvokeTokenEndpointAsync>d__8.MoveNext() +4143
   System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() +32
   System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) +62
   Microsoft.Owin.Security.OAuth.<InvokeAsync>d__5.MoveNext() +1098
   System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() +32
   System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) +62
   Microsoft.Owin.Security.Infrastructure.<Invoke>d__5.MoveNext() +517
   System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() +32
   System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) +62
   Microsoft.Owin.Host.SystemWeb.IntegratedPipeline.<RunApp>d__5.MoveNext() +197
   System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() +32
   System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) +62
   Microsoft.Owin.Host.SystemWeb.IntegratedPipeline.<DoFinalWork>d__2.MoveNext() +184
   System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() +32
   Microsoft.Owin.Host.SystemWeb.IntegratedPipeline.StageAsyncResult.End(IAsyncResult ar) +118
   System.Web.AsyncEventExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute() +510
   System.Web.HttpApplication.ExecuteStepImpl(IExecutionStep step) +220
   System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously) +134

what I've gathered开始,那个例外是

Thrown if the IssuingSecurityTokenProvider is not a SigningSecurityTokenProvider.

有人能对此有所启发吗?

要生成 JWT 令牌,库需要执行 Protect() 方法。但是微软并没有提供 Protect() 方法的实现(错误信息提示 "Specified method is not supported" )。它仅提供 Unprotect() 方法的实现。您可以使用 ILDASM 查看库来验证这一点。

所以我们不能直接使用AccessTokenFormat = new JwtFormat()来生成JWT token。 也就是说,要生成 JWT 令牌,您需要编写一个实现 ISecureDataFormat 接口的自定义 class。该接口提供了两个方法 Protect() 和 Unprotect()。要生成 JWT 令牌,您只需要实现 Protect() 方法并使用此 class 作为访问令牌格式。

下面的 link 很好地解释了如何实现这个 class 及其用法。

https://bitoftech.net/2014/10/27/json-web-token-asp-net-web-api-2-jwt-owin-authorization-server/