尝试将 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/
我有以下配置:
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/