e79aa3c0ed
Former-commit-id: a2155e9bd80020e49e72e86c44da02a8ac0e57a4
131 lines
6.5 KiB
C#
131 lines
6.5 KiB
C#
// <copyright>
|
|
// Copyright (c) Microsoft Corporation. All rights reserved.
|
|
// </copyright>
|
|
|
|
namespace System.ServiceModel.Web
|
|
{
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using System.Net;
|
|
using System.Runtime;
|
|
using System.ServiceModel.Activation;
|
|
using System.ServiceModel.Channels;
|
|
using System.ServiceModel.Configuration;
|
|
using System.ServiceModel.Description;
|
|
|
|
internal abstract class AutomaticEndpointGenerator
|
|
{
|
|
private IDictionary<string, ContractDescription> implementedContracts;
|
|
private string multipleContractsErrorMessage;
|
|
private string noContractErrorMessage;
|
|
private string standardEndpointKind;
|
|
private Type singleImplementedContract;
|
|
|
|
protected AutomaticEndpointGenerator(IDictionary<string, ContractDescription> implementedContracts, string multipleContractsErrorMessage, string noContractErrorMessage, string standardEndpointKind)
|
|
{
|
|
Fx.Assert(implementedContracts != null, "The 'implementedContracts' parameter should not be null.");
|
|
Fx.Assert(multipleContractsErrorMessage != null, "The 'multipleContractsErrorMessage' parameter should not be null.");
|
|
Fx.Assert(noContractErrorMessage != null, "The 'noContractErrorMessage' parameter should not be null.");
|
|
Fx.Assert(standardEndpointKind != null, "The 'standardEndpointKind' parameter should not be null.");
|
|
|
|
this.implementedContracts = implementedContracts;
|
|
this.multipleContractsErrorMessage = multipleContractsErrorMessage;
|
|
this.noContractErrorMessage = noContractErrorMessage;
|
|
this.standardEndpointKind = standardEndpointKind;
|
|
}
|
|
|
|
protected abstract string BindingCollectionElementName { get; }
|
|
|
|
public ServiceEndpoint GenerateServiceEndpoint(ServiceHostBase serviceHost, Uri baseAddress)
|
|
{
|
|
Fx.Assert(serviceHost != null, "The 'serviceHost' parameter should not be null.");
|
|
Fx.Assert(baseAddress != null, "The 'baseAddress' parameter should not be null.");
|
|
|
|
AuthenticationSchemes supportedSchemes = GetAuthenticationSchemes(baseAddress);
|
|
Type contractType = this.GetSingleImplementedContract();
|
|
ConfigLoader configLoader = new ConfigLoader(serviceHost.GetContractResolver(this.implementedContracts));
|
|
ServiceEndpointElement serviceEndpointElement = new ServiceEndpointElement();
|
|
|
|
serviceEndpointElement.Contract = contractType.FullName;
|
|
this.SetBindingConfiguration(baseAddress.Scheme, serviceEndpointElement);
|
|
serviceEndpointElement.Kind = this.standardEndpointKind;
|
|
|
|
ServiceEndpoint serviceEndpoint = configLoader.LookupEndpoint(serviceEndpointElement, null, serviceHost, serviceHost.Description, true);
|
|
this.ConfigureBinding(serviceEndpoint.Binding, baseAddress.Scheme, supportedSchemes, AspNetEnvironment.Enabled);
|
|
|
|
// Setting the Endpoint address and listenUri now that we've set the binding security
|
|
ConfigLoader.ConfigureEndpointAddress(serviceEndpointElement, serviceHost, serviceEndpoint);
|
|
ConfigLoader.ConfigureEndpointListenUri(serviceEndpointElement, serviceHost, serviceEndpoint);
|
|
|
|
return serviceEndpoint;
|
|
}
|
|
|
|
protected abstract void ConfigureBinding(Binding binding, string uriScheme, AuthenticationSchemes supportedAuthenticationSchemes, bool hostedEnvironment);
|
|
|
|
private static AuthenticationSchemes GetAuthenticationSchemes(Uri baseAddress)
|
|
{
|
|
AuthenticationSchemes supportedSchemes = AspNetEnvironment.Current.GetAuthenticationSchemes(baseAddress);
|
|
|
|
if (AspNetEnvironment.Current.IsSimpleApplicationHost)
|
|
{
|
|
// Cassini always reports the auth scheme as anonymous or Ntlm. Map this to Ntlm, except when forms auth
|
|
// is requested
|
|
if (supportedSchemes == (AuthenticationSchemes.Anonymous | AuthenticationSchemes.Ntlm))
|
|
{
|
|
if (AspNetEnvironment.Current.IsWindowsAuthenticationConfigured())
|
|
{
|
|
supportedSchemes = AuthenticationSchemes.Ntlm;
|
|
}
|
|
else
|
|
{
|
|
supportedSchemes = AuthenticationSchemes.Anonymous;
|
|
}
|
|
}
|
|
}
|
|
|
|
return supportedSchemes;
|
|
}
|
|
|
|
private Type GetSingleImplementedContract()
|
|
{
|
|
if (this.singleImplementedContract == null)
|
|
{
|
|
Fx.Assert(this.implementedContracts != null, "The 'implementedContracts' field should not be null.");
|
|
Fx.Assert(this.multipleContractsErrorMessage != null, "The 'multipleContractsErrorMessage' field should not be null.");
|
|
Fx.Assert(this.noContractErrorMessage != null, "The 'noContractErrorMessage' field should not be null.");
|
|
|
|
if (this.implementedContracts.Count > 1)
|
|
{
|
|
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(this.multipleContractsErrorMessage));
|
|
}
|
|
else if (this.implementedContracts.Count == 0)
|
|
{
|
|
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(this.noContractErrorMessage));
|
|
}
|
|
|
|
foreach (ContractDescription contract in this.implementedContracts.Values)
|
|
{
|
|
this.singleImplementedContract = contract.ContractType;
|
|
break;
|
|
}
|
|
}
|
|
|
|
return this.singleImplementedContract;
|
|
}
|
|
|
|
private void SetBindingConfiguration(string uriScheme, ServiceEndpointElement serviceEndpointElement)
|
|
{
|
|
Fx.Assert(uriScheme != null, "The 'uriScheme' parameter should not be null.");
|
|
Fx.Assert(serviceEndpointElement != null, "The 'serviceEndpointElement' parameter should not be null.");
|
|
Fx.Assert(this.BindingCollectionElementName != null, "The 'this.BindingCollectionElementName' property should not be null.");
|
|
|
|
ProtocolMappingItem protocolMappingItem = ConfigLoader.LookupProtocolMapping(uriScheme);
|
|
if (protocolMappingItem != null &&
|
|
string.Equals(protocolMappingItem.Binding, this.BindingCollectionElementName, StringComparison.Ordinal))
|
|
{
|
|
serviceEndpointElement.BindingConfiguration = protocolMappingItem.BindingConfiguration;
|
|
}
|
|
}
|
|
}
|
|
}
|