c# - tipos - url significado
Jabón con tejido de servicio-Https y Http vinculante. (3)
Actualmente estoy desarrollando una aplicación de tejido de servicio que expondrá a un oyente de jabón que será consumido por otra aplicación
Sigo recibiendo un error diciendo
No se pudo encontrar una dirección base que coincida con el esquema https para el punto final con el enlace CustomBinding. Los esquemas de dirección base registrados son []
Aquí está el método CreateServiceInstanceListener
protected override IEnumerable<ServiceInstanceListener> CreateServiceInstanceListeners()
{
var serviceInstanceListers = new List<ServiceInstanceListener>()
{
new ServiceInstanceListener(context =>
{
return CreateSoapListener(context);
})
,
new ServiceInstanceListener(context =>
{
return CreateSoapHTTPSListener(context);
}),
};
return serviceInstanceListers;
}
private static ICommunicationListener CreateSoapHTTPSListener(StatelessServiceContext context)
{
string host = context.NodeContext.IPAddressOrFQDN;
var endpointConfig = context.CodePackageActivationContext.GetEndpoint("SecureServiceEndpoint");
int port = endpointConfig.Port;
string scheme = endpointConfig.Protocol.ToString();
string uri = string.Format(CultureInfo.InvariantCulture, "{0}://{1}:{2}/MyService/", scheme, host, port);
var listener = new WcfCommunicationListener<IServiceInterface>(
serviceContext: context,
wcfServiceObject: new Service(),
listenerBinding: new BasicHttpsBinding(BasicHttpsSecurityMode.Transport),
address: new EndpointAddress(uri)
);
// Check to see if the service host already has a ServiceMetadataBehavior
ServiceMetadataBehavior smb = listener.ServiceHost.Description.Behaviors.Find<ServiceMetadataBehavior>();
// If not, add one
if (smb == null)
{
smb = new ServiceMetadataBehavior();
smb.MetadataExporter.PolicyVersion = PolicyVersion.Policy15;
smb.HttpsGetEnabled = true;
smb.HttpsGetUrl = new Uri(uri);
listener.ServiceHost.Description.Behaviors.Add(smb);
}
return listener;
}
private static ICommunicationListener CreateSoapListener(StatelessServiceContext context)
{
string host = context.NodeContext.IPAddressOrFQDN;
var endpointConfig = context.CodePackageActivationContext.GetEndpoint("ServiceEndpoint");
int port = endpointConfig.Port;
string scheme = endpointConfig.Protocol.ToString();
string uri = string.Format(CultureInfo.InvariantCulture, "{0}://{1}:{2}/MyService/", scheme, host, port);
var listener = new WcfCommunicationListener<IServiceInterface>(
serviceContext: context,
wcfServiceObject: new Service(),
listenerBinding: new BasicHttpBinding(BasicHttpSecurityMode.None),
address: new EndpointAddress(uri)
);
// Check to see if the service host already has a ServiceMetadataBehavior
ServiceMetadataBehavior smb = listener.ServiceHost.Description.Behaviors.Find<ServiceMetadataBehavior>();
// If not, add one
if (smb == null)
{
smb = new ServiceMetadataBehavior();
smb.MetadataExporter.PolicyVersion = PolicyVersion.Policy15;
smb.HttpGetEnabled = true;
smb.HttpGetUrl = new Uri(uri);
listener.ServiceHost.Description.Behaviors.Add(smb);
}
return listener;
}
y aquí está la aplicación .config (perdón si hay entradas inútiles, lo copié de una aplicación WCF existente)
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.6.2"/>
</startup>
<system.web>
<customErrors mode="On"></customErrors>
<compilation debug="true" targetFramework="4.6.2"/>
<httpModules>
<add name="ApplicationInsightsWebTracking" type="Microsoft.ApplicationInsights.Web.ApplicationInsightsHttpModule, Microsoft.AI.Web"/>
</httpModules>
<machineKey decryption="AES" decryptionKey="decryptionkey" validation="SHA1" validationKey="validationkey"/>
</system.web>
<system.serviceModel>
<diagnostics wmiProviderEnabled="true">
<messageLogging logEntireMessage="true" logKnownPii="true" logMalformedMessages="true" logMessagesAtServiceLevel="true" logMessagesAtTransportLevel="true"/>
<endToEndTracing propagateActivity="true" activityTracing="true" messageFlowTracing="true"/>
</diagnostics>
<bindings>
<customBinding>
<binding name="HubBinding">
<security defaultAlgorithmSuite="Basic256Sha256Rsa15" allowSerializedSigningTokenOnReply="true" authenticationMode="MutualCertificateDuplex" securityHeaderLayout="Lax" messageProtectionOrder="EncryptBeforeSign" messageSecurityVersion="WSSecurity11WSTrustFebruary2005WSSecureConversationFebruary2005WSSecurityPolicy11BasicSecurityProfile10"/>
<textMessageEncoding messageVersion="Default"/>
<httpsTransport maxReceivedMessageSize="1073741824"/>
</binding>
<binding name="AuthorityCustomBinding">
<security defaultAlgorithmSuite="Basic256Sha256Rsa15" allowSerializedSigningTokenOnReply="true" authenticationMode="MutualCertificateDuplex" securityHeaderLayout="Lax" messageProtectionOrder="EncryptBeforeSign" messageSecurityVersion="WSSecurity11WSTrustFebruary2005WSSecureConversationFebruary2005WSSecurityPolicy11BasicSecurityProfile10"/>
<textMessageEncoding messageVersion="Default"/>
<httpsTransport maxReceivedMessageSize="1073741824"/>
</binding>
<binding name="CustomBinding_IServiceInterface">
<security/>
<textMessageEncoding/>
<httpsTransport/>
</binding>
</customBinding>
</bindings>
<services>
<service name="MyApp.ProductServiceManufacturer" behaviorConfiguration="ManufacturerBehaviour">
<endpoint address="" name="ManufacturerProductService" binding="customBinding" bindingConfiguration="HubBinding" contract="MyApp.IProductServiceV20161"/>
</service>
</services>
<client>
<endpoint address="https://serverurl:8088/IServiceInterface/Service.svc" behaviorConfiguration="HubManufacturerBehavior" binding="customBinding" bindingConfiguration="AuthorityCustomBinding" contract="Service.IServiceInterface" name="CustomBinding_IProductServiceManufacturerV20161">
<identity>
<dns value="ServerCert"/>
</identity>
</endpoint>
</client>
<behaviors>
<endpointBehaviors>
<behavior name="HubManufacturerBehavior">
<clientCredentials>
<clientCertificate findValue="XXXXXX" storeLocation="LocalMachine" storeName="My" x509FindType="FindByThumbprint"/>
<serviceCertificate>
<defaultCertificate findValue="XXXXXX" storeLocation="LocalMachine" storeName="My" x509FindType="FindByThumbprint"/>
</serviceCertificate>
</clientCredentials>
</behavior>
<behavior name="MyApp.ReportingServiceManufacturerAspNetAjaxBehavior">
<enableWebScript/>
</behavior>
</endpointBehaviors>
<serviceBehaviors>
<behavior name="ManufacturerBehaviour">
<serviceMetadata httpGetEnabled="true" httpsGetEnabled="true"/>
<serviceDebug includeExceptionDetailInFaults="true"/>
<serviceCredentials>
<serviceCertificate findValue="XXXXXX" storeLocation="LocalMachine" storeName="My" x509FindType="FindByThumbprint"/>
</serviceCredentials>
<serviceSecurityAudit auditLogLocation="Application" suppressAuditFailure="true" serviceAuthorizationAuditLevel="Failure" messageAuthenticationAuditLevel="Failure"/>
</behavior>
<behavior name="">
<serviceMetadata httpGetEnabled="true"/>
<serviceDebug includeExceptionDetailInFaults="false"/>
</behavior>
</serviceBehaviors>
</behaviors>
<serviceHostingEnvironment aspNetCompatibilityEnabled="true" multipleSiteBindingsEnabled="true"/>
<extensions>
<bindingElementExtensions>
<add name="securityBindingElementExtension" type="MyApp.BindingExtensions.SecurityBindingElementExtension, MyApp"/>
</bindingElementExtensions>
</extensions>
<protocolMapping>
<add binding="basicHttpsBinding" scheme="http"/>
<add binding="customBinding" scheme="https"/>
</protocolMapping>
</system.serviceModel>
<system.webServer>
<modules runAllManagedModulesForAllRequests="true">
<remove name="TelemetryCorrelationHttpModule"/>
<add name="TelemetryCorrelationHttpModule" type="Microsoft.AspNet.TelemetryCorrelation.TelemetryCorrelationHttpModule, Microsoft.AspNet.TelemetryCorrelation" preCondition="integratedMode,managedHandler"/>
<remove name="ApplicationInsightsWebTracking"/>
<add name="ApplicationInsightsWebTracking" type="Microsoft.ApplicationInsights.Web.ApplicationInsightsHttpModule, Microsoft.AI.Web" preCondition="managedHandler"/>
</modules>
<directoryBrowse enabled="true"/>
<validation validateIntegratedModeConfiguration="false"/>
</system.webServer>
</configuration>
¿Qué estoy haciendo mal o qué falta en el código? Cualquier ayuda sería apreciada ya que nunca antes había hecho WCF. Por cierto, la aplicación WCF funciona con la misma configuración cuando se implementa en un servidor, pero si está vagando por qué lo hago con la estructura de servicio, no depende de mí :)
ACTUALIZACIÓN Teniendo en cuenta la respuesta de LoekD, actualicé mi método CreateSoapHTTPSListener y este es el siguiente:
private static ICommunicationListener CreateSoapHTTPSListener(StatelessServiceContext context)
{
string host = context.NodeContext.IPAddressOrFQDN;
var endpointConfig = context.CodePackageActivationContext.GetEndpoint("SecureServiceEndpoint");
int port = endpointConfig.Port;
string scheme = endpointConfig.Protocol.ToString();
var binding = new BasicHttpsBinding(BasicHttpsSecurityMode.Transport);
binding.Security.Transport.ClientCredentialType = HttpClientCredentialType.None;
binding.MaxReceivedMessageSize = 1073741824;
string uri = ConfigurationManager.AppSettings.Get("ProductManufacturerService");
Tools.TraceMessage(uri);
var listener = new WcfCommunicationListener<IProductServiceV20161>(
serviceContext: context,
wcfServiceObject: new ProductServiceManufacturer(),
listenerBinding: binding,
address: new EndpointAddress(uri)
);
listener.ServiceHost.Credentials.ServiceCertificate.SetCertificate(StoreLocation.LocalMachine, StoreName.My, X509FindType.FindByThumbprint, ConfigurationManager.AppSettings.Get("ServiceCertificateThumbprint"));
listener.ServiceHost.Credentials.ClientCertificate.SetCertificate(StoreLocation.LocalMachine, StoreName.My, X509FindType.FindByThumbprint, ConfigurationManager.AppSettings.Get("ClientCertificateThumbprint"));
// Check to see if the service host already has a ServiceMetadataBehavior
ServiceMetadataBehavior smb = listener.ServiceHost.Description.Behaviors.Find<ServiceMetadataBehavior>();
// If not, add one
if (smb == null)
{
smb = new ServiceMetadataBehavior();
smb.MetadataExporter.PolicyVersion = PolicyVersion.Policy15;
smb.HttpsGetEnabled = true;
smb.HttpGetEnabled = false;
smb.HttpsGetUrl = new Uri(uri);
listener.ServiceHost.Description.Behaviors.Add(smb);
}
return listener;
}
Entonces me equivoqué diciendo que:
El Servicio contiene múltiples ServiceEndpoints con diferentes descripciones de contrato, cada una con el nombre = ''IProductServiceV20161'' y el espacio de nombres = ''namespaceurl /''
Supongo que es porque hay dos definiciones del punto final de servicio, una en el archivo app.config y la otra en el archivo .cs. Comenté la etiqueta de punto final en la aplicación.config y funcionó. Sin embargo, el archivo wsdl que estoy recibiendo falta algunas entradas en comparación con el archivo que obtengo con la aplicación WCF.
ACTUALIZACIÓN 2: ¿Cómo especificar la identidad del punto final para el servicio? y ¿es posible usar una clase personalizada BindingElementExtensionElement?
Asegúrese de que el punto final en el manifiesto de servicio esté declarado como tipo ''HTTPS'' y para agregar el certificado SSL al servicio de atención al cliente WCF.
¿Puedes intentar cambiar esto?
listenerBinding: new BasicHttpsBinding(BasicHttpsSecurityMode.Transport)
dentro de esto:
listenerBinding: binding
donde la unión se define como:
var binding = new BasicHttpsBinding(BasicHttpsSecurityMode.Transport)
binding.Security.Transport.ClientCredentialType = HttpClientCredentialType.None;
Más información here .
Y configura el host de servicio con tu certificado SSL:
listener.ServiceHost.Credentials.ServiceCertificate.SetCertificate(StoreLocation.LocalMachine, StoreName.My, X509FindType.FindByThumbprint, "Certificate Thumbprint Here");
Asumiré que enmascaró la huella digital de su certificado con esas X y también cambió el nombre del servidor a serverurl para la dirección del punto final del cliente.
Con esas suposiciones, usaré los valores que veo en el punto final de su cliente para mostrarle lo que parece faltar en la configuración de punto final de su servicio.
Hay dos opciones para configurar la dirección base para su servicio. La primera opción funciona bien para un punto final de servicio y es una solución simple en su configuración; simplemente añada la dirección a su servicio. Me gusta esto:
<service name="MyApp.ProductServiceManufacturer" behaviorConfiguration="ManufacturerBehaviour">
<endpoint address="https://serverurl:8088/IServiceInterface/Service.svc" name="ManufacturerProductService" binding="customBinding" bindingConfiguration="HubBinding" contract="MyApp.IProductServiceV20161"/>
</service>
Segunda opción, que funciona bien para múltiples encabezados de host o incluso si tiene múltiples servicios y desea utilizar transformaciones de configuración para implementaciones de entorno. Esta solución requiere que agregue la (s) dirección (es) base de manera individual y luego solo haga referencia a * .svc en la dirección del punto final. Me gusta esto:
<service name="MyApp.ProductServiceManufacturer" behaviorConfiguration="ManufacturerBehaviour">
<endpoint address="Service.svc" name="ManufacturerProductService" binding="customBinding" bindingConfiguration="HubBinding" contract="MyApp.IProductServiceV20161"/>
<host>
<baseAddresses>
<add baseAddress="https://serverurl:8088/IServiceInterface" />
</baseAddresses>
</host>
</service>
Prueba cualquiera de estos y prueba la codificación feliz.
-Estoy enroscado
Para aquellos que están trabajando en algo similar, esto es lo que terminé (y que funciona perfectamente):
protected override IEnumerable<ServiceInstanceListener> CreateServiceInstanceListeners()
{
var serviceInstanceListers = new List<ServiceInstanceListener>()
{
new ServiceInstanceListener(context =>
{
//return CreateRestListener(context);
return CreateSoapHTTPSListener(context);
}),
};
return serviceInstanceListers;
}
private static ICommunicationListener CreateSoapHTTPSListener(StatelessServiceContext context)
{
var binding = new CustomBinding();
AsymmetricSecurityBindingElement assbe = (AsymmetricSecurityBindingElement)SecurityBindingElement.CreateMutualCertificateBindingElement(
MessageSecurityVersion.WSSecurity10WSTrustFebruary2005WSSecureConversationFebruary2005WSSecurityPolicy11BasicSecurityProfile10);
binding.Elements.Add(assbe);
binding.Elements.Add(new TextMessageEncodingBindingElement());
binding.Elements.Add(new HttpsTransportBindingElement());
// Extract the STS certificate from the certificate store.
X509Store store = new X509Store(StoreName.My, StoreLocation.LocalMachine);
store.Open(OpenFlags.ReadOnly);
X509Certificate2Collection certs = store.Certificates.Find(X509FindType.FindByThumbprint, ConfigurationManager.AppSettings.Get("ClientCertificateThumbprint"), false);
store.Close();
var identity = EndpointIdentity.CreateX509CertificateIdentity(certs[0]);
string uri = ConfigurationManager.AppSettings.Get("ServiceUri");
var listener = new WcfCommunicationListener<IService>(
serviceContext: context,
wcfServiceObject: new Service(),//where service implements IService
listenerBinding: binding,
address: new EndpointAddress(new Uri(uri), identity)
);
listener.ServiceHost.Credentials.ClientCertificate.SetCertificate(StoreLocation.LocalMachine, StoreName.My, X509FindType.FindByThumbprint, ConfigurationManager.AppSettings.Get("ServiceCertificateThumbprint"));
listener.ServiceHost.Credentials.ServiceCertificate.SetCertificate(StoreLocation.LocalMachine, StoreName.My, X509FindType.FindByThumbprint, ConfigurationManager.AppSettings.Get("ClientCertificateThumbprint"));
// Check to see if the service host already has a ServiceMetadataBehavior
ServiceMetadataBehavior smb = listener.ServiceHost.Description.Behaviors.Find<ServiceMetadataBehavior>();
// If not, add one
if (smb == null)
{
smb = new ServiceMetadataBehavior();
smb.MetadataExporter.PolicyVersion = PolicyVersion.Policy12;
smb.HttpsGetEnabled = true;
smb.HttpGetEnabled = false;
smb.HttpsGetUrl = new Uri(uri);
listener.ServiceHost.Description.Behaviors.Add(smb);
}
return listener;
}