我正在使用基於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
?
你爲什麼不設置在STS壽命可以增加嗎? – leastprivilege 2013-03-15 05:44:53
發現它隱藏在STS的自定義SecurityTokenServiceConfiguration類中。它被硬編碼到10個小時。謝謝多米尼克。 – nickytonline 2013-03-15 15:13:59
我在這裏發佈了一個答案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