Code:
/ WCF / WCF / 3.5.30729.1 / untmp / Orcas / SP / ndp / cdf / src / WCF / ServiceModel / System / ServiceModel / Security / SecurityProtocol.cs / 1 / SecurityProtocol.cs
//----------------------------------------------------------
// Copyright (c) Microsoft Corporation. All rights reserved.
//-----------------------------------------------------------
namespace System.ServiceModel.Security
{
using System.Diagnostics;
using System.Collections.Generic;
using System.ServiceModel;
using System.ServiceModel.Description;
using System.Collections.ObjectModel;
using System.IO;
using System.IdentityModel.Selectors;
using System.IdentityModel.Claims;
using System.IdentityModel.Policy;
using System.IdentityModel.Tokens;
using System.Security.Cryptography;
using System.ServiceModel.Channels;
using System.Text;
using System.Xml;
using System.Xml.Serialization;
using System.ServiceModel.Diagnostics;
using System.ServiceModel.Security.Tokens;
// See SecurityProtocolFactory for contracts on subclasses etc
// SecureOutgoingMessage and VerifyIncomingMessage take message as
// ref parameters (instead of taking a message and returning a
// message) to reduce the likelihood that a caller will forget to
// do the rest of the processing with the modified message object.
// Especially, on the sender-side, not sending the modified
// message will result in sending it with an unencrypted body.
// Correspondingly, the async versions have out parameters instead
// of simple return values.
abstract class SecurityProtocol : ISecurityCommunicationObject
{
static ReadOnlyCollection emptyTokenProviders;
ICollection channelSupportingTokenProviderSpecification;
Dictionary> scopedSupportingTokenProviderSpecification;
Dictionary> mergedSupportingTokenProvidersMap;
SecurityProtocolFactory factory;
EndpointAddress target;
Uri via;
WrapperSecurityCommunicationObject communicationObject;
ChannelParameterCollection channelParameters;
protected SecurityProtocol(SecurityProtocolFactory factory, EndpointAddress target, Uri via)
{
this.factory = factory;
this.target = target;
this.via = via;
this.communicationObject = new WrapperSecurityCommunicationObject(this);
}
protected WrapperSecurityCommunicationObject CommunicationObject
{
get { return this.communicationObject; }
}
public SecurityProtocolFactory SecurityProtocolFactory
{
get { return this.factory; }
}
public EndpointAddress Target
{
get { return this.target; }
}
public Uri Via
{
get { return this.via; }
}
public ICollection ChannelSupportingTokenProviderSpecification
{
get
{
return this.channelSupportingTokenProviderSpecification;
}
}
public Dictionary> ScopedSupportingTokenProviderSpecification
{
get
{
return this.scopedSupportingTokenProviderSpecification;
}
}
static ReadOnlyCollection EmptyTokenProviders
{
get
{
if (emptyTokenProviders == null)
{
emptyTokenProviders = new ReadOnlyCollection(new List());
}
return emptyTokenProviders;
}
}
public ChannelParameterCollection ChannelParameters
{
get
{
return this.channelParameters;
}
set
{
this.communicationObject.ThrowIfDisposedOrImmutable();
this.channelParameters = value;
}
}
// ISecurityCommunicationObject members
public TimeSpan DefaultOpenTimeout
{
get { return ServiceDefaults.OpenTimeout; }
}
public TimeSpan DefaultCloseTimeout
{
get { return ServiceDefaults.CloseTimeout; }
}
public IAsyncResult OnBeginClose(TimeSpan timeout, AsyncCallback callback, object state)
{
return new OperationWithTimeoutAsyncResult(new OperationWithTimeoutCallback(this.OnClose), timeout, callback, state);
}
public IAsyncResult OnBeginOpen(TimeSpan timeout, AsyncCallback callback, object state)
{
return new OperationWithTimeoutAsyncResult(new OperationWithTimeoutCallback(this.OnOpen), timeout, callback, state);
}
public void OnClosed()
{
}
public void OnClosing()
{
}
public void OnEndClose(IAsyncResult result)
{
OperationWithTimeoutAsyncResult.End(result);
}
public void OnEndOpen(IAsyncResult result)
{
OperationWithTimeoutAsyncResult.End(result);
}
public void OnFaulted()
{
}
public void OnOpened()
{
}
public void OnOpening()
{
}
internal IList GetSupportingTokenProviders(string action)
{
if (this.mergedSupportingTokenProvidersMap != null && this.mergedSupportingTokenProvidersMap.Count > 0)
{
if (action != null && this.mergedSupportingTokenProvidersMap.ContainsKey(action))
{
return this.mergedSupportingTokenProvidersMap[action];
}
else if (this.mergedSupportingTokenProvidersMap.ContainsKey(MessageHeaders.WildcardAction))
{
return this.mergedSupportingTokenProvidersMap[MessageHeaders.WildcardAction];
}
}
// return null if the token providers list is empty - this gets a perf benefit since calling Count is expensive for an empty
// ReadOnlyCollection
return (this.channelSupportingTokenProviderSpecification == EmptyTokenProviders) ? null : (IList)this.channelSupportingTokenProviderSpecification;
}
protected InitiatorServiceModelSecurityTokenRequirement CreateInitiatorSecurityTokenRequirement()
{
InitiatorServiceModelSecurityTokenRequirement requirement = new InitiatorServiceModelSecurityTokenRequirement();
requirement.TargetAddress = this.Target;
requirement.Via = this.via;
requirement.SecurityBindingElement = this.factory.SecurityBindingElement;
requirement.SecurityAlgorithmSuite = this.factory.OutgoingAlgorithmSuite;
requirement.MessageSecurityVersion = this.factory.MessageSecurityVersion.SecurityTokenVersion;
if (this.factory.PrivacyNoticeUri != null)
{
requirement.Properties[ServiceModelSecurityTokenRequirement.PrivacyNoticeUriProperty] = this.factory.PrivacyNoticeUri;
}
if (this.channelParameters != null)
{
requirement.Properties[ServiceModelSecurityTokenRequirement.ChannelParametersCollectionProperty] = this.channelParameters;
}
requirement.Properties[ServiceModelSecurityTokenRequirement.PrivacyNoticeVersionProperty] = this.factory.PrivacyNoticeVersion;
return requirement;
}
InitiatorServiceModelSecurityTokenRequirement CreateInitiatorSecurityTokenRequirement(SecurityTokenParameters parameters, SecurityTokenAttachmentMode attachmentMode)
{
InitiatorServiceModelSecurityTokenRequirement requirement = CreateInitiatorSecurityTokenRequirement();
parameters.InitializeSecurityTokenRequirement(requirement);
requirement.KeyUsage = SecurityKeyUsage.Signature;
requirement.Properties[ServiceModelSecurityTokenRequirement.MessageDirectionProperty] = MessageDirection.Output;
requirement.Properties[ServiceModelSecurityTokenRequirement.SupportingTokenAttachmentModeProperty] = attachmentMode;
return requirement;
}
void AddSupportingTokenProviders(SupportingTokenParameters supportingTokenParameters, bool isOptional, IList providerSpecList)
{
for (int i = 0; i < supportingTokenParameters.Endorsing.Count; ++i)
{
SecurityTokenRequirement requirement = this.CreateInitiatorSecurityTokenRequirement(supportingTokenParameters.Endorsing[i], SecurityTokenAttachmentMode.Endorsing);
try
{
System.IdentityModel.Selectors.SecurityTokenProvider provider = this.factory.SecurityTokenManager.CreateSecurityTokenProvider(requirement);
SupportingTokenProviderSpecification providerSpec = new SupportingTokenProviderSpecification(provider, SecurityTokenAttachmentMode.Endorsing, supportingTokenParameters.Endorsing[i]);
providerSpecList.Add(providerSpec);
}
catch (Exception e)
{
if (!isOptional || DiagnosticUtility.IsFatal(e))
{
throw;
}
}
}
for (int i = 0; i < supportingTokenParameters.SignedEndorsing.Count; ++i)
{
SecurityTokenRequirement requirement = this.CreateInitiatorSecurityTokenRequirement(supportingTokenParameters.SignedEndorsing[i], SecurityTokenAttachmentMode.SignedEndorsing);
try
{
System.IdentityModel.Selectors.SecurityTokenProvider provider = this.factory.SecurityTokenManager.CreateSecurityTokenProvider(requirement);
SupportingTokenProviderSpecification providerSpec = new SupportingTokenProviderSpecification(provider, SecurityTokenAttachmentMode.SignedEndorsing, supportingTokenParameters.SignedEndorsing[i]);
providerSpecList.Add(providerSpec);
}
catch (Exception e)
{
if (!isOptional || DiagnosticUtility.IsFatal(e))
{
throw;
}
}
}
for (int i = 0; i < supportingTokenParameters.SignedEncrypted.Count; ++i)
{
SecurityTokenRequirement requirement = this.CreateInitiatorSecurityTokenRequirement(supportingTokenParameters.SignedEncrypted[i], SecurityTokenAttachmentMode.SignedEncrypted);
try
{
System.IdentityModel.Selectors.SecurityTokenProvider provider = this.factory.SecurityTokenManager.CreateSecurityTokenProvider(requirement);
SupportingTokenProviderSpecification providerSpec = new SupportingTokenProviderSpecification(provider, SecurityTokenAttachmentMode.SignedEncrypted, supportingTokenParameters.SignedEncrypted[i]);
providerSpecList.Add(providerSpec);
}
catch (Exception e)
{
if (!isOptional || DiagnosticUtility.IsFatal(e))
{
throw;
}
}
}
for (int i = 0; i < supportingTokenParameters.Signed.Count; ++i)
{
SecurityTokenRequirement requirement = this.CreateInitiatorSecurityTokenRequirement(supportingTokenParameters.Signed[i], SecurityTokenAttachmentMode.Signed);
try
{
System.IdentityModel.Selectors.SecurityTokenProvider provider = this.factory.SecurityTokenManager.CreateSecurityTokenProvider(requirement);
SupportingTokenProviderSpecification providerSpec = new SupportingTokenProviderSpecification(provider, SecurityTokenAttachmentMode.Signed, supportingTokenParameters.Signed[i]);
providerSpecList.Add(providerSpec);
}
catch (Exception e)
{
if (!isOptional || DiagnosticUtility.IsFatal(e))
{
throw;
}
}
}
}
void MergeSupportingTokenProviders(TimeSpan timeout)
{
if (this.ScopedSupportingTokenProviderSpecification.Count == 0)
{
this.mergedSupportingTokenProvidersMap = null;
}
else
{
TimeoutHelper timeoutHelper = new TimeoutHelper(timeout);
this.factory.ExpectSupportingTokens = true;
this.mergedSupportingTokenProvidersMap = new Dictionary>();
foreach (string action in this.ScopedSupportingTokenProviderSpecification.Keys)
{
ICollection scopedProviders = this.ScopedSupportingTokenProviderSpecification[action];
if (scopedProviders == null || scopedProviders.Count == 0)
{
continue;
}
Collection mergedProviders = new Collection();
foreach (SupportingTokenProviderSpecification spec in this.channelSupportingTokenProviderSpecification)
{
mergedProviders.Add(spec);
}
foreach (SupportingTokenProviderSpecification spec in scopedProviders)
{
SecurityUtils.OpenTokenProviderIfRequired(spec.TokenProvider, timeoutHelper.RemainingTime());
if (spec.SecurityTokenAttachmentMode == SecurityTokenAttachmentMode.Endorsing || spec.SecurityTokenAttachmentMode == SecurityTokenAttachmentMode.SignedEndorsing)
{
if (spec.TokenParameters.RequireDerivedKeys && !spec.TokenParameters.HasAsymmetricKey)
{
this.factory.ExpectKeyDerivation = true;
}
}
mergedProviders.Add(spec);
}
this.mergedSupportingTokenProvidersMap.Add(action, mergedProviders);
}
}
}
public void Open(TimeSpan timeout)
{
this.communicationObject.Open(timeout);
}
public IAsyncResult BeginOpen(TimeSpan timeout, AsyncCallback callback, object state)
{
return this.communicationObject.BeginOpen(timeout, callback, state);
}
public void EndOpen(IAsyncResult result)
{
this.communicationObject.EndOpen(result);
}
public virtual void OnOpen(TimeSpan timeout)
{
TimeoutHelper timeoutHelper = new TimeoutHelper(timeout);
if (this.factory.ActAsInitiator)
{
this.channelSupportingTokenProviderSpecification = new Collection();
this.scopedSupportingTokenProviderSpecification = new Dictionary>();
AddSupportingTokenProviders(this.factory.SecurityBindingElement.EndpointSupportingTokenParameters, false, (IList)this.channelSupportingTokenProviderSpecification);
AddSupportingTokenProviders(this.factory.SecurityBindingElement.OptionalEndpointSupportingTokenParameters, true, (IList)this.channelSupportingTokenProviderSpecification);
foreach (string action in this.factory.SecurityBindingElement.OperationSupportingTokenParameters.Keys)
{
Collection providerSpecList = new Collection();
AddSupportingTokenProviders(this.factory.SecurityBindingElement.OperationSupportingTokenParameters[action], false, providerSpecList);
this.scopedSupportingTokenProviderSpecification.Add(action, providerSpecList);
}
foreach (string action in this.factory.SecurityBindingElement.OptionalOperationSupportingTokenParameters.Keys)
{
Collection providerSpecList;
ICollection existingList;
if (this.scopedSupportingTokenProviderSpecification.TryGetValue(action, out existingList))
{
providerSpecList = ((Collection)existingList);
}
else
{
providerSpecList = new Collection();
this.scopedSupportingTokenProviderSpecification.Add(action, providerSpecList);
}
this.AddSupportingTokenProviders(this.factory.SecurityBindingElement.OptionalOperationSupportingTokenParameters[action], true, providerSpecList);
}
if (!this.channelSupportingTokenProviderSpecification.IsReadOnly)
{
if (this.channelSupportingTokenProviderSpecification.Count == 0)
{
this.channelSupportingTokenProviderSpecification = EmptyTokenProviders;
}
else
{
this.factory.ExpectSupportingTokens = true;
foreach (SupportingTokenProviderSpecification tokenProviderSpec in this.channelSupportingTokenProviderSpecification)
{
SecurityUtils.OpenTokenProviderIfRequired(tokenProviderSpec.TokenProvider, timeoutHelper.RemainingTime());
if (tokenProviderSpec.SecurityTokenAttachmentMode == SecurityTokenAttachmentMode.Endorsing || tokenProviderSpec.SecurityTokenAttachmentMode == SecurityTokenAttachmentMode.SignedEndorsing)
{
if (tokenProviderSpec.TokenParameters.RequireDerivedKeys && !tokenProviderSpec.TokenParameters.HasAsymmetricKey)
{
this.factory.ExpectKeyDerivation = true;
}
}
}
this.channelSupportingTokenProviderSpecification =
new ReadOnlyCollection((Collection)this.channelSupportingTokenProviderSpecification);
}
}
// create a merged map of the per operation supporting tokens
MergeSupportingTokenProviders(timeoutHelper.RemainingTime());
}
}
public void Close(bool aborted, TimeSpan timeout)
{
if (aborted)
{
this.communicationObject.Abort();
}
else
{
this.communicationObject.Close(timeout);
}
}
public virtual void OnAbort()
{
if (this.factory.ActAsInitiator)
{
foreach (SupportingTokenProviderSpecification spec in this.channelSupportingTokenProviderSpecification)
{
SecurityUtils.AbortTokenProviderIfRequired(spec.TokenProvider);
}
foreach (string action in this.scopedSupportingTokenProviderSpecification.Keys)
{
ICollection supportingProviders = this.scopedSupportingTokenProviderSpecification[action];
foreach (SupportingTokenProviderSpecification spec in supportingProviders)
{
SecurityUtils.AbortTokenProviderIfRequired(spec.TokenProvider);
}
}
}
}
public virtual void OnClose(TimeSpan timeout)
{
if (this.factory.ActAsInitiator)
{
TimeoutHelper timeoutHelper = new TimeoutHelper(timeout);
foreach (SupportingTokenProviderSpecification spec in this.channelSupportingTokenProviderSpecification)
{
SecurityUtils.CloseTokenProviderIfRequired(spec.TokenProvider, timeoutHelper.RemainingTime());
}
foreach (string action in this.scopedSupportingTokenProviderSpecification.Keys)
{
ICollection supportingProviders = this.scopedSupportingTokenProviderSpecification[action];
foreach (SupportingTokenProviderSpecification spec in supportingProviders)
{
SecurityUtils.CloseTokenProviderIfRequired(spec.TokenProvider, timeoutHelper.RemainingTime());
}
}
}
}
public IAsyncResult BeginClose(TimeSpan timeout, AsyncCallback callback, object state)
{
return this.communicationObject.BeginClose(timeout, callback, state);
}
public void EndClose(IAsyncResult result)
{
this.communicationObject.EndClose(result);
}
static void SetSecurityHeaderId(SendSecurityHeader securityHeader, Message message)
{
SecurityMessageProperty messageProperty = message.Properties.Security;
if (messageProperty != null)
{
securityHeader.IdPrefix = messageProperty.SenderIdPrefix;
}
}
void AddSupportingTokenSpecification(SecurityMessageProperty security, IList tokens, SecurityTokenAttachmentMode attachmentMode, IDictionary> tokenPoliciesMapping)
{
if (tokens == null || tokens.Count == 0)
{
return;
}
for (int i = 0; i < tokens.Count; ++i)
{
security.IncomingSupportingTokens.Add(new SupportingTokenSpecification(tokens[i], tokenPoliciesMapping[tokens[i]], attachmentMode));
}
}
protected void AddSupportingTokenSpecification(SecurityMessageProperty security, IList basicTokens, IList endorsingTokens, IList signedEndorsingTokens, IList signedTokens, IDictionary> tokenPoliciesMapping)
{
AddSupportingTokenSpecification(security, basicTokens, SecurityTokenAttachmentMode.SignedEncrypted, tokenPoliciesMapping);
AddSupportingTokenSpecification(security, endorsingTokens, SecurityTokenAttachmentMode.Endorsing, tokenPoliciesMapping);
AddSupportingTokenSpecification(security, signedEndorsingTokens, SecurityTokenAttachmentMode.SignedEndorsing, tokenPoliciesMapping);
AddSupportingTokenSpecification(security, signedTokens, SecurityTokenAttachmentMode.Signed, tokenPoliciesMapping);
}
protected SendSecurityHeader CreateSendSecurityHeader(Message message, string actor, SecurityProtocolFactory factory)
{
return CreateSendSecurityHeader(message, actor, factory, true);
}
protected SendSecurityHeader CreateSendSecurityHeaderForTransportProtocol(Message message, string actor, SecurityProtocolFactory factory)
{
return CreateSendSecurityHeader(message, actor, factory, false);
}
SendSecurityHeader CreateSendSecurityHeader(Message message, string actor, SecurityProtocolFactory factory, bool requireMessageProtection)
{
MessageDirection transferDirection = factory.ActAsInitiator ? MessageDirection.Input : MessageDirection.Output;
SendSecurityHeader sendSecurityHeader = factory.StandardsManager.CreateSendSecurityHeader(
message,
actor, true, false,
factory.OutgoingAlgorithmSuite, transferDirection);
sendSecurityHeader.Layout = factory.SecurityHeaderLayout;
sendSecurityHeader.RequireMessageProtection = requireMessageProtection;
SetSecurityHeaderId(sendSecurityHeader, message);
if (factory.AddTimestamp)
{
sendSecurityHeader.AddTimestamp(factory.TimestampValidityDuration);
}
return sendSecurityHeader;
}
internal void AddMessageSupportingTokens(Message message, ref IList supportingTokens)
{
SecurityMessageProperty supportingTokensProperty = message.Properties.Security;
if (supportingTokensProperty != null && supportingTokensProperty.HasOutgoingSupportingTokens)
{
if (supportingTokens == null)
{
supportingTokens = new Collection();
}
for (int i = 0; i < supportingTokensProperty.OutgoingSupportingTokens.Count; ++i)
{
SupportingTokenSpecification spec = supportingTokensProperty.OutgoingSupportingTokens[i];
if (spec.SecurityTokenParameters == null)
{
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new MessageSecurityException(SR.GetString(SR.SenderSideSupportingTokensMustSpecifySecurityTokenParameters)));
}
supportingTokens.Add(spec);
}
}
}
internal bool TryGetSupportingTokens(SecurityProtocolFactory factory, EndpointAddress target, Uri via, Message message, TimeSpan timeout, bool isBlockingCall, out IList supportingTokens)
{
if (!factory.ActAsInitiator)
{
supportingTokens = null;
return true;
}
if (message == null)
{
throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("message");
}
TimeoutHelper timeoutHelper = new TimeoutHelper(timeout);
supportingTokens = null;
IList supportingTokenProviders = this.GetSupportingTokenProviders(message.Headers.Action);
if (supportingTokenProviders != null && supportingTokenProviders.Count > 0)
{
// dont do anything if blocking is not allowed
if (!isBlockingCall)
{
return false;
}
supportingTokens = new Collection();
for (int i = 0; i < supportingTokenProviders.Count; ++i)
{
SupportingTokenProviderSpecification spec = supportingTokenProviders[i];
SecurityToken supportingToken = spec.TokenProvider.GetToken(timeoutHelper.RemainingTime());
supportingTokens.Add(new SupportingTokenSpecification(supportingToken, EmptyReadOnlyCollection.Instance, spec.SecurityTokenAttachmentMode, spec.TokenParameters));
}
}
// add any runtime supporting tokens
AddMessageSupportingTokens(message, ref supportingTokens);
return true;
}
protected IList GetSupportingTokenAuthenticatorsAndSetExpectationFlags(SecurityProtocolFactory factory, Message message,
ReceiveSecurityHeader securityHeader)
{
if (factory.ActAsInitiator)
{
return null;
}
if (message == null)
{
throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("message");
}
bool expectBasicTokens;
bool expectSignedTokens;
bool expectEndorsingTokens;
IList authenticators = factory.GetSupportingTokenAuthenticators(message.Headers.Action,
out expectSignedTokens, out expectBasicTokens, out expectEndorsingTokens);
securityHeader.ExpectBasicTokens = expectBasicTokens;
securityHeader.ExpectEndorsingTokens = expectEndorsingTokens;
securityHeader.ExpectSignedTokens = expectSignedTokens;
return authenticators;
}
protected ReadOnlyCollection MergeOutOfBandResolvers(IList supportingAuthenticators, ReadOnlyCollection primaryResolvers)
{
Collection outOfBandResolvers = null;
if (supportingAuthenticators != null && supportingAuthenticators.Count > 0)
{
for (int i = 0; i < supportingAuthenticators.Count; ++i)
{
if (supportingAuthenticators[i].TokenResolver != null)
{
outOfBandResolvers = outOfBandResolvers ?? new Collection();
outOfBandResolvers.Add(supportingAuthenticators[i].TokenResolver);
}
}
}
if (outOfBandResolvers != null)
{
if (primaryResolvers != null)
{
for (int i = 0; i < primaryResolvers.Count; ++i)
{
outOfBandResolvers.Insert(0, primaryResolvers[i]);
}
}
return new ReadOnlyCollection(outOfBandResolvers);
}
else
{
return primaryResolvers ?? EmptyReadOnlyCollection.Instance;
}
}
protected void AddSupportingTokens(SendSecurityHeader securityHeader, IList supportingTokens)
{
if (supportingTokens != null)
{
for (int i = 0; i < supportingTokens.Count; ++i)
{
SecurityToken token = supportingTokens[i].SecurityToken;
SecurityTokenParameters tokenParameters = supportingTokens[i].SecurityTokenParameters;
switch (supportingTokens[i].SecurityTokenAttachmentMode)
{
case SecurityTokenAttachmentMode.Signed:
securityHeader.AddSignedSupportingToken(token, tokenParameters);
break;
case SecurityTokenAttachmentMode.Endorsing:
securityHeader.AddEndorsingSupportingToken(token, tokenParameters);
break;
case SecurityTokenAttachmentMode.SignedEncrypted:
securityHeader.AddBasicSupportingToken(token, tokenParameters);
break;
case SecurityTokenAttachmentMode.SignedEndorsing:
securityHeader.AddSignedEndorsingSupportingToken(token, tokenParameters);
break;
default:
DiagnosticUtility.DebugAssert("Unknown token attachment mode " + supportingTokens[i].SecurityTokenAttachmentMode.ToString());
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new NotSupportedException(SR.GetString(SR.UnknownTokenAttachmentMode, supportingTokens[i].SecurityTokenAttachmentMode.ToString())));
}
}
}
}
public virtual IAsyncResult BeginSecureOutgoingMessage(Message message, TimeSpan timeout, AsyncCallback callback, object state)
{
SecureOutgoingMessage(ref message, timeout);
return new TypedCompletedAsyncResult(message, callback, state);
}
public virtual IAsyncResult BeginSecureOutgoingMessage(Message message, TimeSpan timeout, SecurityProtocolCorrelationState correlationState, AsyncCallback callback, object state)
{
SecurityProtocolCorrelationState newCorrelationState = SecureOutgoingMessage(ref message, timeout, correlationState);
return new TypedCompletedAsyncResult(message, newCorrelationState, callback, state);
}
public virtual IAsyncResult BeginVerifyIncomingMessage(Message message, TimeSpan timeout, AsyncCallback callback, object state)
{
VerifyIncomingMessage(ref message, timeout);
return new TypedCompletedAsyncResult(message, callback, state);
}
public virtual IAsyncResult BeginVerifyIncomingMessage(Message message, TimeSpan timeout, SecurityProtocolCorrelationState[] correlationStates, AsyncCallback callback, object state)
{
SecurityProtocolCorrelationState newCorrelationState = VerifyIncomingMessage(ref message, timeout, correlationStates);
return new TypedCompletedAsyncResult(message, newCorrelationState, callback, state);
}
public virtual void EndSecureOutgoingMessage(IAsyncResult result, out Message message)
{
message = TypedCompletedAsyncResult.End(result);
}
public virtual void EndSecureOutgoingMessage(IAsyncResult result, out Message message, out SecurityProtocolCorrelationState newCorrelationState)
{
message = TypedCompletedAsyncResult.End(result, out newCorrelationState);
}
public virtual void EndVerifyIncomingMessage(IAsyncResult result, out Message message)
{
message = TypedCompletedAsyncResult.End(result);
}
public virtual void EndVerifyIncomingMessage(IAsyncResult result, out Message message, out SecurityProtocolCorrelationState newCorrelationState)
{
message = TypedCompletedAsyncResult.End(result, out newCorrelationState);
}
internal static SecurityToken GetToken(SecurityTokenProvider provider, EndpointAddress target, TimeSpan timeout)
{
if (provider == null)
{
// should this be an ArgumentNullException ?
// throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentNullException("provider"));
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new MessageSecurityException(SR.GetString(SR.TokenProviderCannotGetTokensForTarget, target)));
}
SecurityToken token = null;
try
{
token = provider.GetToken(timeout);
}
catch (SecurityTokenException exception)
{
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new MessageSecurityException(SR.GetString(SR.TokenProviderCannotGetTokensForTarget, target), exception));
}
catch (SecurityNegotiationException sne)
{
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new SecurityNegotiationException(SR.GetString(SR.TokenProviderCannotGetTokensForTarget, target), sne));
}
return token;
}
public abstract void SecureOutgoingMessage(ref Message message, TimeSpan timeout);
// subclasses that offer correlation should override this version
public virtual SecurityProtocolCorrelationState SecureOutgoingMessage(ref Message message, TimeSpan timeout, SecurityProtocolCorrelationState correlationState)
{
SecureOutgoingMessage(ref message, timeout);
return null;
}
protected virtual void OnOutgoingMessageSecured(Message securedMessage)
{
SecurityTraceRecordHelper.TraceOutgoingMessageSecured(this, securedMessage);
}
protected virtual void OnSecureOutgoingMessageFailure(Message message)
{
SecurityTraceRecordHelper.TraceSecureOutgoingMessageFailure(this, message);
}
public abstract void VerifyIncomingMessage(ref Message message, TimeSpan timeout);
// subclasses that offer correlation should override this version
public virtual SecurityProtocolCorrelationState VerifyIncomingMessage(ref Message message, TimeSpan timeout, params SecurityProtocolCorrelationState[] correlationStates)
{
VerifyIncomingMessage(ref message, timeout);
return null;
}
protected virtual void OnIncomingMessageVerified(Message verifiedMessage)
{
SecurityTraceRecordHelper.TraceIncomingMessageVerified(this, verifiedMessage);
if (AuditLevel.Success == (this.factory.MessageAuthenticationAuditLevel & AuditLevel.Success))
{
SecurityAuditHelper.WriteMessageAuthenticationSuccessEvent(this.factory.AuditLogLocation,
this.factory.SuppressAuditFailure, verifiedMessage, verifiedMessage.Headers.To, verifiedMessage.Headers.Action,
SecurityUtils.GetIdentityNamesFromContext(verifiedMessage.Properties.Security.ServiceSecurityContext.AuthorizationContext));
}
}
protected virtual void OnVerifyIncomingMessageFailure(Message message, Exception exception)
{
SecurityTraceRecordHelper.TraceVerifyIncomingMessageFailure(this, message);
if (PerformanceCounters.PerformanceCountersEnabled && null != this.factory.ListenUri) //service side
{
if ((exception.GetType() == typeof(MessageSecurityException) || exception.GetType().IsSubclassOf(typeof(MessageSecurityException)))
|| (exception.GetType() == typeof(SecurityTokenException) || exception.GetType().IsSubclassOf(typeof(SecurityTokenException))))
{
PerformanceCounters.AuthenticationFailed(message, this.factory.ListenUri);
}
}
if (AuditLevel.Failure == (this.factory.MessageAuthenticationAuditLevel & AuditLevel.Failure))
{
try
{
SecurityMessageProperty security = message.Properties.Security;
string primaryIdentity;
if (security != null && security.ServiceSecurityContext != null)
primaryIdentity = SecurityUtils.GetIdentityNamesFromContext(security.ServiceSecurityContext.AuthorizationContext);
else
primaryIdentity = SecurityUtils.AnonymousIdentity.Name;
SecurityAuditHelper.WriteMessageAuthenticationFailureEvent(this.factory.AuditLogLocation,
this.factory.SuppressAuditFailure, message, message.Headers.To, message.Headers.Action, primaryIdentity, exception);
}
#pragma warning suppress 56500
catch (Exception auditException)
{
if (DiagnosticUtility.IsFatal(auditException))
throw;
DiagnosticUtility.ExceptionUtility.TraceHandledException(auditException, TraceEventType.Error);
}
}
}
protected abstract class GetSupportingTokensAsyncResult : AsyncResult
{
static AsyncCallback getSupportingTokensCallback = DiagnosticUtility.ThunkAsyncCallback(new AsyncCallback(GetSupportingTokenCallback));
SecurityProtocol binding;
Message message;
IList supportingTokens;
int currentTokenProviderIndex = 0;
IList supportingTokenProviders;
TimeoutHelper timeoutHelper;
public GetSupportingTokensAsyncResult(Message m, SecurityProtocol binding, TimeSpan timeout, AsyncCallback callback, object state)
: base(callback, state)
{
this.message = m;
this.binding = binding;
this.timeoutHelper = new TimeoutHelper(timeout);
}
protected IList SupportingTokens
{
get { return this.supportingTokens; }
}
protected abstract bool OnGetSupportingTokensDone(TimeSpan timeout);
static void GetSupportingTokenCallback(IAsyncResult result)
{
if (result.CompletedSynchronously)
{
return;
}
GetSupportingTokensAsyncResult self = (GetSupportingTokensAsyncResult)result.AsyncState;
bool completeSelf;
Exception completionException = null;
try
{
self.AddSupportingToken(result);
completeSelf = self.AddSupportingTokens();
}
#pragma warning suppress 56500 // covered by FxCOP
catch (Exception e)
{
if (Diagnostics.ExceptionUtility.IsFatal(e))
throw;
completeSelf = true;
completionException = e;
}
if (completeSelf)
{
self.Complete(false, completionException);
}
}
void AddSupportingToken(IAsyncResult result)
{
SupportingTokenProviderSpecification spec = supportingTokenProviders[this.currentTokenProviderIndex];
this.supportingTokens.Add(new SupportingTokenSpecification(spec.TokenProvider.EndGetToken(result), EmptyReadOnlyCollection.Instance, spec.SecurityTokenAttachmentMode, spec.TokenParameters));
++this.currentTokenProviderIndex;
}
bool AddSupportingTokens()
{
while (this.currentTokenProviderIndex < supportingTokenProviders.Count)
{
SupportingTokenProviderSpecification spec = supportingTokenProviders[this.currentTokenProviderIndex];
IAsyncResult result = spec.TokenProvider.BeginGetToken(timeoutHelper.RemainingTime(), getSupportingTokensCallback, this);
if (!result.CompletedSynchronously)
{
return false;
}
this.AddSupportingToken(result);
}
this.binding.AddMessageSupportingTokens(message, ref this.supportingTokens);
return this.OnGetSupportingTokensDone(timeoutHelper.RemainingTime());
}
protected void Start()
{
bool completeSelf;
if (this.binding.TryGetSupportingTokens(this.binding.SecurityProtocolFactory, this.binding.Target, this.binding.Via, this.message, timeoutHelper.RemainingTime(), false, out supportingTokens))
{
completeSelf = this.OnGetSupportingTokensDone(timeoutHelper.RemainingTime());
}
else
{
this.supportingTokens = new Collection();
this.supportingTokenProviders = this.binding.GetSupportingTokenProviders(message.Headers.Action);
if (!(this.supportingTokenProviders != null && this.supportingTokenProviders.Count > 0))
{
DiagnosticUtility.DebugAssert("There must be at least 1 supporting token provider");
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new NotSupportedException("There must be at least 1 supporting token provider"));
}
completeSelf = this.AddSupportingTokens();
}
if (completeSelf)
{
base.Complete(true);
}
}
}
}
}
// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
// Copyright (c) Microsoft Corporation. All rights reserved.
Link Menu

This book is available now!
Buy at Amazon US or
Buy at Amazon UK
- RuntimeArgument.cs
- HttpGetProtocolReflector.cs
- ViewManager.cs
- TypeElement.cs
- TextSchema.cs
- SecureEnvironment.cs
- AtlasWeb.Designer.cs
- AnonymousIdentificationSection.cs
- Error.cs
- PropertyToken.cs
- DrawingContextDrawingContextWalker.cs
- ServiceObjectContainer.cs
- ImageFormat.cs
- SmtpException.cs
- XPathDocumentIterator.cs
- UIElement.cs
- SmtpClient.cs
- DependencyProperty.cs
- TdsParser.cs
- ClientRolePrincipal.cs
- ObjectCloneHelper.cs
- ClientWindowsAuthenticationMembershipProvider.cs
- ClientTargetCollection.cs
- MethodExpr.cs
- AmbientValueAttribute.cs
- DataGridRow.cs
- WebPartConnectionsConfigureVerb.cs
- FrameworkEventSource.cs
- FileLoadException.cs
- DataGridViewImageColumn.cs
- XmlWriter.cs
- EntitySqlQueryState.cs
- EventLogPermissionEntry.cs
- TextWriterTraceListener.cs
- TableItemStyle.cs
- CodeExporter.cs
- ColumnWidthChangingEvent.cs
- HandlerBase.cs
- ValidatorAttribute.cs
- FlowSwitch.cs
- HTTPNotFoundHandler.cs
- EntityDataSourceMemberPath.cs
- DataGridViewCellEventArgs.cs
- HotSpot.cs
- SrgsToken.cs
- Completion.cs
- ConfigXmlAttribute.cs
- ScrollItemPattern.cs
- MouseEvent.cs
- DrawingContextWalker.cs
- SqlNotificationRequest.cs
- IpcPort.cs
- DefaultValueTypeConverter.cs
- HitTestWithGeometryDrawingContextWalker.cs
- PageAsyncTaskManager.cs
- ColorBlend.cs
- XmlNamedNodeMap.cs
- METAHEADER.cs
- ProfileParameter.cs
- NullableBoolConverter.cs
- EnumConverter.cs
- DBConcurrencyException.cs
- DebugView.cs
- XmlAtomicValue.cs
- RegisteredArrayDeclaration.cs
- TreeNode.cs
- JoinGraph.cs
- XmlEncoding.cs
- SafeFileMapViewHandle.cs
- BaseCodeDomTreeGenerator.cs
- Size3DValueSerializer.cs
- Command.cs
- Random.cs
- DecoderNLS.cs
- MethodBody.cs
- WorkflowQueueInfo.cs
- SafeNativeMethods.cs
- Asn1IntegerConverter.cs
- ZipIOModeEnforcingStream.cs
- FrameworkElementAutomationPeer.cs
- HtmlInputCheckBox.cs
- HighlightVisual.cs
- SynchronizingStream.cs
- EpmContentDeSerializerBase.cs
- DesignUtil.cs
- Filter.cs
- MethodRental.cs
- LayoutTableCell.cs
- XmlLoader.cs
- DbModificationClause.cs
- CommandHelpers.cs
- odbcmetadatacolumnnames.cs
- DesignerCategoryAttribute.cs
- RoutedPropertyChangedEventArgs.cs
- XmlReader.cs
- SecurityUniqueId.cs
- BatchParser.cs
- CacheSection.cs
- TreeNodeConverter.cs
- DocumentSequence.cs