在OWIN JWT OAuth中使用Clockskew的正确方法

时间:2018-07-27 00:05:04

标签: c# asp.net jwt owin

我有一个使用以下软件包的应用程序

Autofac version="4.8.1" targetFramework="net471"
Autofac.Owin version="4.2.0" targetFramework="net471"
Autofac.WebApi2" version="4.2.0" targetFramework="net471"
Autofac.WebApi2.Owin" version="4.0.0" targetFramework="net471"
jose-jwt" version="2.4.0" targetFramework="net471"
Microsoft.AspNet.Cors" version="5.2.6" targetFramework="net471"
Microsoft.AspNet.WebApi.Client" version="5.2.6" targetFramework="net471"
Microsoft.AspNet.WebApi.Core" version="5.2.6" targetFramework="net471"
Microsoft.AspNet.WebApi.Owin" version="5.2.6" targetFramework="net471"
Microsoft.CodeDom.Providers.DotNetCompilerPlatform" version="1.0.7" targetFramework="net471"
Microsoft.IdentityModel.Logging" version="5.2.4" targetFramework="net471"
Microsoft.IdentityModel.Tokens" version="5.2.4" targetFramework="net471"
Microsoft.Net.Compilers" version="2.1.0" targetFramework="net471"
Microsoft.Owin" version="3.1.0" targetFramework="net471"
Microsoft.Owin.Cors" version="3.1.0" targetFramework="net471"
Microsoft.Owin.Host.SystemWeb" version="3.1.0" targetFramework="net471"
Microsoft.Owin.Security" version="3.1.0" targetFramework="net471"
Microsoft.Owin.Security.Jwt" version="3.1.0" targetFramework="net471"
Microsoft.Owin.Security.OAuth" version="3.1.0" targetFramework="net471"
Newtonsoft.Json" version="11.0.2" targetFramework="net471"
Owin" version="1.0" targetFramework="net471"
Serilog" version="2.7.1" targetFramework="net471"
Swashbuckle.Core" version="5.6.0" targetFramework="net471"
System.IdentityModel.Tokens.Jwt" version="4.0.4.403061554" targetFramework="net471"

服务器发行的令牌的有效时间为20分钟。

在资源服务器中,我具有以下配置

TokenValidationParameters tokenValidationParameters = new 
TokenValidationParameters()
{
     ClockSkew = TimeSpan.FromSeconds(_allowedClockDriftSeconds),
     IssuerSigningKey =   ...
     ValidateIssuer = true,
     ValidateAudience = true,
     RequireSignedTokens = true,
     ValidIssuer = "...",
     ValidAudience = "....",
 };

 app.UseJwtBearerAuthentication(new JwtBearerAuthenticationOptions
 {
      AuthenticationMode = AuthenticationMode.Active,
      AllowedAudiences = new[] { "ConsumerDataServices" },
      IssuerSecurityTokenProviders =  new IIssuerSecurityTokenProvider[]
      {...},
      TokenHandler = new JoseJwtTokenHandler(decryptionHandler, logger),
      TokenValidationParameters = tokenValidationParameters,
  });

Auth Server发行令牌作为JWE令牌。 JoseJwtTokenHandler正在重写ReadToken以解密并返回JWT令牌,

所有内容都能找到20分钟。我可以在AuthorizationFilterAttribut中的principal.Identity中看到我的声明。但是20分钟后,授权将不再作为principal.Identity.IsAuthenticated设置为false,并且声明为空。在调试时,我可以看到JoseJwtTokenHandler运行正常。

在我的日志中,我可以看到以下内容

Microsoft.Owin.Security.OAuth.OAuthBearerAuthenticationMiddleware警告:0:收到过期的承载令牌

查看Microsoft.Owin.Security.OAuth.OAuthBearerAuthenticationHandler的代码

DateTimeOffset currentUtc = this.Options.SystemClock.UtcNow;
if (ticket.Properties.ExpiresUtc.HasValue && ticket.Properties.ExpiresUtc.Value < currentUtc)
{
    this._logger.WriteWarning("expired bearer token received");
    return (AuthenticationTicket) null;
}

OAuthBearerAuthenticationHandler似乎忽略了ClockSkew。

我花了很多时间在上面,但无法正常工作。我在做什么看起来好吗?如果不是,正确的方法是什么?

1 个答案:

答案 0 :(得分:0)

我刚刚用JWT oAuth 2.0实现了OWIN。调试后我遇到了同样的问题,我知道我没有设置令牌发行者服务器的到期时间。默认情况下,其时间仅为20分钟。请在OAuthServerOptions中将AccessTokenExpireTimeSpan设置为您所需的时间,然后将其用作附件。以下是我的代码段,希望对您有所帮助。

   public void ConfigureOAuth(IAppBuilder app)
    {
        var authuri = ConfigurationManager.AppSettings["AuthURL"];
        var timeout = Convert.ToInt32(ConfigurationManager.AppSettings["SessionTimeOut"]);
        var AllowInsecureHttp = Convert.ToBoolean(ConfigurationManager.AppSettings["AllowInsecureHttp"]);

        OAuthAuthorizationServerOptions OAuthServerOptions = new OAuthAuthorizationServerOptions()
        {
            //Todo by Hasan : For Dev enviroment only (on production should be AllowInsecureHttp = false)
            AllowInsecureHttp = AllowInsecureHttp,
            TokenEndpointPath = new PathString("/oauth2/token"),
            AccessTokenExpireTimeSpan = TimeSpan.FromMinutes(timeout),
            Provider = new CustomOAuthProvider(),
            AccessTokenFormat = new CustomJwtFormat(authuri)
        };

        // OAuth 2.0 Bearer Access Token Generation
        app.UseOAuthAuthorizationServer(OAuthServerOptions);

    }