428 lines
24 KiB
C#
428 lines
24 KiB
C#
|
//-----------------------------------------------------------------------------
|
||
|
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||
|
//-----------------------------------------------------------------------------
|
||
|
namespace System.ServiceModel.Channels
|
||
|
{
|
||
|
using System;
|
||
|
using System.ServiceModel.Description;
|
||
|
using System.Xml;
|
||
|
using System.Collections.Generic;
|
||
|
using System.Globalization;
|
||
|
using System.Runtime.Serialization;
|
||
|
using System.ServiceModel;
|
||
|
using System.ServiceModel.Security;
|
||
|
using System.ServiceModel.Security.Tokens;
|
||
|
using System.ServiceModel.Dispatcher;
|
||
|
using System.Net.Security;
|
||
|
using System.Text;
|
||
|
|
||
|
public sealed class SymmetricSecurityBindingElement : SecurityBindingElement, IPolicyExportExtension
|
||
|
{
|
||
|
MessageProtectionOrder messageProtectionOrder;
|
||
|
SecurityTokenParameters protectionTokenParameters;
|
||
|
bool requireSignatureConfirmation;
|
||
|
|
||
|
SymmetricSecurityBindingElement(SymmetricSecurityBindingElement elementToBeCloned)
|
||
|
: base(elementToBeCloned)
|
||
|
{
|
||
|
this.messageProtectionOrder = elementToBeCloned.messageProtectionOrder;
|
||
|
if (elementToBeCloned.protectionTokenParameters != null)
|
||
|
this.protectionTokenParameters = (SecurityTokenParameters)elementToBeCloned.protectionTokenParameters.Clone();
|
||
|
this.requireSignatureConfirmation = elementToBeCloned.requireSignatureConfirmation;
|
||
|
}
|
||
|
|
||
|
public SymmetricSecurityBindingElement()
|
||
|
: this((SecurityTokenParameters)null)
|
||
|
{
|
||
|
// empty
|
||
|
}
|
||
|
|
||
|
public SymmetricSecurityBindingElement(SecurityTokenParameters protectionTokenParameters)
|
||
|
: base()
|
||
|
{
|
||
|
this.messageProtectionOrder = SecurityBindingElement.defaultMessageProtectionOrder;
|
||
|
this.requireSignatureConfirmation = SecurityBindingElement.defaultRequireSignatureConfirmation;
|
||
|
this.protectionTokenParameters = protectionTokenParameters;
|
||
|
}
|
||
|
|
||
|
public bool RequireSignatureConfirmation
|
||
|
{
|
||
|
get
|
||
|
{
|
||
|
return this.requireSignatureConfirmation;
|
||
|
}
|
||
|
set
|
||
|
{
|
||
|
this.requireSignatureConfirmation = value;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
public MessageProtectionOrder MessageProtectionOrder
|
||
|
{
|
||
|
get
|
||
|
{
|
||
|
return this.messageProtectionOrder;
|
||
|
}
|
||
|
set
|
||
|
{
|
||
|
if (!MessageProtectionOrderHelper.IsDefined(value))
|
||
|
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentOutOfRangeException("value"));
|
||
|
this.messageProtectionOrder = value;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
public SecurityTokenParameters ProtectionTokenParameters
|
||
|
{
|
||
|
get
|
||
|
{
|
||
|
return this.protectionTokenParameters;
|
||
|
}
|
||
|
set
|
||
|
{
|
||
|
this.protectionTokenParameters = value;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
internal override ISecurityCapabilities GetIndividualISecurityCapabilities()
|
||
|
{
|
||
|
bool supportsServerAuthentication = false;
|
||
|
bool supportsClientAuthentication;
|
||
|
bool supportsClientWindowsIdentity;
|
||
|
GetSupportingTokensCapabilities(out supportsClientAuthentication, out supportsClientWindowsIdentity);
|
||
|
if (ProtectionTokenParameters != null)
|
||
|
{
|
||
|
supportsClientAuthentication = supportsClientAuthentication || ProtectionTokenParameters.SupportsClientAuthentication;
|
||
|
supportsClientWindowsIdentity = supportsClientWindowsIdentity || ProtectionTokenParameters.SupportsClientWindowsIdentity;
|
||
|
|
||
|
if (ProtectionTokenParameters.HasAsymmetricKey)
|
||
|
{
|
||
|
supportsServerAuthentication = ProtectionTokenParameters.SupportsClientAuthentication;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
supportsServerAuthentication = ProtectionTokenParameters.SupportsServerAuthentication;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return new SecurityCapabilities(supportsClientAuthentication, supportsServerAuthentication, supportsClientWindowsIdentity,
|
||
|
ProtectionLevel.EncryptAndSign, ProtectionLevel.EncryptAndSign);
|
||
|
}
|
||
|
|
||
|
internal override bool SessionMode
|
||
|
{
|
||
|
get
|
||
|
{
|
||
|
SecureConversationSecurityTokenParameters secureConversationTokenParameters = this.ProtectionTokenParameters as SecureConversationSecurityTokenParameters;
|
||
|
if (secureConversationTokenParameters != null)
|
||
|
return secureConversationTokenParameters.RequireCancellation;
|
||
|
else
|
||
|
return false;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
internal override bool SupportsDuplex
|
||
|
{
|
||
|
get { return this.SessionMode; }
|
||
|
}
|
||
|
|
||
|
internal override bool SupportsRequestReply
|
||
|
{
|
||
|
get { return true; }
|
||
|
}
|
||
|
|
||
|
public override void SetKeyDerivation(bool requireDerivedKeys)
|
||
|
{
|
||
|
base.SetKeyDerivation(requireDerivedKeys);
|
||
|
if (this.protectionTokenParameters != null)
|
||
|
this.protectionTokenParameters.RequireDerivedKeys = requireDerivedKeys;
|
||
|
}
|
||
|
|
||
|
internal override bool IsSetKeyDerivation(bool requireDerivedKeys)
|
||
|
{
|
||
|
if (!base.IsSetKeyDerivation(requireDerivedKeys))
|
||
|
return false;
|
||
|
|
||
|
if (this.protectionTokenParameters != null && this.protectionTokenParameters.RequireDerivedKeys != requireDerivedKeys)
|
||
|
return false;
|
||
|
|
||
|
return true;
|
||
|
}
|
||
|
|
||
|
internal override SecurityProtocolFactory CreateSecurityProtocolFactory<TChannel>(BindingContext context, SecurityCredentialsManager credentialsManager, bool isForService, BindingContext issuerBindingContext)
|
||
|
{
|
||
|
if (context == null)
|
||
|
throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("context");
|
||
|
if (credentialsManager == null)
|
||
|
throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("credentialsManager");
|
||
|
|
||
|
if (this.ProtectionTokenParameters == null)
|
||
|
{
|
||
|
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.GetString(SR.SymmetricSecurityBindingElementNeedsProtectionTokenParameters, this.ToString())));
|
||
|
}
|
||
|
|
||
|
SymmetricSecurityProtocolFactory protocolFactory = new SymmetricSecurityProtocolFactory();
|
||
|
if (isForService)
|
||
|
{
|
||
|
base.ApplyAuditBehaviorSettings(context, protocolFactory);
|
||
|
}
|
||
|
protocolFactory.SecurityTokenParameters = (SecurityTokenParameters)this.ProtectionTokenParameters.Clone();
|
||
|
SetIssuerBindingContextIfRequired(protocolFactory.SecurityTokenParameters, issuerBindingContext);
|
||
|
protocolFactory.ApplyConfidentiality = true;
|
||
|
protocolFactory.RequireConfidentiality = true;
|
||
|
protocolFactory.ApplyIntegrity = true;
|
||
|
protocolFactory.RequireIntegrity = true;
|
||
|
protocolFactory.IdentityVerifier = this.LocalClientSettings.IdentityVerifier;
|
||
|
protocolFactory.DoRequestSignatureConfirmation = this.RequireSignatureConfirmation;
|
||
|
protocolFactory.MessageProtectionOrder = this.MessageProtectionOrder;
|
||
|
protocolFactory.ProtectionRequirements.Add(SecurityBindingElement.ComputeProtectionRequirements(this, context.BindingParameters, context.Binding.Elements, isForService));
|
||
|
base.ConfigureProtocolFactory(protocolFactory, credentialsManager, isForService, issuerBindingContext, context.Binding);
|
||
|
|
||
|
return protocolFactory;
|
||
|
}
|
||
|
|
||
|
internal override bool RequiresChannelDemuxer()
|
||
|
{
|
||
|
return (base.RequiresChannelDemuxer() || RequiresChannelDemuxer(this.ProtectionTokenParameters));
|
||
|
}
|
||
|
|
||
|
protected override IChannelFactory<TChannel> BuildChannelFactoryCore<TChannel>(BindingContext context)
|
||
|
{
|
||
|
ISecurityCapabilities securityCapabilities = this.GetProperty<ISecurityCapabilities>(context);
|
||
|
SecurityCredentialsManager credentialsManager = context.BindingParameters.Find<SecurityCredentialsManager>();
|
||
|
if (credentialsManager == null)
|
||
|
{
|
||
|
credentialsManager = ClientCredentials.CreateDefaultCredentials();
|
||
|
}
|
||
|
|
||
|
// This adds the demuxer element to the context. We add a demuxer element only if the binding is configured to do
|
||
|
// secure conversation or negotiation
|
||
|
bool requireDemuxer = RequiresChannelDemuxer();
|
||
|
ChannelBuilder channelBuilder = new ChannelBuilder(context, requireDemuxer);
|
||
|
if (requireDemuxer)
|
||
|
{
|
||
|
ApplyPropertiesOnDemuxer(channelBuilder, context);
|
||
|
}
|
||
|
BindingContext issuerBindingContext = context.Clone();
|
||
|
|
||
|
SecurityChannelFactory<TChannel> channelFactory;
|
||
|
if (this.ProtectionTokenParameters is SecureConversationSecurityTokenParameters)
|
||
|
{
|
||
|
SecureConversationSecurityTokenParameters scParameters = (SecureConversationSecurityTokenParameters)this.ProtectionTokenParameters;
|
||
|
if (scParameters.BootstrapSecurityBindingElement == null)
|
||
|
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.GetString(SR.SecureConversationSecurityTokenParametersRequireBootstrapBinding)));
|
||
|
|
||
|
BindingContext scIssuerBindingContext = issuerBindingContext.Clone();
|
||
|
scIssuerBindingContext.BindingParameters.Remove<ChannelProtectionRequirements>();
|
||
|
scIssuerBindingContext.BindingParameters.Add(scParameters.BootstrapProtectionRequirements);
|
||
|
|
||
|
if (scParameters.RequireCancellation)
|
||
|
{
|
||
|
SessionSymmetricMessageSecurityProtocolFactory sessionFactory = new SessionSymmetricMessageSecurityProtocolFactory();
|
||
|
sessionFactory.SecurityTokenParameters = scParameters.Clone();
|
||
|
((SecureConversationSecurityTokenParameters)sessionFactory.SecurityTokenParameters).IssuerBindingContext = scIssuerBindingContext;
|
||
|
sessionFactory.ApplyConfidentiality = true;
|
||
|
sessionFactory.RequireConfidentiality = true;
|
||
|
sessionFactory.ApplyIntegrity = true;
|
||
|
sessionFactory.RequireIntegrity = true;
|
||
|
sessionFactory.IdentityVerifier = this.LocalClientSettings.IdentityVerifier;
|
||
|
sessionFactory.DoRequestSignatureConfirmation = this.RequireSignatureConfirmation;
|
||
|
sessionFactory.MessageProtectionOrder = this.MessageProtectionOrder;
|
||
|
sessionFactory.IdentityVerifier = this.LocalClientSettings.IdentityVerifier;
|
||
|
sessionFactory.ProtectionRequirements.Add(SecurityBindingElement.ComputeProtectionRequirements(this, context.BindingParameters, context.Binding.Elements, false));
|
||
|
base.ConfigureProtocolFactory(sessionFactory, credentialsManager, false, issuerBindingContext, context.Binding);
|
||
|
|
||
|
SecuritySessionClientSettings<TChannel> sessionClientSettings = new SecuritySessionClientSettings<TChannel>();
|
||
|
sessionClientSettings.ChannelBuilder = channelBuilder;
|
||
|
sessionClientSettings.KeyRenewalInterval = this.LocalClientSettings.SessionKeyRenewalInterval;
|
||
|
sessionClientSettings.CanRenewSession = scParameters.CanRenewSession;
|
||
|
sessionClientSettings.KeyRolloverInterval = this.LocalClientSettings.SessionKeyRolloverInterval;
|
||
|
sessionClientSettings.TolerateTransportFailures = this.LocalClientSettings.ReconnectTransportOnFailure;
|
||
|
sessionClientSettings.IssuedSecurityTokenParameters = scParameters.Clone();
|
||
|
((SecureConversationSecurityTokenParameters)sessionClientSettings.IssuedSecurityTokenParameters).IssuerBindingContext = issuerBindingContext;
|
||
|
sessionClientSettings.SecurityStandardsManager = sessionFactory.StandardsManager;
|
||
|
sessionClientSettings.SessionProtocolFactory = sessionFactory;
|
||
|
channelFactory = new SecurityChannelFactory<TChannel>(securityCapabilities, context, sessionClientSettings);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
SymmetricSecurityProtocolFactory protocolFactory = new SymmetricSecurityProtocolFactory();
|
||
|
|
||
|
protocolFactory.SecurityTokenParameters = scParameters.Clone();
|
||
|
((SecureConversationSecurityTokenParameters)protocolFactory.SecurityTokenParameters).IssuerBindingContext = scIssuerBindingContext;
|
||
|
protocolFactory.ApplyConfidentiality = true;
|
||
|
protocolFactory.RequireConfidentiality = true;
|
||
|
protocolFactory.ApplyIntegrity = true;
|
||
|
protocolFactory.RequireIntegrity = true;
|
||
|
protocolFactory.IdentityVerifier = this.LocalClientSettings.IdentityVerifier;
|
||
|
protocolFactory.DoRequestSignatureConfirmation = this.RequireSignatureConfirmation;
|
||
|
protocolFactory.MessageProtectionOrder = this.MessageProtectionOrder;
|
||
|
protocolFactory.ProtectionRequirements.Add(SecurityBindingElement.ComputeProtectionRequirements(this, context.BindingParameters, context.Binding.Elements, false));
|
||
|
base.ConfigureProtocolFactory(protocolFactory, credentialsManager, false, issuerBindingContext, context.Binding);
|
||
|
|
||
|
channelFactory = new SecurityChannelFactory<TChannel>(securityCapabilities, context, channelBuilder, protocolFactory);
|
||
|
}
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
SecurityProtocolFactory protocolFactory = this.CreateSecurityProtocolFactory<TChannel>(context, credentialsManager, false, issuerBindingContext);
|
||
|
channelFactory = new SecurityChannelFactory<TChannel>(securityCapabilities, context, channelBuilder, protocolFactory);
|
||
|
}
|
||
|
|
||
|
return channelFactory;
|
||
|
}
|
||
|
|
||
|
protected override IChannelListener<TChannel> BuildChannelListenerCore<TChannel>(BindingContext context)
|
||
|
{
|
||
|
SecurityChannelListener<TChannel> channelListener = new SecurityChannelListener<TChannel>(this, context);
|
||
|
|
||
|
SecurityCredentialsManager credentialsManager = context.BindingParameters.Find<SecurityCredentialsManager>();
|
||
|
if (credentialsManager == null)
|
||
|
credentialsManager = ServiceCredentials.CreateDefaultCredentials();
|
||
|
|
||
|
// This adds the demuxer element to the context. We add a demuxer element only if the binding is configured to do
|
||
|
// secure conversation or negotiation
|
||
|
|
||
|
bool requireDemuxer = RequiresChannelDemuxer();
|
||
|
ChannelBuilder channelBuilder = new ChannelBuilder(context, requireDemuxer);
|
||
|
if (requireDemuxer)
|
||
|
{
|
||
|
ApplyPropertiesOnDemuxer(channelBuilder, context);
|
||
|
}
|
||
|
|
||
|
BindingContext issuerBindingContext = context.Clone();
|
||
|
|
||
|
if (this.ProtectionTokenParameters is SecureConversationSecurityTokenParameters)
|
||
|
{
|
||
|
SecureConversationSecurityTokenParameters scParameters = (SecureConversationSecurityTokenParameters)this.ProtectionTokenParameters;
|
||
|
if (scParameters.BootstrapSecurityBindingElement == null)
|
||
|
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.GetString(SR.SecureConversationSecurityTokenParametersRequireBootstrapBinding)));
|
||
|
|
||
|
BindingContext scIssuerBindingContext = issuerBindingContext.Clone();
|
||
|
scIssuerBindingContext.BindingParameters.Remove<ChannelProtectionRequirements>();
|
||
|
scIssuerBindingContext.BindingParameters.Add(scParameters.BootstrapProtectionRequirements);
|
||
|
IMessageFilterTable<EndpointAddress> endpointFilterTable = context.BindingParameters.Find<IMessageFilterTable<EndpointAddress>>();
|
||
|
|
||
|
AddDemuxerForSecureConversation(channelBuilder, scIssuerBindingContext);
|
||
|
|
||
|
if (scParameters.RequireCancellation)
|
||
|
{
|
||
|
SessionSymmetricMessageSecurityProtocolFactory sessionFactory = new SessionSymmetricMessageSecurityProtocolFactory();
|
||
|
base.ApplyAuditBehaviorSettings(context, sessionFactory);
|
||
|
sessionFactory.SecurityTokenParameters = scParameters.Clone();
|
||
|
((SecureConversationSecurityTokenParameters)sessionFactory.SecurityTokenParameters).IssuerBindingContext = scIssuerBindingContext;
|
||
|
sessionFactory.ApplyConfidentiality = true;
|
||
|
sessionFactory.RequireConfidentiality = true;
|
||
|
sessionFactory.ApplyIntegrity = true;
|
||
|
sessionFactory.RequireIntegrity = true;
|
||
|
sessionFactory.IdentityVerifier = this.LocalClientSettings.IdentityVerifier;
|
||
|
sessionFactory.DoRequestSignatureConfirmation = this.RequireSignatureConfirmation;
|
||
|
sessionFactory.MessageProtectionOrder = this.MessageProtectionOrder;
|
||
|
sessionFactory.IdentityVerifier = this.LocalClientSettings.IdentityVerifier;
|
||
|
sessionFactory.ProtectionRequirements.Add(SecurityBindingElement.ComputeProtectionRequirements(this, context.BindingParameters, context.Binding.Elements, true));
|
||
|
base.ConfigureProtocolFactory(sessionFactory, credentialsManager, true, issuerBindingContext, context.Binding);
|
||
|
|
||
|
channelListener.SessionMode = true;
|
||
|
channelListener.SessionServerSettings.InactivityTimeout = this.LocalServiceSettings.InactivityTimeout;
|
||
|
channelListener.SessionServerSettings.KeyRolloverInterval = this.LocalServiceSettings.SessionKeyRolloverInterval;
|
||
|
channelListener.SessionServerSettings.MaximumPendingSessions = this.LocalServiceSettings.MaxPendingSessions;
|
||
|
channelListener.SessionServerSettings.MaximumKeyRenewalInterval = this.LocalServiceSettings.SessionKeyRenewalInterval;
|
||
|
channelListener.SessionServerSettings.TolerateTransportFailures = this.LocalServiceSettings.ReconnectTransportOnFailure;
|
||
|
channelListener.SessionServerSettings.CanRenewSession = scParameters.CanRenewSession;
|
||
|
channelListener.SessionServerSettings.IssuedSecurityTokenParameters = scParameters.Clone();
|
||
|
((SecureConversationSecurityTokenParameters)channelListener.SessionServerSettings.IssuedSecurityTokenParameters).IssuerBindingContext = scIssuerBindingContext;
|
||
|
channelListener.SessionServerSettings.SecurityStandardsManager = sessionFactory.StandardsManager;
|
||
|
channelListener.SessionServerSettings.SessionProtocolFactory = sessionFactory;
|
||
|
channelListener.SessionServerSettings.SessionProtocolFactory.EndpointFilterTable = endpointFilterTable;
|
||
|
|
||
|
// pass in the error handler for handling unknown security sessions - dont do this if the underlying channel is duplex since sending
|
||
|
// back faults in response to badly secured requests over duplex can result in DoS.
|
||
|
if (context.BindingParameters != null && context.BindingParameters.Find<IChannelDemuxFailureHandler>() == null
|
||
|
&& !IsUnderlyingListenerDuplex<TChannel>(context))
|
||
|
{
|
||
|
context.BindingParameters.Add(new SecuritySessionServerSettings.SecuritySessionDemuxFailureHandler(sessionFactory.StandardsManager));
|
||
|
}
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
SymmetricSecurityProtocolFactory protocolFactory = new SymmetricSecurityProtocolFactory();
|
||
|
base.ApplyAuditBehaviorSettings(context, protocolFactory);
|
||
|
protocolFactory.SecurityTokenParameters = scParameters.Clone();
|
||
|
((SecureConversationSecurityTokenParameters)protocolFactory.SecurityTokenParameters).IssuerBindingContext = scIssuerBindingContext;
|
||
|
protocolFactory.ApplyConfidentiality = true;
|
||
|
protocolFactory.RequireConfidentiality = true;
|
||
|
protocolFactory.ApplyIntegrity = true;
|
||
|
protocolFactory.RequireIntegrity = true;
|
||
|
protocolFactory.IdentityVerifier = this.LocalClientSettings.IdentityVerifier;
|
||
|
protocolFactory.DoRequestSignatureConfirmation = this.RequireSignatureConfirmation;
|
||
|
protocolFactory.MessageProtectionOrder = this.MessageProtectionOrder;
|
||
|
protocolFactory.ProtectionRequirements.Add(SecurityBindingElement.ComputeProtectionRequirements(this, context.BindingParameters, context.Binding.Elements, true));
|
||
|
protocolFactory.EndpointFilterTable = endpointFilterTable;
|
||
|
base.ConfigureProtocolFactory(protocolFactory, credentialsManager, true, issuerBindingContext, context.Binding);
|
||
|
|
||
|
channelListener.SecurityProtocolFactory = protocolFactory;
|
||
|
}
|
||
|
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
SecurityProtocolFactory protocolFactory = this.CreateSecurityProtocolFactory<TChannel>(context, credentialsManager, true, issuerBindingContext);
|
||
|
channelListener.SecurityProtocolFactory = protocolFactory;
|
||
|
}
|
||
|
|
||
|
channelListener.InitializeListener(channelBuilder);
|
||
|
|
||
|
return channelListener;
|
||
|
}
|
||
|
|
||
|
public override T GetProperty<T>(BindingContext context)
|
||
|
{
|
||
|
if (context == null)
|
||
|
throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("context");
|
||
|
|
||
|
if (typeof(T) == typeof(ChannelProtectionRequirements))
|
||
|
{
|
||
|
AddressingVersion addressing = MessageVersion.Default.Addressing;
|
||
|
#pragma warning suppress 56506
|
||
|
MessageEncodingBindingElement encoding = context.Binding.Elements.Find<MessageEncodingBindingElement>();
|
||
|
if (encoding != null)
|
||
|
{
|
||
|
addressing = encoding.MessageVersion.Addressing;
|
||
|
}
|
||
|
ChannelProtectionRequirements myRequirements = base.GetProtectionRequirements(addressing, ProtectionLevel.EncryptAndSign);
|
||
|
myRequirements.Add(context.GetInnerProperty<ChannelProtectionRequirements>() ?? new ChannelProtectionRequirements());
|
||
|
return (T)(object)myRequirements;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
return base.GetProperty<T>(context);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
public override string ToString()
|
||
|
{
|
||
|
StringBuilder sb = new StringBuilder();
|
||
|
sb.AppendLine(base.ToString());
|
||
|
|
||
|
sb.AppendLine(String.Format(CultureInfo.InvariantCulture, "MessageProtectionOrder: {0}", this.messageProtectionOrder.ToString()));
|
||
|
sb.AppendLine(String.Format(CultureInfo.InvariantCulture, "RequireSignatureConfirmation: {0}", this.requireSignatureConfirmation.ToString()));
|
||
|
sb.Append("ProtectionTokenParameters: ");
|
||
|
if (this.protectionTokenParameters != null)
|
||
|
sb.AppendLine(this.protectionTokenParameters.ToString().Trim().Replace("\n", "\n "));
|
||
|
else
|
||
|
sb.AppendLine("null");
|
||
|
|
||
|
return sb.ToString().Trim();
|
||
|
}
|
||
|
|
||
|
public override BindingElement Clone()
|
||
|
{
|
||
|
return new SymmetricSecurityBindingElement(this);
|
||
|
}
|
||
|
|
||
|
void IPolicyExportExtension.ExportPolicy(MetadataExporter exporter, PolicyConversionContext context)
|
||
|
{
|
||
|
SecurityBindingElement.ExportPolicy(exporter, context);
|
||
|
}
|
||
|
}
|
||
|
}
|