代码之家  ›  专栏  ›  技术社区  ›  Benoit Patra

Microsoft.Owin.Security。OpenIdConnect与Azure Active Directory身份验证票证生存期

  •  13
  • Benoit Patra  · 技术社区  · 9 年前

    我正在构建一个多租户web应用程序,该应用程序使用 Microsoft.Owin.Security。OpenIdConnect,版本=3.0.0.0 和Azure Active Directory Microsoft.IdentityModel.Clients。ActiveDirectory,版本=2.19.0.0 下列的 this sample .

    我们的web应用程序客户端(用户代理)使用asp对服务器进行身份验证。NET cookie,而我们的服务器和授权服务器(此处为Azure AD)之间的身份验证是使用OpenID授权代码流进行的。

    我们出发去Asp。NET cookie的有效期为30天。然而,即使在设置 UseTokenLifetime=真 这应该与两种认证机制的寿命相匹配。 Short lived authentication ticket

    我们面临的问题是:我们的最终用户必须频繁地重新加载(少于一小时)。问题是, 我们如何在这个owin openidconnect中间件中增加/更改身份验证票证的寿命?

    备注:我还发布了 a question 关于ADAL刷新令牌的使用。 根据我们的理解,这个问题只与身份验证有关。的生命周期 访问标记 刷新标记 这是由ActiveDirectory客户端管理的授权问题。如果我错了,请纠正我。

    启动.Auth.cs

    public partial class Startup
    {
      public const string CookieName = ".AspNet.MyName";
      public const int DayExpireCookie = 30;
    
      public void ConfigureAuth(IAppBuilder app)
      {
       app.SetDefaultSignInAsAuthenticationType(CookieAuthenticationDefaults.AuthenticationType);
    
       var cookieAuthenticationOptions = new CookieAuthenticationOptions()
       {
           CookieName = CookieName,
           ExpireTimeSpan = TimeSpan.FromDays(DayExpireCookie),
           AuthenticationType = CookieAuthenticationDefaults.AuthenticationType,
           SlidingExpiration = true,
       };
    
       app.UseCookieAuthentication(cookieAuthenticationOptions);
    
       app.UseOpenIdConnectAuthentication(
           new OpenIdConnectAuthenticationOptions
           {
               ClientId = SettingsHelper.ClientId,
               Authority = SettingsHelper.Authority,
               ClientSecret = SettingsHelper.AppKey,
               UseTokenLifetime = true,
               TokenValidationParameters = new System.IdentityModel.Tokens.TokenValidationParameters
               {
                   ValidateIssuer = false
               },
    
               Notifications = new OpenIdConnectAuthenticationNotifications()
               {
                   // If there is a code in the OpenID Connect response, redeem it for an access token and refresh token, and store those away. 
                   AuthorizationCodeReceived = (context) =>
                   {
                       var code = context.Code;
                       string tenantID = context.AuthenticationTicket.Identity.FindFirst("http://schemas.microsoft.com/identity/claims/tenantid").Value;
                       string signInUserId = context.AuthenticationTicket.Identity.FindFirst(ClaimTypes.NameIdentifier).Value;
                       AuthenticationContext authContext = new AuthenticationContext(string.Format("{0}/{1}", SettingsHelper.AuthorizationUri, tenantID), new ADALTokenCache(signInUserId));
                       ClientCredential credential = new ClientCredential(SettingsHelper.ClientId, SettingsHelper.AppKey);
                       // Get the access token for AAD Graph. Doing this will also initialize the token cache associated with the authentication context
                       // In theory, you could acquire token for any service your application has access to here so that you can initialize the token cache
                       Uri redirectUri = new Uri(HttpContext.Current.Request.Url.GetLeftPart(UriPartial.Path));
                       AuthenticationResult result = authContext.AcquireTokenByAuthorizationCode(code, redirectUri, credential, SettingsHelper.AADGraphResourceId);
                       return Task.FromResult(0);
                   },
    
                   RedirectToIdentityProvider = (RedirectToIdentityProviderNotification<OpenIdConnectMessage, OpenIdConnectAuthenticationOptions> context) =>
                   {
                       string appBaseUrl = context.Request.Scheme + "://" + context.Request.Host + context.Request.PathBase;
                       context.ProtocolMessage.RedirectUri = appBaseUrl + SettingsHelper.LoginRedirectRelativeUri;
                       context.ProtocolMessage.PostLogoutRedirectUri = appBaseUrl + SettingsHelper.LogoutRedirectRelativeUri;
                       return Task.FromResult(0);
                   },
                   AuthenticationFailed = (context) =>
                   {
                       context.HandleResponse();
                       return Task.FromResult(0);
                   }
               }
           });
      }
    }
    

    账户控制员

    public class AccountController : Controller
    {
    
         public void SignIn()
         {
             var dateTimeOffset = DateTimeOffset.UtcNow;
             var authenticationProperties = new AuthenticationProperties
             {
                 AllowRefresh = true,
                 IssuedUtc = dateTimeOffset,
                 ExpiresUtc = dateTimeOffset.AddDays(Startup.DayExpireCookie -1),
                 RedirectUri = SettingsHelper.LoginRedirectRelativeUri, IsPersistent = true
             };
             HttpContext.GetOwinContext()
                 .Authentication.Challenge(authenticationProperties,OpenIdConnectAuthenticationDefaults.AuthenticationType, CookieAuthenticationDefaults.AuthenticationType);
         }
    
         public void SignOut()
         {
             HttpContext.GetOwinContext().Authentication.SignOut(
                 new AuthenticationProperties { RedirectUri = SettingsHelper.LogoutRedirectRelativeUri,  },
                 OpenIdConnectAuthenticationDefaults.AuthenticationType, CookieAuthenticationDefaults.AuthenticationType);
         }
     }
    
    1 回复  |  直到 8 年前
        1
  •  7
  •   Benoit Patra    9 年前

    事实上 我需要设置 UseTokenLifetime = false . 的确 UseTokenLifetime = true 更改Asp中的内部票证。NET cookie的默认生存期 access_token 这是一个小时。 @Tratcher的评论是真的,但误导了我…是的 访问标记 生命由Azure AD控制,对此我无能为力。但是,我们实施了 refresh_token ADAL的管理。NET,因此有可能将身份验证/授权与Microsoft Identity server保持一个小时以上。背景 UseTokenLifetTime = false 并且使用cookie身份验证,在我的客户端应用程序和服务器之间滑动15天的到期时间,现在效果很好。