Microsoft.Owin.Security.OpenIdConnect 与 Azure Active Directory 身份验证票证生命周期 [英] Microsoft.Owin.Security.OpenIdConnect with Azure Active Directory authentication ticket lifetime

查看:18
本文介绍了Microsoft.Owin.Security.OpenIdConnect 与 Azure Active Directory 身份验证票证生命周期的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在构建一个多租户 Web 应用程序,该应用程序使用 Microsoft.Owin.Security.OpenIdConnect, Version=3.0.0.0 和带有 Microsoft.IdentityModel.Clients 的 Azure Active Directory 连接 Office 365 服务.ActiveDirectory, Version=2.19.0.0 遵循

我们遇到的问题是:我们的最终用户必须经常重新登录(少于一小时).那么问题来了,我们如何在这个 owin openidconnect 中间件中增加/更改身份验证票证的生命周期?

备注:我还在通过 ADAL 使用刷新令牌.据我们了解,这个问题只和认证有关.access_tokenrefresh_token 的生命周期是由 ActiveDirectory 客户端管理的授权问题,与此问题无关.如果我错了,请纠正我.

Startup.Auth.cs

公共部分类启动{公共常量字符串 CookieName = ".AspNet.MyName";公共常量 int DayExpireCookie = 30;公共无效 ConfigureAuth(IAppBuilder 应用程序){app.SetDefaultSignInAsAuthenticationType(CookieAuthenticationDefaults.AuthenticationType);var cookieAuthenticationOptions = 新的 CookieAuthenticationOptions(){Cookie 名称 = Cookie 名称,ExpireTimeSpan = TimeSpan.FromDays(DayExpireCookie),AuthenticationType = CookieAuthenticationDefaults.AuthenticationType,SlidingExpiration = true,};app.UseCookieAuthentication(cookieAuthenticationOptions);app.UseOpenIdConnectAuthentication(新的 OpenIdConnectAuthenticationOptions{ClientId = SettingsHelper.ClientId,权限 = SettingsHelper.Authority,ClientSecret = SettingsHelper.AppKey,UseTokenLifetime = true,TokenValidationParameters = 新 System.IdentityModel.Tokens.TokenValidationParameters{验证发行人 = 假},通知 = 新 OpenIdConnectAuthenticationNotifications(){//如果 OpenID Connect 响应中有代码,则将其兑换为访问令牌和刷新令牌,并将它们存储起来.AuthorizationCodeReceived = (上下文) =>{var 代码 = 上下文.代码;字符串tenantID = context.AuthenticationTicket.Identity.FindFirst("http://schemas.microsoft.com/identity/claims/tenantid").Value;字符串 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);//获取 AAD Graph 的访问令牌.这样做还将初始化与身份验证上下文关联的令牌缓存//理论上,您可以在此处为您的应用程序可以访问的任何服务获取令牌,以便您可以初始化令牌缓存Uri redirectUri = new Uri(HttpContext.Current.Request.Url.GetLeftPart(UriPartial.Path));AuthenticationResult 结果 = authContext.AcquireTokenByAuthorizationCode(code, redirectUri, credential, SettingsHelper.AADGraphResourceId);返回 Task.FromResult(0);},RedirectToIdentityProvider = (RedirectToIdentityProviderNotification<OpenIdConnectMessage, OpenIdConnectAuthenticationOptions> 上下文) =>{字符串 appBaseUrl = context.Request.Scheme + "://" + context.Request.Host + context.Request.PathBase;context.ProtocolMessage.RedirectUri = appBaseUrl + SettingsHelper.LoginRedirectRelativeUri;context.ProtocolMessage.PostLogoutRedirectUri = appBaseUrl + SettingsHelper.LogoutRedirectRelativeUri;返回 Task.FromResult(0);},AuthenticationFailed = (上下文) =>{context.HandleResponse();返回 Task.FromResult(0);}}});}}

账户控制人

公共类 AccountController : 控制器{公共无效登录(){var dateTimeOffset = DateTimeOffset.UtcNow;var authenticationProperties = 新的 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);}公共无效SignOut(){HttpContext.GetOwinContext().Authentication.SignOut(新的 AuthenticationProperties { RedirectUri = SettingsHelper.LogoutRedirectRelativeUri, },OpenIdConnectAuthenticationDefaults.AuthenticationType,CookieAuthenticationDefaults.AuthenticationType);}}

解决方案

其实,我需要设置 UseTokenLifetime = false.实际上,UseTokenLifetime = true 将 Asp.NET cookie 中的内部票据更改为默认的 access_token 生命周期,即一小时.@Tratcher 的评论是真实的,但误导了我......是的,access_token 生命周期由 Azure AD 控制,我对此无能为力.但是,我们使用 ADAL.NET 实现了 refresh_token 管理,因此可以将 Microsoft 身份服务器的身份验证/授权保持一小时以上.设置 UseTokenLifetTime = false 并使用 cookie 身份验证,在我的客户端应用程序和我的服务器之间的 15 天滑动到期时间现在就像一个魅力.

I am building a multi tenant web app that connects Office 365 services using Microsoft.Owin.Security.OpenIdConnect, Version=3.0.0.0 and Azure Active Directory with Microsoft.IdentityModel.Clients.ActiveDirectory, Version=2.19.0.0 following this sample.

Our web app client (user agent) is authenticated to our server using an asp.NET cookie while the authentication between our server and authority server (Azure AD here) is made with OpenID Authorization Code Flow.

We set for the Asp.NET cookie a 30 days sliding expiration for its lifetime. However we still have a short lived AuthenticationTicket from the Authority Server even when setting UseTokenLifetime= true which is supposed to match the lifetime of the two authentication mechanisms.

The problem we have is: our end-users must relog frequently (less than hour). The question is then, how do we increase/change the lifetime of the authentication ticket in this owin openidconnect middleware?

REMARK: I also posted a question on the usage of refresh tokens with ADAL. From what we have understood, this problem is only related to authentication. The lifetimes of the access_token and refresh_token which is an authorization concern managed by ActiveDirectory client are independent of this problem. Correct me if I am wrong.

Startup.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);
               }
           }
       });
  }
}

Account Controller

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);
     }
 }

解决方案

Actually, I needed to set UseTokenLifetime = false. Indeed, UseTokenLifetime = true changes the internal ticket in the Asp.NET cookie to the default lifetime of access_token which is one hour. The comments from @Tratcher were true but mislead me... Yes the access_token lifetime is controlled by Azure AD and there is nothing that I can do about it. But, we implemented the refresh_token management with ADAL.NET so there is a possibility to keep authentication/authorization with Microsoft Identity server for more than one hour. Setting UseTokenLifetTime = false and use cookie authentication with 15 days sliding expiry time between my client app and my server works like a charm now.

这篇关于Microsoft.Owin.Security.OpenIdConnect 与 Azure Active Directory 身份验证票证生命周期的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆