2013-03-14 25 views
1

我正在使用基於WIF(.NET 4.0)的自定義STS,它目前僅用於SharePoint應用程序。我在預期的HTTP模塊中設置了滑動到期代碼,除了安全令牌的生命週期是10小時(默認生存時間)。SAML令牌僅在10小時後過期

/// <summary> 
/// Handles the SessionSecurityTokenReceived event of the SingleSignOnModule control. 
/// </summary> 
/// <param name="sender">The source of the event.</param> 
/// <param name="e">The <see cref="Microsoft.IdentityModel.Web.SessionSecurityTokenReceivedEventArgs"/> instance containing the event data.</param> 
private void SingleSignOnModule_SessionSecurityTokenReceived(Object sender, SessionSecurityTokenReceivedEventArgs e) 
{ 
    using (new SPMonitoredScope("SingleSignOnModule-SessionSecurityTokenReceived")) 
    { 
     if ((HttpContext.Current != null) && (FederatedAuthentication.SessionAuthenticationModule != null) && (e != null)) 
     { 
      TimeSpan logonTokenCacheExpirationWindow = TimeSpan.FromSeconds(1); 
      SPSecurity.RunWithElevatedPrivileges(delegate() 
      { 
       logonTokenCacheExpirationWindow = SPSecurityTokenServiceManager.Local.LogonTokenCacheExpirationWindow; 
      }); 

      DateTime currentDateTime = DateTime.UtcNow; 
      TimeSpan sessionLifetime = (e.SessionToken.ValidTo - e.SessionToken.ValidFrom); 
      DateTime sessionValidFrom = e.SessionToken.ValidFrom; 
      DateTime sessionValidTo = (e.SessionToken.ValidTo - logonTokenCacheExpirationWindow); 

      if ((currentDateTime < sessionValidTo) && (currentDateTime > sessionValidFrom.AddMinutes(sessionLifetime.TotalMinutes/2))) 
      { 
       e.SessionToken = FederatedAuthentication.SessionAuthenticationModule.CreateSessionSecurityToken(e.SessionToken.ClaimsPrincipal, e.SessionToken.Context, currentDateTime, currentDateTime.AddMinutes(sessionLifetime.TotalMinutes), e.SessionToken.IsPersistent); 
       e.ReissueCookie = true; 
      } 
     } 
    } 
} 

最初,我認爲這可能只是由SPSecurityTokenServiceManager設置。但是,這並沒有改變。 (PowerShell的片段)

Write-Output("[INFO] Updating the SPSecurityTokenServiceManager") 
$stsMgr = Get-SPSecurityTokenServiceConfig 

Write-Output("[INFO] Updating the SPSecurityTokenServiceManager to use session cookies.") 
$stsMgr.UseSessionCookies = $true; # 

Write-Output("[INFO] Updating the SPSecurityTokenServiceManager logon token cache expiration window") 
$stsMgr.LogonTokenCacheExpirationWindow = New-TimeSpan -Days 0 -Hours 0 -Minutes 1 

Write-Output("[INFO] Updating the SPSecurityTokenServiceManager service token cache expiration window.") 
$stsMgr.ServiceTokenCacheExpirationWindow = New-TimeSpan -Days 0 -Hours 0 -Minutes 20 

$stsMgr.Update() 

我不能因爲它的只讀並設置爲10小時設置SessionSecurityTokenHandler.DefaultLifetime。

// Type: Microsoft.IdentityModel.Tokens.SecurityTokenHandler 
// Assembly: Microsoft.IdentityModel, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35 
// Assembly location: C:\Windows\assembly\GAC_MSIL\Microsoft.IdentityModel\3.5.0.0__31bf3856ad364e35\Microsoft.IdentityModel.dll 

namespace Microsoft.IdentityModel.Tokens 
{ 
    public class SessionSecurityTokenHandler : SecurityTokenHandler 
    { 
     public static readonly TimeSpan DefaultLifetime = TimeSpan.FromHours(10.0); 
     ... 
    } 
} 

的SecurityToken.ValidTo只有一個getter不是setter。

// Type: System.IdentityModel.Tokens.SecurityToken 
// Assembly: System.IdentityModel, Version=3.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 
// Assembly location: C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\v3.0\System.IdentityModel.dll 

namespace System.IdentityModel.Tokens 
{ 
    /// <summary> 
    /// Represents a base class used to implement all security tokens. 
    /// </summary> 
    /// <filterpriority>2</filterpriority> 
    public abstract class SecurityToken 
    { 
     ... 

     /// <summary> 
     /// Gets the last instant in time at which this security token is valid. 
     /// </summary> 
     /// 
     /// <returns> 
     /// A <see cref="T:System.DateTime"/> that represents the last instant in time at which this security token is valid. 
     /// </returns> 
     /// <filterpriority>2</filterpriority> 
     public abstract DateTime ValidTo { get; } 

     ... 
    } 
} 

我也注意到,在FederatedAuthentication.SessionAuthenticationModule.CreateSessionSecurityToken,默認ValidTo屬性設置爲ValidFrom +默認令牌生存。我可以看到設置SecurityToken.ValidTo的唯一方法是在創建安全令牌時。這是否意味着我需要實現一個自定義的SecurityToken類,或者在WIF堆棧中的某處是否可以攔截創建令牌?到目前爲止,我似乎只發現了以下事件處理程序FederatedAuthentication.SessionAuthenticationModule.SessionSecurityTokenCreated,但此時該令牌已經創建,並且在那裏我可以訪問該令牌,但正如預期的那樣,SecurityToken.ValidTo屬性只是一個吸氣劑。

以及<microsoft.identityModel /> config部分似乎沒有爲此設置。有一個persistenLifeTime設置,但這僅適用於寫入磁盤的cookie。

<microsoft.identityModel> 
     <federatedAuthentication> 
     <wsFederation 
      persistentCookiesOnPassiveRedirects="true" /> 
     <cookieHandler 
      persistentSessionLifetime="60.0:0:0" /> 
     </federatedAuthentication> 
</microsoft.identityModel> 

此外,爲了使加密/解密成爲服務器不可知的,加密使用證書。爲此,我將編程添加到我的聯合身份驗證提供程序的Global.asax中的會話安全令牌處理程序。我只提到這一點,因爲我想知道,如果我需要自定義SecurityToken.ValidTo,我可能需要創建一個自定義安全令牌處理程序類,或者我目前正在Global.asax罰款,我需要看其他地方解決SecurityToken.ValidTo問題?

<microsoft.identityModel> 
    <service> 
     <serviceCertificate> 
     <certificateReference x509FindType="FindByThumbprint" findValue="myThumbPrint" /> 
     </serviceCertificate> 
     ... 
    </microsoft.identityModel> 

namespace MyCompany.IdentityServer.FederationProvider 
{ 
    public class Global : System.Web.HttpApplication 
    { 
     /// <summary> 
     /// Handles the Start event of the Application control. 
     /// </summary> 
     /// <param name="sender">The source of the event.</param> 
     /// <param name="e">The <see cref="System.EventArgs"/> instance containing the event data.</param> 
     protected void Application_Start(object sender, EventArgs e) 
     { 
      FederatedAuthentication.ServiceConfigurationCreated += OnServiceConfigurationCreated; 
     } 

     /// <summary> 
     /// Called when [service configuration created]. 
     /// </summary> 
     /// <param name="sender">The sender.</param> 
     /// <param name="e">The <see cref="Microsoft.IdentityModel.Web.Configuration.ServiceConfigurationCreatedEventArgs"/> instance containing the event data.</param> 
     private void OnServiceConfigurationCreated(object sender, ServiceConfigurationCreatedEventArgs e) 
     { 
      // The session security token handler needs to be overridden so that encryption/decryption is not server dependent via DPAPI. 
      // We need encryption/decryption to be server agnostic, so we make it certificate based instead. 
      // See http://blogs.msdn.com/b/distributedservices/archive/2012/10/29/wif-1-0-id1073-a-cryptographicexception-occurred-when-attempting-to-decrypt-the-cookie-using-the-protecteddata-api.aspx 

      // Use the <serviceCertificate> to protect the cookies that are 
      // sent to the client. 
      var sessionTransforms = 
       new List<CookieTransform>(new CookieTransform[] { 
       new DeflateCookieTransform(), 
       new RsaEncryptionCookieTransform(e.ServiceConfiguration.ServiceCertificate), 
       new RsaSignatureCookieTransform(e.ServiceConfiguration.ServiceCertificate) }); 

      var sessionHandler = new SessionSecurityTokenHandler(sessionTransforms.AsReadOnly()); 

      // This does nothing 
      //sessionHandler.TokenLifetime = someLifeTime; 

      e.ServiceConfiguration.SecurityTokenHandlers.AddOrReplace(sessionHandler); 
     } 
    } 
} 

如果我創建一個自定義securityTokenHandler,我看到,我可以指定一個有效期,但是這看起來像什麼,我試圖在我的Global.asax以上,sessionHandler.TokenLifetime = ...

<microsoft.identityModel> 
    <service> 
     <securityTokenHandlers> 
      <add type="System.IdentityModel.Tokens.SessionSecurityTokenHandler, System.IdentityModel"> 
      <sessionTokenRequirement lifetime="TimeSpan" /> 
      </add> 
     </securityTokenHandlers> 
     ... 
    </service> 
</microsoft.identityModel> 

我只能假設我錯過了一些明顯的設置,或者是我唯一需要定製的SecurityToken.ValidTo

+1

你爲什麼不設置在STS壽命可以增加嗎? – leastprivilege 2013-03-15 05:44:53

+0

發現它隱藏在STS的自定義SecurityTokenServiceConfiguration類中。它被硬編碼到10個小時。謝謝多米尼克。 – nickytonline 2013-03-15 15:13:59

+0

我在這裏發佈了一個答案http:// stackoverflow。com/questions/17099727/expiration-time-buffer-of-sessionsecuritytokenhandler-of-wif-4-5-in-azure-web,它顯示瞭如何從Relying Party中覆蓋SAML的「ValidTo」。以防萬一您無法直接更改STS。 – 2014-05-23 19:40:48

回答

2

在STS中 - 在SecurityTokenConfigurationConfiguration類上設置DefaultTokenLifetime屬性以覆蓋默認的10h。

0

使用此PowerShell腳本

$sts = Get-SPSecurityTokenServiceConfig 
$sts.FormsTokenLifeTime = (New-TimeSpan -minutes <NUMBER_OF_MINUTES>) 
$sts.Update() 
Get-SPSecurityTokenServiceConfig