I have a problem to pass username and password through Castle Windsor register by using custom WCF authentication.
I have a Web service configuration like below :
<system.serviceModel>
<bindings>
<wsHttpBinding>
<binding name="wsSecureBinding">
<security mode="TransportWithMessageCredential">
<message clientCredentialType="UserName" />
</security>
</binding>
</wsHttpBinding>
</bindings>
<services>
<service behaviorConfiguration="defaultProfile" name="GS1.CSSM.XMLGenerate.WebService.Implementation.XMLGenerateService">
<endpoint address="" binding="wsHttpBinding" bindingConfiguration="wsSecureBinding" name="wsSecureService" contract="GS1.CSSM.XMLGenerate.WebService.Interface.IXMLGenerateService">
</endpoint>
<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange"/>
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior name="defaultProfile">
<serviceMetadata httpGetEnabled="false" httpsGetEnabled="true"/>
<serviceDebug includeExceptionDetailInFaults="false"/>
<serviceCredentials>
<userNameAuthentication userNamePasswordValidationMode="Custom" customUserNamePasswordValidatorType="GS1.CSSM.XMLGenerate.WebService.ServiceAuthenticator, GS1.CSSM.XMLGenerate.WebService"/>
</serviceCredentials>
</behavior>
<behavior name="noAuthentication">
<serviceMetadata httpGetEnabled="false" httpsGetEnabled="true"/>
<serviceDebug includeExceptionDetailInFaults="false"/>
</behavior>
</serviceBehaviors>
</behaviors>
<!--<protocolMapping>
<add binding="basicHttpsBinding" scheme="https" />
</protocolMapping>-->
<serviceHostingEnvironment aspNetCompatibilityEnabled="true" multipleSiteBindingsEnabled="true" />
</system.serviceModel>
This is the Container Setup :
var container = new WindsorContainer();
container.AddFacility()
.Register(
Component.For<IXMLGenerateService>()
.ImplementedBy<XMLGenerateServiceClient>()
.AsWcfClient(
new DefaultClientModel
{
Endpoint =
WcfEndpoint.FromConfiguration("wsSecureService")
}.Credentials(new UserNameCredentials("zul", "password"))));
And this is client config file :
<system.serviceModel>
<bindings>
<wsHttpBinding>
<binding name="wsSecureService">
<security mode="TransportWithMessageCredential">
<message clientCredentialType="UserName" />
</security>
</binding>
</wsHttpBinding>
</bindings>
<client>
<endpoint address="https://localhost:44302/Service/XMLGenerateService.svc" binding="wsHttpBinding" bindingConfiguration="wsSecureService" contract="XMLGenerateService.IXMLGenerateService" name="wsSecureService" />
</client>
</system.serviceModel>
I got this error "Additional information: The username is not provided. Specify username in ClientCredentials." once I tried to call method from the service.
Any ideas?
I will answer it by myself :)
here it is how i resolved that issue
container.Kernel.AddFacility<WcfFacility>()
.Register(Component.For<IXMLGenerateService>()
.AsWcfClient(new DefaultClientModel
{
Endpoint = WcfEndpoint.FromConfiguration("wsSecureService")
}.Credentials(new UserNameCredentials("zul", "password"))));
_smXMLGenerateService = container.Resolve<IXMLGenerateService>();
Hopefully, it can help anyone with the same issue.
Related
I'm trying to configure WCF authentication with UserName but without success, I have tried a a lot of solution that I found already, but nothing seem to work for me.
The HTTP request is unauthorized with client authentication scheme
'Anonymous'. The authentication header received from the server was
'Negotiate,NTLM,Basic realm="localhost"'.
Server setting
<system.serviceModel>
<bindings>
<wsHttpBinding>
<binding name="basicHttpBindingConfiguration">
<security mode="TransportWithMessageCredential">
<message clientCredentialType="UserName" negotiateServiceCredential="false" />
<transport clientCredentialType="None" />
</security>
</binding>
</wsHttpBinding>
</bindings>
<services>
<service name="Namespace.Service" behaviorConfiguration="wsHttpBehavior">
<endpoint binding="wsHttpBinding" bindingConfiguration="basicHttpBindingConfiguration" name="Soap" bindingNamespace="/WebServices" contract="Namespace.IService">
</endpoint>
<endpoint address="mex" binding="mexHttpsBinding" contract="IMetadataExchange" name="mex" />
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior name="wsHttpBehavior">
<serviceMetadata httpGetEnabled="true" httpsGetEnabled="true" />
<serviceDebug includeExceptionDetailInFaults="false" />
<serviceCredentials>
<userNameAuthentication userNamePasswordValidationMode="Custom" customUserNamePasswordValidatorType="UserNamePasswordValidator, WebApplication" />
<!--<serviceCertificate findValue="ServiceModelSamples-HTTPS-Server" storeLocation="LocalMachine" storeName="My" x509FindType="FindBySubjectName" />-->
</serviceCredentials>
</behavior>
</serviceBehaviors>
</behaviors>
<serviceHostingEnvironment aspNetCompatibilityEnabled="true" multipleSiteBindingsEnabled="true" />
</system.serviceModel>
On the client side
<system.serviceModel>
<bindings>
<wsHttpBinding>
<binding name="Soap">
<security mode="TransportWithMessageCredential">
<transport clientCredentialType="None" />
<message clientCredentialType="UserName" />
</security>
</binding>
</wsHttpBinding>
</bindings>
<client>
<endpoint address="https://localhost:85/WebServices/Service.svc"
binding="wsHttpBinding" bindingConfiguration="Soap" contract="ServiceReference1.IService"
name="Soap" />
</client>
</system.serviceModel>
Here is my IIS config
Most of solution that I found use Windows Transport, I need Authentication only through Username.
I check this :
https://blog.sandervanlooveren.be/posts/securing-a-wcf-service-with-username-and-password/
https://learn.microsoft.com/en-us/dotnet/framework/wcf/samples/ws-transport-with-message-credential
I have tried security mode="Message" and security mode="TransportWithMessageCredential" without success
My client code look like :
// Instantiate the proxy
var proxy = new ServiceClient();
proxy.ClientCredentials.UserName.UserName = "username";
proxy.ClientCredentials.UserName.Password = "password";
Please can anyone check my config and tell what I'm setting wrong ?
Edit:
This is a Service inside an ASP.Net MVC5 App, Can this also be a problem ?
There might be something amiss with the customUserNamePasswordValidatorType property string.It is usually in the following form
customUserNamePasswordValidatorType="Namespace.MyCustUserNamePasswordVal,Namespace"
Can you access the WSDL of hosting service? Also, turning on the anonymous authentication is enough, unnecessary to enable others authentication.
Here is my configuration, I used simplified configuration which be supported in WCF4.5, wish it is useful to you.
<system.serviceModel>
<behaviors>
<serviceBehaviors>
<behavior>
<serviceMetadata httpGetEnabled="true" httpsGetEnabled="true"/>
<serviceDebug includeExceptionDetailInFaults="false"/>
<serviceCredentials>
<userNameAuthentication customUserNamePasswordValidatorType="WcfService1.CustUserNamePasswordVal,WcfService1" userNamePasswordValidationMode="Custom"/>
</serviceCredentials>
</behavior>
</serviceBehaviors>
</behaviors>
<bindings>
<wsHttpBinding>
<binding>
<security mode="TransportWithMessageCredential">
<message clientCredentialType="UserName"/>
</security>
</binding>
</wsHttpBinding>
</bindings>
<protocolMapping>
<add binding="wsHttpBinding" scheme="https" />
</protocolMapping>
<serviceHostingEnvironment aspNetCompatibilityEnabled="true" multipleSiteBindingsEnabled="true" />
</system.serviceModel>
Feel free to let me know If there is anything I can help with.
I've created my custom Certificate Authority (CA) using openssl. Then I've created certificated using the previous one and the request from IIS. So now I have chain of certificates. Then I've bound the second one to my WCF service and every thing is fine. Then on client I've installed my CA certificate in Trusted Root Certification Authority to make it able to recognize my custom certificate.
My WCF service currently run on simple http connection.
Server side:
<system.serviceModel>
<behaviors>
<serviceBehaviors>
<behavior name="SyncWcfServices.MainServiceBehavior">
<serviceMetadata httpGetEnabled="true" httpsGetEnabled="true" />
<serviceDebug includeExceptionDetailInFaults="true" />
</behavior>
</serviceBehaviors>
</behaviors>
<bindings>
<wsHttpBinding>
<binding name="ExtendedMaxSize" maxReceivedMessageSize="2147483647">
<security mode="None">
<transport clientCredentialType="None"></transport>
</security>
</binding>
</wsHttpBinding>
</bindings>
<services>
<service name="SyncWcfServices.MainService" behaviorConfiguration="SyncWcfServices.MainServiceBehavior">
<endpoint address="/syncService.svc" binding="wsHttpBinding" bindingConfiguration="ExtendedMaxSize" contract="SyncWcfServices.IMainService"></endpoint>
<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange"></endpoint>
</service>
</services>
<serviceHostingEnvironment aspNetCompatibilityEnabled="true" multipleSiteBindingsEnabled="true" />
</system.serviceModel>
Client side:
<system.serviceModel>
<bindings>
<wsHttpBinding>
<binding name="WSHttpBinding_IMainService" maxReceivedMessageSize="2147483647" sendTimeout="00:10:00">
<security mode="None" />
</binding>
</wsHttpBinding>
</bindings>
<client>
<endpoint address="http://localhost/SyncService/SyncService.svc"
binding="wsHttpBinding" bindingConfiguration="WSHttpBinding_IMainService"
contract="SyncServiceReference.IMainService" name="WSHttpBinding_IMainService" />
</client>
</system.serviceModel>
So, I need to change this settings to support SSL connection. I've read a lot of post how to do it but there always using 2-way certification check that mean server must check client certificate and client must check server certificate. But I only want client to check server certificate using CA that I installed. And server will check with ordinary credentials (username, password) as it was before. I think that I have to change the security mode to Transport in both sides and server mex endpoint to mexHttpsBinding but what should I do next? Please help to resolve it.
Thanks you all!
Finally I found the correct way! So server side:
<system.serviceModel>
<behaviors>
<serviceBehaviors>
<behavior name="SyncWcfServices.MainServiceBehavior">
<serviceMetadata httpGetEnabled="true" httpsGetEnabled="true" />
<serviceDebug includeExceptionDetailInFaults="true" />
<serviceCredentials>
<serviceCertificate
findValue = "*.mydomain.com"
storeLocation = "LocalMachine"
storeName = "My"
x509FindType = "FindBySubjectName"
/>
</serviceCredentials>
</behavior>
</serviceBehaviors>
</behaviors>
<bindings>
<wsHttpBinding>
<binding name="ExtendedMaxSize" maxReceivedMessageSize="2147483647">
<security mode="Transport">
<transport clientCredentialType="None"></transport>
</security>
</binding>
</wsHttpBinding>
</bindings>
<services>
<service name="SyncWcfServices.MainService" behaviorConfiguration="SyncWcfServices.MainServiceBehavior">
<endpoint address="" binding="wsHttpBinding" bindingConfiguration="ExtendedMaxSize" contract="SyncWcfServices.IMainService"></endpoint>
<endpoint address="mex" binding="mexHttpsBinding" contract="IMetadataExchange"></endpoint>
<host>
<baseAddresses>
<add baseAddress="http://localhost:8095/Design_Time_Addresses/SyncWcfServices/MainService/" />
</baseAddresses>
</host>
</service>
</services>
<serviceHostingEnvironment aspNetCompatibilityEnabled="true" multipleSiteBindingsEnabled="true" />
</system.serviceModel>
Client Side:
<system.serviceModel>
<behaviors>
<endpointBehaviors>
<behavior name = "ServiceCertificate">
<clientCredentials>
<serviceCertificate>
<authentication certificateValidationMode = "ChainTrust"/>
</serviceCertificate>
</clientCredentials>
</behavior>
</endpointBehaviors>
</behaviors>
<bindings>
<wsHttpBinding>
<binding name="ExtendedMaxSize" maxReceivedMessageSize="2147483647">
<security mode="Transport">
<transport clientCredentialType="None"></transport>
</security>
</binding>
</wsHttpBinding>
</bindings>
<client>
<endpoint address="https://localhost/SyncService/SyncService.svc"
binding="wsHttpBinding" bindingConfiguration="ExtendedMaxSize"
behaviorConfiguration = "ServiceCertificate"
contract="SyncServiceReference.IMainService" name="WSHttpBinding_IMainService">
</endpoint>
</client>
</system.serviceModel>
Hope it will help someone!
Also please look at "Programming WCF Services" (4th edition) book by Juval Lowy & Michael Montgomery. It's a great book!
I have a .net client and I am consuming the WCF service and able to do that sucessfully. but when i try to post that on our production I am not able to consume the same service. Below is my web.config :
<system.serviceModel>
<behaviors>
<serviceBehaviors>
<behavior name="MyBehavior">
<useRequestHeadersForMetadataAddress></useRequestHeadersForMetadataAddress>
<serviceMetadata httpGetEnabled="true"/>
<serviceDebug includeExceptionDetailInFaults="false"/>
<serviceCredentials>
<userNameAuthentication userNamePasswordValidationMode="Custom" customUserNamePasswordValidatorType="TestProject.Implementations.AuthenticateUser,TestProject"/>
<serviceCertificate findValue="localhost" x509FindType="FindBySubjectName" storeLocation="LocalMachine" storeName="My"/>
</serviceCredentials>
</behavior>
</serviceBehaviors>
</behaviors>
<services>
<service name="TestProject.Implementations.ServiceCustom" behaviorConfiguration="MyBehavior">
<endpoint address="" binding="wsHttpBinding" bindingConfiguration="SampleServiceBinding" contract="TestProject.Interfaces.IServiceCustom"></endpoint>
<endpoint contract="IMetadataExchange" binding="mexHttpBinding" address="mex"></endpoint>
</service>
</services>
<bindings>
<wsHttpBinding>
<binding name="SampleServiceBinding">
<security mode ="Message">
<message clientCredentialType="UserName"/>
</security>
</binding>
</wsHttpBinding>
</bindings>
and also I want to make my service HTTPS enabled.
I get below errormessage:
There was no endpoint listening at http://url.com that could accept the message. This is often caused by an incorrect address or SOAP action. See InnerException, if present, for more details.
This error clearly suggest that the WCF service you are trying to access is not clearly hosted, or the address you are using to connect to is not pointing to the service, make sure by using the address in a browser you are able to access that service.
If you are able to access the service , check your client application web.config and find out the end point details for that service. If the endpoint url is mismatched you may get this error.
I fixed the error and below is the web config code:
<system.serviceModel>
<behaviors>
<serviceBehaviors>
<behavior name="MyBehavior">
<useRequestHeadersForMetadataAddress></useRequestHeadersForMetadataAddress>
<serviceMetadata httpGetEnabled="true" httpsGetEnabled="true" />
<serviceDebug includeExceptionDetailInFaults="false"/>
<serviceCredentials>
<userNameAuthentication userNamePasswordValidationMode="Custom" customUserNamePasswordValidatorType="TestProject.Implementations.AuthenticateUser,TestProject"/>
<serviceCertificate findValue="localhost" x509FindType="FindBySubjectName" storeLocation="LocalMachine" storeName="My"/>
</serviceCredentials>
</behavior>
</serviceBehaviors>
</behaviors>
<services>
<service name="TestProject.Implementations.Test" behaviorConfiguration="MyBehavior">
<endpoint address="http://rul" binding="wsHttpBinding" bindingConfiguration="SampleServiceBinding" contract="TestProject.Interfaces.Test"></endpoint>
<endpoint address="https:url" binding="wsHttpBinding" bindingConfiguration="SampleServiceBindingHttps" contract="TestProject.Interfaces.ITest"></endpoint>
<endpoint contract="IMetadataExchange" binding="mexHttpsBinding" address="mex"></endpoint>
</service>
</services>
<bindings>
<wsHttpBinding>
<binding name="SampleServiceBinding">
<security mode="Message">
<message clientCredentialType="UserName"/>
</security>
</binding>
<binding name="SampleServiceBindingHttps">
<security mode="TransportWithMessageCredential">
<message clientCredentialType="UserName"/>
</security>
</binding>
</wsHttpBinding>
</bindings>
I changed the security mode to TransportWithMessageCredential mode and change few config like binding = "mexHttpsBinding"
I have had to change a wcf service I had running on console application to https due to an issue with "mixed content blocking" in firefox.
This is the config:
<services>
<service name="ServiceHost.Services.BiometricCaptureService" behaviorConfiguration="Default">
<endpoint address="rest" behaviorConfiguration="CorsBehavior" binding="webHttpBinding" bindingConfiguration="httpsBinding" contract="ServiceHost.IServices.IBiometricCaptureService"/>
<endpoint address="mex" binding="mexHttpsBinding" contract="IMetadataExchange" />
<host>
<baseAddresses>
<add baseAddress="https://localhost:8502/biometrics/biometricscaptureservice.svc"/>
</baseAddresses>
</host>
</service>
</services>
<behaviors>
<endpointBehaviors>
<behavior name="CorsBehavior">
<webHttp/>
<crossOriginResourceSharingBehavior/>
</behavior>
</endpointBehaviors>
<serviceBehaviors>
<behavior name="Default">
<serviceMetadata httpGetEnabled="false" httpsGetEnabled="true"/>
<serviceDebug includeExceptionDetailInFaults="true"/>
</behavior>
</serviceBehaviors>
</behaviors>
<extensions>
<behaviorExtensions>
<add name="crossOriginResourceSharingBehavior" type="ServiceHost.Utility.CORSBehaviorExtensionElement, ServiceHost, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null"/>
</behaviorExtensions>
</extensions>
<bindings>
<webHttpBinding>
<binding name="httpsBinding" maxReceivedMessageSize="2147483647">
<security mode="Transport">
<transport clientCredentialType="None" proxyCredentialType="None" realm="" />
</security>
<readerQuotas maxStringContentLength="2147483647" />
</binding>
</webHttpBinding>
</bindings>
<serviceHostingEnvironment aspNetCompatibilityEnabled="true"/>
Starting the service does not throw any errors with this configuration but I cannot hit on the endpoint any more.
The only error I could get was this: "Unable to read data from the transport connection: An existing connection was forcibly closed by the remote host."
Can anyone see any issues with this?
I don't see how your service will find the encryption certificate.
You should have something like this:
<behaviors>
<serviceBehaviors>
<behavior name="mySvcBehavior">
<serviceCredentials>
<serviceCertificate findValue="xxxxxx" x509FindType="FindByThumbprint" />
</serviceCredentials>
</behavior>
</serviceBehaviors>
</behaviors>
This is a pretty decent step-by-step guide to setting up HTTPS on a WCF site. http://robbincremers.me/2011/12/27/wcf-transport-security-and-client-certificate-authentication-with-self-signed-certificates/
wasnt sure quite what to name the question but the problem is as follows:
I am deploying a WCF service on IIS 6 which is to be consumed by an external source.
the box that it is on is externally hosted but has a DC so is effectively on my network ('mydomain'), internally it's called 'prod' say.
the service need to run over SSL so we got an SSL cert for the domain the service will respond to: service.oursite.com lets say
DNS has all filtered through and I can indeed hit the service on
https://service.oursite.com/service.svc
and it kicks out the little svcutil link .
the problem is that the address that the link points to is not
https://service.oursite.com/service.svc?wsdl as I would hope
it is instead
https://prod.mydomain.com/service.svc?wsdl
so of course the SSL bails as the cert is not for that
and if i click through to the wsdl all the schemaLocation links are wrong, again pointing to the internal rather than external name
question is:
why is it doing that?
and
how do i stop it doing that?
is it a matter of adding something in the config? (please say yes :))
any help as ever most gratefully received
if it helps here is the config
<services>
<service name="CBBookingService.CBBookingService" behaviorConfiguration="CBBookingService.CBBookingServiceBehavior">
<endpoint address="" binding="basicHttpBinding" bindingConfiguration="TransportSecurity" contract="CBBookingService.ICBBookingService" />
<endpoint address="mex" binding="mexHttpsBinding" contract="IMetadataExchange" />
</service>
</services>
<bindings>
<basicHttpBinding>
<binding name="BasicSecurity" maxReceivedMessageSize="2147483647">
<security mode="None" />
</binding>
<binding name="TransportSecurity" maxReceivedMessageSize="2147483647">
<!--https-->
<security mode="Transport">
<transport clientCredentialType="None" />
</security>
</binding>
</basicHttpBinding>
</bindings>
<behaviors>
<serviceBehaviors>
<behavior name="CBBookingService.CBBookingServiceBehavior">
<serviceMetadata httpGetEnabled="true" httpsGetEnabled="true" />
<serviceDebug includeExceptionDetailInFaults="false"/>
<dataContractSerializer maxItemsInObjectGraph="2147483647" />
</behavior>
</serviceBehaviors>
</behaviors>
You can use the <useRequestHeadersForMetadataAddress> service behavior, and you should get the behavior you want:
<behaviors>
<serviceBehaviors>
<behavior name="CBBookingService.CBBookingServiceBehavior">
<serviceMetadata httpGetEnabled="true" httpsGetEnabled="true" />
<serviceDebug includeExceptionDetailInFaults="false"/>
<dataContractSerializer maxItemsInObjectGraph="2147483647" />
<useRequestHeadersForMetadataAddress />
</behavior>
</serviceBehaviors>
</behaviors>
You can change it in your configuration.
<serviceMetadata httpGetEnabled="true"
externalMetadataLocation="https://service.oursite.com/service.svc?wsdl"/>
or use https://stackoverflow.com/a/14592767/2012977 for asp.net v4 or later.
thanks for the answers
unfortunately I am using .net 3.5 so the answers below do not work
I ended up doing this
<system.serviceModel>
<services>
<service name="CBBookingService.CBBookingService" behaviorConfiguration="CBBookingService.CBBookingServiceBehavior">
<endpoint address="https://service.oursite.com/CBBookingService.svc" binding="basicHttpBinding" bindingConfiguration="TransportSecurity" contract="CBBookingService.ICBBookingService" name="SSL" />
<endpoint address="mex" binding="mexHttpsBinding" contract="IMetadataExchange" />
</service>
</services>
<bindings>
<basicHttpBinding>
<binding name="BasicSecurity" maxReceivedMessageSize="2147483647">
<security mode="None" />
</binding>
<binding name="TransportSecurity" maxReceivedMessageSize="2147483647">
<!--https-->
<security mode="Transport">
<transport clientCredentialType="None" />
</security>
</binding>
</basicHttpBinding>
</bindings>
<behaviors>
<serviceBehaviors>
<behavior name="CBBookingService.CBBookingServiceBehavior">
<serviceMetadata httpsGetEnabled="true" httpsGetUrl="https://service.oursite.com/CBBookingService.svc/SSL" />
<serviceDebug includeExceptionDetailInFaults="false"/>
<dataContractSerializer maxItemsInObjectGraph="2147483647" />
</behavior>
</serviceBehaviors>
</behaviors>
<serviceHostingEnvironment aspNetCompatibilityEnabled="true">
</serviceHostingEnvironment>
</system.serviceModel>