1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130
|
// <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;
}
}
}
}
|