e79aa3c0ed
Former-commit-id: a2155e9bd80020e49e72e86c44da02a8ac0e57a4
228 lines
9.2 KiB
C#
228 lines
9.2 KiB
C#
//----------------------------------------------------------------------------
|
|
// Copyright (c) Microsoft Corporation. All rights reserved.
|
|
//----------------------------------------------------------------------------
|
|
|
|
namespace System.ServiceModel.Description
|
|
{
|
|
using System;
|
|
using System.Collections.ObjectModel;
|
|
using System.Net;
|
|
using System.ServiceModel;
|
|
using System.ServiceModel.Channels;
|
|
using System.ServiceModel.Dispatcher;
|
|
using System.ServiceModel.Security;
|
|
using System.ServiceModel.Security.Tokens;
|
|
|
|
public sealed class ServiceAuthenticationBehavior : IServiceBehavior
|
|
{
|
|
internal ServiceAuthenticationManager defaultServiceAuthenticationManager;
|
|
|
|
ServiceAuthenticationManager serviceAuthenticationManager;
|
|
AuthenticationSchemes authenticationSchemes;
|
|
bool isAuthenticationManagerSet;
|
|
bool isAuthenticationSchemesSet;
|
|
bool isReadOnly;
|
|
|
|
public ServiceAuthenticationBehavior()
|
|
{
|
|
this.ServiceAuthenticationManager = defaultServiceAuthenticationManager;
|
|
this.authenticationSchemes = AuthenticationSchemes.None;
|
|
}
|
|
|
|
ServiceAuthenticationBehavior(ServiceAuthenticationBehavior other)
|
|
{
|
|
this.serviceAuthenticationManager = other.ServiceAuthenticationManager;
|
|
this.authenticationSchemes = other.authenticationSchemes;
|
|
this.isReadOnly = other.isReadOnly;
|
|
this.isAuthenticationManagerSet = other.isAuthenticationManagerSet;
|
|
this.isAuthenticationSchemesSet = other.isAuthenticationSchemesSet;
|
|
}
|
|
|
|
public ServiceAuthenticationManager ServiceAuthenticationManager
|
|
{
|
|
get
|
|
{
|
|
return this.serviceAuthenticationManager;
|
|
}
|
|
set
|
|
{
|
|
ThrowIfImmutable();
|
|
this.serviceAuthenticationManager = value;
|
|
this.isAuthenticationManagerSet = value != null;
|
|
}
|
|
}
|
|
|
|
public AuthenticationSchemes AuthenticationSchemes
|
|
{
|
|
get
|
|
{
|
|
return this.authenticationSchemes;
|
|
}
|
|
set
|
|
{
|
|
ThrowIfImmutable();
|
|
this.authenticationSchemes = value;
|
|
this.isAuthenticationSchemesSet = true;
|
|
}
|
|
}
|
|
|
|
public bool ShouldSerializeServiceAuthenticationManager()
|
|
{
|
|
return this.isAuthenticationManagerSet;
|
|
}
|
|
|
|
public bool ShouldSerializeAuthenticationSchemes()
|
|
{
|
|
return this.isAuthenticationSchemesSet;
|
|
}
|
|
|
|
void IServiceBehavior.Validate(ServiceDescription description, ServiceHostBase serviceHostBase)
|
|
{
|
|
}
|
|
|
|
void IServiceBehavior.AddBindingParameters(ServiceDescription description, ServiceHostBase serviceHostBase, Collection<ServiceEndpoint> endpoints, BindingParameterCollection parameters)
|
|
{
|
|
if (parameters == null)
|
|
{
|
|
throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("parameters");
|
|
}
|
|
|
|
if (this.serviceAuthenticationManager != null)
|
|
{
|
|
// throw if bindingParameters already has a AuthenticationManager
|
|
ServiceAuthenticationManager otherAuthenticationManager = parameters.Find<ServiceAuthenticationManager>();
|
|
if (otherAuthenticationManager != null)
|
|
{
|
|
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.GetString(SR.MultipleAuthenticationManagersInServiceBindingParameters, otherAuthenticationManager)));
|
|
}
|
|
|
|
parameters.Add(this.serviceAuthenticationManager);
|
|
}
|
|
|
|
if (this.authenticationSchemes != AuthenticationSchemes.None)
|
|
{
|
|
// throw if bindingParameters already has an AuthenticationSchemes
|
|
AuthenticationSchemesBindingParameter otherAuthenticationSchemesBindingParameter = parameters.Find<AuthenticationSchemesBindingParameter>();
|
|
if (otherAuthenticationSchemesBindingParameter != null)
|
|
{
|
|
if (otherAuthenticationSchemesBindingParameter.AuthenticationSchemes != authenticationSchemes)
|
|
{
|
|
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.GetString(SR.MultipleAuthenticationSchemesInServiceBindingParameters, otherAuthenticationSchemesBindingParameter.AuthenticationSchemes)));
|
|
}
|
|
}
|
|
else
|
|
{
|
|
parameters.Add(new AuthenticationSchemesBindingParameter(this.authenticationSchemes));
|
|
}
|
|
}
|
|
}
|
|
|
|
void IServiceBehavior.ApplyDispatchBehavior(ServiceDescription description, ServiceHostBase serviceHostBase)
|
|
{
|
|
if (description == null)
|
|
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentNullException("description"));
|
|
if (serviceHostBase == null)
|
|
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentNullException("serviceHostBase"));
|
|
|
|
if (this.serviceAuthenticationManager == null)
|
|
{
|
|
return;
|
|
}
|
|
|
|
for (int i = 0; i < serviceHostBase.ChannelDispatchers.Count; i++)
|
|
{
|
|
ChannelDispatcher channelDispatcher = serviceHostBase.ChannelDispatchers[i] as ChannelDispatcher;
|
|
if (channelDispatcher != null && !ServiceMetadataBehavior.IsHttpGetMetadataDispatcher(description, channelDispatcher))
|
|
{
|
|
foreach (EndpointDispatcher endpointDispatcher in channelDispatcher.Endpoints)
|
|
{
|
|
DispatchRuntime behavior = endpointDispatcher.DispatchRuntime;
|
|
behavior.ServiceAuthenticationManager = this.serviceAuthenticationManager;
|
|
|
|
ServiceEndpoint endpoint = FindMatchingServiceEndpoint(description, endpointDispatcher);
|
|
if (endpoint != null)
|
|
{
|
|
bool isSecureConversationBinding = IsSecureConversationBinding(endpoint.Binding);
|
|
|
|
if (isSecureConversationBinding)
|
|
{
|
|
SecurityStandardsManager standardsManager = GetConfiguredSecurityStandardsManager(endpoint.Binding);
|
|
behavior.ServiceAuthenticationManager = new ServiceAuthenticationManagerWrapper(this.serviceAuthenticationManager, new string[] { standardsManager.SecureConversationDriver.CloseAction.Value });
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
internal ServiceAuthenticationBehavior Clone()
|
|
{
|
|
return new ServiceAuthenticationBehavior(this);
|
|
}
|
|
|
|
internal void MakeReadOnly()
|
|
{
|
|
this.isReadOnly = true;
|
|
}
|
|
|
|
void ThrowIfImmutable()
|
|
{
|
|
if (this.isReadOnly)
|
|
{
|
|
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.GetString(SR.ObjectIsReadOnly)));
|
|
}
|
|
}
|
|
|
|
ServiceEndpoint FindMatchingServiceEndpoint(ServiceDescription description, EndpointDispatcher endpointDispatcher)
|
|
{
|
|
foreach (ServiceEndpoint endpoint in description.Endpoints)
|
|
{
|
|
if (endpoint.Address.Equals(endpointDispatcher.EndpointAddress))
|
|
{
|
|
return endpoint;
|
|
}
|
|
}
|
|
|
|
return null;
|
|
}
|
|
|
|
bool IsSecureConversationBinding(Binding binding)
|
|
{
|
|
if (binding == null)
|
|
throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("binding");
|
|
|
|
SecurityBindingElement securityBindingElement = binding.CreateBindingElements().Find<SecurityBindingElement>();
|
|
if (securityBindingElement == null)
|
|
{
|
|
return false;
|
|
}
|
|
|
|
foreach (SecurityTokenParameters tokenParam in new SecurityTokenParametersEnumerable(securityBindingElement, true))
|
|
{
|
|
if (tokenParam is SecureConversationSecurityTokenParameters)
|
|
{
|
|
return true;
|
|
}
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
SecurityStandardsManager GetConfiguredSecurityStandardsManager(Binding binding)
|
|
{
|
|
if (binding == null)
|
|
throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("binding");
|
|
|
|
SecurityBindingElement securityBindingElement = binding.CreateBindingElements().Find<SecurityBindingElement>();
|
|
if (securityBindingElement == null)
|
|
{
|
|
throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgument("binding", SR.GetString(SR.NoSecurityBindingElementFound));
|
|
}
|
|
|
|
return new SecurityStandardsManager(securityBindingElement.MessageSecurityVersion, new WSSecurityTokenSerializer(securityBindingElement.MessageSecurityVersion.SecurityVersion));
|
|
}
|
|
|
|
}
|
|
|
|
}
|