令牌问题在b2c-dotnet-webapp-and-webapi

时间:2017-03-24 15:38:14

标签: c# oauth asp.net-web-api2 owin azure-ad-b2c

我创建了一个b2c-dotnet-webapp-and-webapi类型的应用程序。但是20分钟后或者过了一段时间(差不多30分钟不确定)我的WebApp在Ajax调用401(未授权)期间抛出异常。当ajax调用命中WebApp控制器时会出现此异常所以此错误来自OWIN中间件,不确定原因。

我的Startup.cs设置

public void ConfigureAuth(IAppBuilder app)
        {
            app.SetDefaultSignInAsAuthenticationType(CookieAuthenticationDefaults.AuthenticationType);
            app.UseCookieAuthentication(new CookieAuthenticationOptions());
            app.UseOpenIdConnectAuthentication(CreateOptionsFromPolicy(_aadB2CPasswordResetPolicy));
            app.UseOpenIdConnectAuthentication(CreateOptionsFromPolicy(_aadB2CSignInPolicy));
        }

        private Task OnAuthenticationFailed(AuthenticationFailedNotification<OpenIdConnectMessage, OpenIdConnectAuthenticationOptions> context)
        {
            context.HandleResponse();
            if (context.Exception is OpenIdConnectProtocolInvalidNonceException &&
                context.Exception.Message.Contains("IDX10316"))
            {
                // Redirect to the originally requested URL
                context.Response.Redirect(context.Request.Uri.PathAndQuery);
            }
            else
            {
                var trackingId = Guid.NewGuid().ToString("N");
                _telemetry.TrackException(
                    context.Exception,
                    new Dictionary<string, string> {{"SignInErrorTrackingId", trackingId}});
                context.Response.Redirect($"/Home/SignInError?trackingId={trackingId}");
            }
            return Task.FromResult(0);
        }

        private OpenIdConnectAuthenticationOptions CreateOptionsFromPolicy(string policy)
        {
            return new OpenIdConnectAuthenticationOptions
            {
                // For each policy, give OWIN the policy-specific metadata address, and
                // set the authentication type to the id of the policy
                MetadataAddress = string.Format(_aadInstance, _tenant, policy),
                AuthenticationType = policy,

                // These are standard OpenID Connect parameters, with values pulled from web.config
                ClientId = _clientId,
                RedirectUri = _redirectUri,
                PostLogoutRedirectUri = _redirectUri,
                Notifications = new OpenIdConnectAuthenticationNotifications
                {
                    AuthenticationFailed = OnAuthenticationFailed,
                },
                Scope = "openid",
                ResponseType = "id_token",

                TokenValidationParameters = new TokenValidationParameters
                {
                    NameClaimType = "name",
                    SaveSigninToken = true,
                },
            };
        }
    } 

如果我正在修改代码

app.UseCookieAuthentication(new CookieAuthenticationOptions { SlidingExpiration = true, ExpireTimeSpan = TimeSpan.FromMinutes(60) });, 并在OpenIdConnectAuthenticationOptions中添加以下设置 UseTokenLifetime = false

然后我的WebApp工作了1个小时,之后我再次面对401 Unauthorized。这次我的WEAPI给出了这个错误,因为默认情况下令牌有效期为1小时。

问题:如果在ajax调用期间1小时后令牌过期,我该如何管理令牌问题?什么是我应该拥有的最佳设置所以我的中间件在20分钟或一些随机时间后不会给我401?

请注意,如果我做的话非常错误。我对此非常陌生并且没有太多想法。

1 个答案:

答案 0 :(得分:2)

你走在正确的轨道上!您需要注意以下几点:

Azure AD B2C返回的所有令牌都有到期时间。 x分钟后,您的ID令牌已过期。您需要再次通过登录过程再次获取新的ID令牌。

因为每隔x分钟登录很烦人,所以当用户第一次登录时,您可以请求刷新令牌。当id令牌过期时,您可以将刷新令牌发送到Azure AD B2C以获取新的ID令牌。

刷新令牌实现的一部分由库自动完成,但这是您需要实现的:

  1. 通过在responseType变量中添加“code”并在scope变量中添加“offline_access”,除了id标记之外还请求代码。
  2. 交换刷新令牌的代码并将令牌存储在缓存中。
  3. 在调用web api之前从缓存中获取令牌。如果令牌过期,库会自动为您续订,然后再将其拉出缓存。
  4. 所有这些都是在example中完成的。您只需要更新范围(当您未指定时,默认的responseType是“code id_token”)。

    注意:我们启用了access tokens并使用它更新了示例。请使用此更新的示例。您的代码反映了旧样本。我还建议在调用Web API时使用访问令牌而不是id令牌。