I had the following configuration:
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());
I read somewhere that they added a JwtFormat
object I could use in the options, by setting AccessTokenFormat
, but when I did that and my options looked something like this:
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());
My OnGrantResourceOwnerCredentials
method throws an exception of MethodNotSupported
StackTrace:
[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
From what I've gathered, that exception is
Thrown if the IssuingSecurityTokenProvider is not a SigningSecurityTokenProvider.
Could anyone shine some light on this?
To generate JWT token, the library needs to execute the Protect() method. However Microsoft hasn't provided an implementation for the Protect() method (The error message gives a hint "Specified method is not supported" ). It only provides an implementation of Unprotect() method. You can verify this by peeking into the library using ILDASM.
So we cannot directly use AccessTokenFormat = new JwtFormat() to generate a JWT token. That being said, to generate a JWT token, you need to write a custom class which implements ISecureDataFormat interface. This interface provides two methods Protect() and Unprotect(). To generate JWT token, you only need to implement Protect() method and use this class as access token format.
The below link gives a very good explanation of how to implement this class and it's usage.
https://bitoftech.net/2014/10/27/json-web-token-asp-net-web-api-2-jwt-owin-authorization-server/