You've already forked linux-packaging-mono
Imported Upstream version 4.6.0.125
Former-commit-id: a2155e9bd80020e49e72e86c44da02a8ac0e57a4
This commit is contained in:
parent
a569aebcfd
commit
e79aa3c0ed
@ -0,0 +1,208 @@
|
||||
//------------------------------------------------------------------------------
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.IdentityModel;
|
||||
using System.IdentityModel.Selectors;
|
||||
using System.IdentityModel.Tokens;
|
||||
using System.ServiceModel.Security.Tokens;
|
||||
|
||||
using SystemUniqueId = System.Xml.UniqueId;
|
||||
using SR = System.ServiceModel.SR;
|
||||
|
||||
namespace System.ServiceModel.Security
|
||||
{
|
||||
|
||||
/// <summary>
|
||||
/// The purpose of this class is to provide an ISecurityContextSecurityTokenCache contract over a SecurityTokenCache.
|
||||
/// This allows for a consistent interface for the SecurityContextSecurityTokenHandler and a SessionSecurityTokenHandler.
|
||||
/// The SecurityTokenCache can be passed to the SecurityContextSecurityTokenHandler and wrapped to expose an ISecurityContextSecurityTokenCache
|
||||
/// that can be set to the be the token cache for WCF context tokens
|
||||
/// </summary>
|
||||
class WrappedTokenCache : SecurityTokenResolver, ISecurityContextSecurityTokenCache
|
||||
{
|
||||
SessionSecurityTokenCache _tokenCache;
|
||||
SctClaimsHandler _claimsHandler;
|
||||
|
||||
public WrappedTokenCache(SessionSecurityTokenCache tokenCache, SctClaimsHandler sctClaimsHandler)
|
||||
{
|
||||
if (tokenCache == null)
|
||||
{
|
||||
throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("tokenCache");
|
||||
}
|
||||
|
||||
if (sctClaimsHandler == null)
|
||||
{
|
||||
throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("sctClaimsHandler");
|
||||
}
|
||||
|
||||
_tokenCache = tokenCache;
|
||||
_claimsHandler = sctClaimsHandler;
|
||||
}
|
||||
|
||||
#region ISecurityContextSecurityTokenCache Members
|
||||
|
||||
public void AddContext(SecurityContextSecurityToken token)
|
||||
{
|
||||
//
|
||||
// WCF will cache the token first before calling the WrappedSessionSecurityTokenHandler.OnTokenIssued.
|
||||
// We need to map the claims here so we will be caching the correct token with Geneva Claims substitued
|
||||
// in place of the WCF claims.
|
||||
//
|
||||
_claimsHandler.SetPrincipalBootstrapTokensAndBindIdfxAuthPolicy(token);
|
||||
|
||||
SessionSecurityTokenCacheKey key = new SessionSecurityTokenCacheKey(_claimsHandler.EndpointId, token.ContextId, token.KeyGeneration);
|
||||
SessionSecurityToken sessionToken = SecurityContextSecurityTokenHelper.ConvertSctToSessionToken(token, SecureConversationVersion.Default);
|
||||
DateTime expiryTime = DateTimeUtil.Add(sessionToken.ValidTo, _claimsHandler.SecurityTokenHandlerCollection.Configuration.MaxClockSkew);
|
||||
_tokenCache.AddOrUpdate(key, sessionToken, expiryTime);
|
||||
}
|
||||
|
||||
public void ClearContexts()
|
||||
{
|
||||
_tokenCache.RemoveAll(_claimsHandler.EndpointId);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Called to retrieve all tokens that match a particular contextId. WCF will call this
|
||||
/// </summary>
|
||||
/// <param name="contextId"></param>
|
||||
/// <returns></returns>
|
||||
public Collection<SecurityContextSecurityToken> GetAllContexts(System.Xml.UniqueId contextId)
|
||||
{
|
||||
Collection<SecurityContextSecurityToken> tokens = new Collection<SecurityContextSecurityToken>();
|
||||
|
||||
IEnumerable<SessionSecurityToken> cachedTokens = _tokenCache.GetAll(_claimsHandler.EndpointId, contextId);
|
||||
if (cachedTokens != null)
|
||||
{
|
||||
foreach (SessionSecurityToken sessionSct in cachedTokens)
|
||||
{
|
||||
if (sessionSct != null && sessionSct.IsSecurityContextSecurityTokenWrapper)
|
||||
{
|
||||
SecurityContextSecurityToken sctToken = SecurityContextSecurityTokenHelper.ConvertSessionTokenToSecurityContextSecurityToken(sessionSct);
|
||||
tokens.Add(sctToken);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return tokens;
|
||||
}
|
||||
|
||||
public SecurityContextSecurityToken GetContext(System.Xml.UniqueId contextId, System.Xml.UniqueId generation)
|
||||
{
|
||||
SessionSecurityToken token = null;
|
||||
SessionSecurityTokenCacheKey key = new SessionSecurityTokenCacheKey(_claimsHandler.EndpointId, contextId, generation);
|
||||
token = _tokenCache.Get(key);
|
||||
|
||||
SecurityContextSecurityToken sctToken = null;
|
||||
|
||||
if (token != null && token.IsSecurityContextSecurityTokenWrapper)
|
||||
{
|
||||
sctToken = SecurityContextSecurityTokenHelper.ConvertSessionTokenToSecurityContextSecurityToken(token);
|
||||
}
|
||||
|
||||
return sctToken;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Removes all the tokens that match the contextId.
|
||||
/// </summary>
|
||||
/// <param name="contextId">The context id.</param>
|
||||
/// <remarks>
|
||||
/// When WCF renews a token, its context id is the same as the issuedToken. The only
|
||||
/// difference is in the generationId. When WCF closes the session channel, all the tokens that
|
||||
/// were issued need to be removed that match the contextId.
|
||||
/// </remarks>
|
||||
public void RemoveAllContexts(System.Xml.UniqueId contextId)
|
||||
{
|
||||
_tokenCache.RemoveAll(_claimsHandler.EndpointId, contextId);
|
||||
}
|
||||
|
||||
public void RemoveContext(System.Xml.UniqueId contextId, System.Xml.UniqueId generation)
|
||||
{
|
||||
SessionSecurityTokenCacheKey key = new SessionSecurityTokenCacheKey(_claimsHandler.EndpointId, contextId, generation);
|
||||
_tokenCache.Remove(key);
|
||||
}
|
||||
|
||||
public bool TryAddContext(SecurityContextSecurityToken token)
|
||||
{
|
||||
//
|
||||
// WCF will cache the token first before calling the WrappedSessionSecurityTokenHandler.OnTokenIssued.
|
||||
// We need to map the claims here so we will be caching the correct token with Geneva Claims substitued
|
||||
// in place of the WCF claims.
|
||||
//
|
||||
_claimsHandler.SetPrincipalBootstrapTokensAndBindIdfxAuthPolicy(token);
|
||||
|
||||
SessionSecurityTokenCacheKey key = new SessionSecurityTokenCacheKey(_claimsHandler.EndpointId, token.ContextId, token.KeyGeneration);
|
||||
SessionSecurityToken sessionToken = SecurityContextSecurityTokenHelper.ConvertSctToSessionToken(token, SecureConversationVersion.Default);
|
||||
DateTime expiryTime = DateTimeUtil.Add(token.ValidTo, _claimsHandler.SecurityTokenHandlerCollection.Configuration.MaxClockSkew);
|
||||
_tokenCache.AddOrUpdate(key, sessionToken, expiryTime);
|
||||
return true;
|
||||
}
|
||||
|
||||
public void UpdateContextCachingTime(SecurityContextSecurityToken token, DateTime expirationTime)
|
||||
{
|
||||
if (token.ValidTo <= expirationTime.ToUniversalTime())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
SessionSecurityTokenCacheKey key = new SessionSecurityTokenCacheKey(_claimsHandler.EndpointId, token.ContextId, token.KeyGeneration);
|
||||
SessionSecurityToken sessionToken = SecurityContextSecurityTokenHelper.ConvertSctToSessionToken(token, SecureConversationVersion.Default);
|
||||
DateTime expiryTime = DateTimeUtil.Add(sessionToken.ValidTo, _claimsHandler.SecurityTokenHandlerCollection.Configuration.MaxClockSkew);
|
||||
if (_tokenCache.Get(key) == null)
|
||||
{
|
||||
throw DiagnosticUtility.ExceptionUtility.ThrowHelperInvalidOperation(SR.GetString(SR.ID4285, sessionToken.ContextId.ToString()));
|
||||
}
|
||||
_tokenCache.AddOrUpdate(key, sessionToken, expiryTime);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
// these are not needed as this will never be used as an SecurityTokenResolver.
|
||||
protected override bool TryResolveSecurityKeyCore(SecurityKeyIdentifierClause keyIdentifierClause, out SecurityKey key)
|
||||
{
|
||||
SecurityToken sct;
|
||||
if (TryResolveTokenCore(keyIdentifierClause, out sct))
|
||||
{
|
||||
key = ((SecurityContextSecurityToken)sct).SecurityKeys[0];
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
key = null;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
protected override bool TryResolveTokenCore(SecurityKeyIdentifierClause keyIdentifierClause, out SecurityToken token)
|
||||
{
|
||||
SecurityContextKeyIdentifierClause sctSkiClause = keyIdentifierClause as SecurityContextKeyIdentifierClause;
|
||||
if (sctSkiClause != null)
|
||||
{
|
||||
token = GetContext(sctSkiClause.ContextId, sctSkiClause.Generation) as SecurityToken;
|
||||
}
|
||||
else
|
||||
{
|
||||
token = null;
|
||||
}
|
||||
return (token != null);
|
||||
}
|
||||
|
||||
protected override bool TryResolveTokenCore(SecurityKeyIdentifier keyIdentifier, out SecurityToken token)
|
||||
{
|
||||
SecurityContextKeyIdentifierClause sctSkiClause;
|
||||
if (keyIdentifier.TryFind<SecurityContextKeyIdentifierClause>(out sctSkiClause))
|
||||
{
|
||||
return TryResolveTokenCore(sctSkiClause, out token);
|
||||
}
|
||||
else
|
||||
{
|
||||
token = null;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user