【问题标题】:Error when trying to use JWT for ASP NET Owin Authentication?尝试使用 JWT 进行 ASP NET Owin 身份验证时出错?
【发布时间】:2021-04-16 04:40:23
【问题描述】:

我有以下配置:

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,该异常是

如果 IssuingSecurityTokenProvider 不是 SigningSecurityTokenProvider 则抛出。

有人能对此有所了解吗?

【问题讨论】:

  • 您找到解决问题的方法了吗?我偶然发现了同样的问题。
  • @stackunderflow 直到今天我都想不通,现在仍然没有。因此,为什么我根本没有尝试迁移到 JWT 的使用,而是坚持使用机器级令牌,这很糟糕,因为它们无法共享。如果您设法弄清楚这一点,为了我的一生,请将其发布为答案,我会为您提供赏金。

标签: c# asp.net authentication jwt owin


【解决方案1】:

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

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

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

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

【讨论】:

  • 我几乎已经设置好了,但我遇到了这个讨厌的错误Could not load file or assembly 'System.IdentityModel.Tokens.Jwt, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35' or one of its dependencies. The located assembly's manifest definition does not match the assembly reference. (Exception from HRESULT: 0x80131040) 上下文:&lt;dependentAssembly&gt; &lt;assemblyIdentity name="System.IdentityModel.Tokens.Jwt" publicKeyToken="31bf3856ad364e35" culture="neutral" /&gt; &lt;bindingRedirect oldVersion="0.0.0.0-4.0.0" newVersion="4.0.0" /&gt; &lt;/dependentAssembly&gt;
  • 查看 web.config 文件的程序集版本,并直接与程序集版本进行比较。有时 VS 不会正确更新 web.config 文件,我们必须手动更新 config 中的版本。就我而言,我使用的是最新版本,这里是设置
  • 谢谢你,昨天我解决了这个问题,似乎我必须将所有 owin 包更新到最新版本,因为有些包已经过时并且对从哪里加载资源感到困惑。
猜你喜欢
  • 2018-09-01
  • 2023-04-01
  • 2018-06-03
  • 2017-01-22
  • 2015-12-25
  • 2022-06-20
  • 2019-12-05
  • 2018-08-30
  • 1970-01-01
相关资源
最近更新 更多