Enable HTTPS on WCF rest webservice
I've already tried multiple configuration but i'm not able to get my WCF rest webservice working via HTTPS. I get 500 internal errors, or 400 bad request.
I've added a new website into IIS, binded to port 80 and 443. Then, enabled http/https protocols.
Here's my Web.config:
<?xml version="1.0"?>
<configuration>
<system.serviceModel>
<services>
<service name="RestService.MyService">
<endpoint address="https://mywebsite.com"
binding="webHttpBinding" contract="RestService.IMyService" />
</service>
</services>
<behaviors>
<endpointBehaviors>
<behavior>
<webHttp/>
</behavior>
</endpointBehaviors>
</behaviors>
</system.serviceModel>
<startup>
<supportedRuntime version="v4.5" sku=".NETFramework,Version=v4.5.1"/>
</startup>
<system.diagnostics>
<sources>
<source name="System.ServiceModel" switchValue="Information,ActivityTracing"
propagateActivity="true">
<listeners>
<add name="xml" />
</listeners>
</source>
<source name="System.ServiceModel.MessageLogging">
<listeners>
<add name="xml" />
</listeners>
</source>
</sources>
<sharedListeners>
<add initializeData="C:\logs\TracingAndLogging-service.svclog" type="System.Diagnostics.XmlWriterTraceListener"
name="xml" />
</sharedListeners>
<trace autoflush="true" />
</system.diagnostics>
</configuration>
Try to add the following binding configuration to the endpoint.
<services>
<service name="WcfServiceFile.Service1">
<endpoint address="" binding="webHttpBinding" contract="WcfServiceFile.IService1" behaviorConfiguration="beh" bindingConfiguration="myBinding">
</endpoint>
</service>
</services>
<bindings>
<webHttpBinding >
<binding name="myBinding" >
<security mode="Transport">
<transport clientCredentialType="None"></transport>
</security>
</binding>
</webHttpBinding>
Don’t forget to apply the bindingconfiguration to the endpoint so that it could take effect.
Result.
Due to the Self-signed certificate, the connection is not secure.
Feel free to contact me if the problem still exists.
Related
I'm new to WCF. I created WCF method that returns file. I deployed it to azure App Service and it worked when i called it like this
https://myapp.azurewebsites.net/myService.svc/MyMethod?MyParam=MyValue
Than i turned on Azure active directory authentication for azure App Service and now i get 404 error. But authentication against AAD works - i get redirected to login page if i'm not singed in user.
I tried searching SO and google and i can't figure out what i'm doing wrong or if it is just not possible to set up this way with WCF.
Web config:
<?xml version="1.0"?>
<configuration>
<appSettings>
<add key="aspnet:UseTaskFriendlySynchronizationContext" value="true"/>
</appSettings>
<system.web>
<customErrors mode="Off"/>
<compilation targetFramework="4.5.2"/>
<httpRuntime targetFramework="4.5.2"/>
<httpModules>
<add name="ApplicationInsightsWebTracking" type="Microsoft.ApplicationInsights.Web.ApplicationInsightsHttpModule, Microsoft.AI.Web"/>
</httpModules>
</system.web>
<system.serviceModel>
<serviceHostingEnvironment multipleSiteBindingsEnabled="true" />
<bindings>
<webHttpBinding>
<binding name="ServiceWebBindingName" transferMode="Streamed" maxReceivedMessageSize="2147483647" >
<readerQuotas maxArrayLength="2147483647" maxStringContentLength="2147483647" />
</binding>
</webHttpBinding>
</bindings>
<behaviors>
<endpointBehaviors>
<behavior name="DefaultRestServiceBehavior">
<webHttp defaultOutgoingResponseFormat="Json" defaultBodyStyle="Wrapped" automaticFormatSelectionEnabled="false"/>
</behavior>
</endpointBehaviors>
<serviceBehaviors>
<behavior name="">
<serviceMetadata httpGetEnabled="true" />
<serviceDebug includeExceptionDetailInFaults="true" />
</behavior>
</serviceBehaviors>
</behaviors>
<services>
<service name="My.App.Service">
<endpoint address="myService.svc"
binding="webHttpBinding"
bindingConfiguration="ServiceWebBindingName"
behaviorConfiguration="DefaultRestServiceBehavior"
name="FileManagerServiceEndpoint"
contract="My.App.IService"/>
</service>
</services>
</system.serviceModel>
<system.webServer>
<modules runAllManagedModulesForAllRequests="true">
<remove name="ApplicationInsightsWebTracking"/>
<add name="ApplicationInsightsWebTracking" type="Microsoft.ApplicationInsights.Web.ApplicationInsightsHttpModule, Microsoft.AI.Web"
preCondition="managedHandler"/>
</modules>
<!--
To browse web app root directory during debugging, set the value below to true.
Set to false before deployment to avoid disclosing web app folder information.
-->
<directoryBrowse enabled="false"/>
<validation validateIntegratedModeConfiguration="false"/>
</system.webServer>
</configuration>
So i found out i did not notice, that my original service url was
http://myapp.azurewebsites.net/myService.svc/MyMethod?MyParam=MyValue
and one that i was redirected to after adding azure ad authentication was
https://myapp.azurewebsites.net/myService.svc/MyMethod?MyParam=MyValue
So redirect points to HTTPS and not HTTP.
It is probably possible to set azure ad application not enforce HTTPS traffic, however in spirit of security and to avoid possible IE zone switching issues I added HTTPS transport to my WCF binding in web.config. Here is great example how to do it How to enable HTTPS on WCF RESTful Service? and it now works flawlessly.
I am trying to convert a WCF service from http to https.
It is using a self-signed certificate.
I can browse to the service using web browser, but when I try to add it as a web reference in another .Net app, I get the following error:
There was an error downloading https://localhost:40300/DBService/SPService.svc/_vti_bin/ListData.svc/$metadata.
The request failed with HTTP status 403: Forbidden.
I have tried editing the web.config in various ways according to lots of Googling, but still have the above error with no way to narrow down the cause...
Here is my web.config:
<?xml version="1.0"?>
<configuration>
<appSettings>
<add key="DatabaseServer" value="Server2008"/>
<add key="Database" value="Licensor"/>
<add key="VerboseLogging" value="True"/>
</appSettings>
<system.web>
<compilation targetFramework="4.0"/>
<httpRuntime/>
</system.web>
<system.serviceModel>
<services>
<service name="DBService.SPService">
<endpoint address="https://localhost/DBService/SPService.svc"
binding="basicHttpBinding"
bindingConfiguration="secureHttpBinding"
contract="DBService.IService1"/>
<endpoint address="mex"
binding="mexHttpsBinding"
contract="IMetadataExchange" />
</service>
</services>
<bindings>
<basicHttpBinding>
<binding name="secureHttpBinding">
<security mode="Transport">
<transport clientCredentialType="None"/>
</security>
</binding>
</basicHttpBinding>
</bindings>
<behaviors>
<serviceBehaviors>
<behavior>
<serviceMetadata httpGetEnabled="true" httpsGetEnabled="true"/>
<serviceDebug includeExceptionDetailInFaults="true"/>
</behavior>
</serviceBehaviors>
</behaviors>
<!--<protocolMapping>
<add binding="basicHttpsBinding" scheme="https"/>
</protocolMapping>-->
<serviceHostingEnvironment aspNetCompatibilityEnabled="false" multipleSiteBindingsEnabled="true"/>
</system.serviceModel>
<system.webServer>
<modules runAllManagedModulesForAllRequests="true"/>
<directoryBrowse enabled="true"/>
</system.webServer>
</configuration>
Can anyone help to find the cause, or even better point me towards a working sample of WCF over SSL using basicHttpBinding?
I have spent quite a few hours trying to resolve this so will appreciate your time on this one. If you need to I can provide access to my machine.
I am trying to add a WCF service reference to my web application using VS2010. It seems to add OK, but the web.config is not updated, meaning I get a runtime exception:
Could not find default endpoint
element that references contract
'CoolService.CoolService' in the
ServiceModel client configuration
section. This might be because no
configuration file was found for your
application, or because no endpoint
element matching this contract could
be found in the client element.
Obviously, because the service is not defined in my web.config. Steps to reproduce:
Right click solution > Add > New Project > ASP.NET Empty Web Application.
Right click Service References in the new web app > Add Service Reference.
Enter address of my service and click Go. My service is visible in the left-hand Services section, and I can see all its operations.
Type a namespace for my service.
Click OK. The service reference is generated correctly, and I can open the Reference.cs file, and it all looks OK.
Open the web.config file. It is still empty!
<system.web>
<compilation debug="true" targetFramework="4.0" />
</system.web>
<system.serviceModel>
<bindings />
<client />
</system.serviceModel>
Why is this happening? It also happens with a console application, or any other project type I try. Any help?
Here is the app.config from my WCF service:
<?xml version="1.0"?>
<configuration>
<system.web>
<compilation debug="true" />
</system.web>
<!-- When deploying the service library project, the content of the config file must be added to the host's
app.config file. System.Configuration does not support config files for libraries. -->
<system.serviceModel>
<services>
<service name="CoolSQL.Server.WCF.CoolService">
<endpoint address=""
binding="webHttpBinding"
contract="CoolSQL.Server.WCF.CoolService"
behaviorConfiguration="SilverlightFaultBehavior">
<identity>
<dns value="localhost" />
</identity>
</endpoint>
<endpoint address="mex"
binding="mexHttpBinding"
contract="IMetadataExchange" />
<host>
<baseAddresses>
<add baseAddress="http://localhost:8732/Design_Time_Addresses/CoolSQL.Server.WCF/CoolService/" />
</baseAddresses>
</host>
</service>
</services>
<behaviors>
<endpointBehaviors>
<behavior name="webBehavior">
<webHttp />
</behavior>
<behavior name="SilverlightFaultBehavior">
<silverlightFaults />
</behavior>
</endpointBehaviors>
<serviceBehaviors>
<behavior name="">
<serviceMetadata httpGetEnabled="true" />
<serviceDebug includeExceptionDetailInFaults="true" />
</behavior>
</serviceBehaviors>
</behaviors>
<bindings>
<webHttpBinding>
<binding name="DefaultBinding"
bypassProxyOnLocal="true"
useDefaultWebProxy="false"
hostNameComparisonMode="WeakWildcard"
sendTimeout="00:05:00"
openTimeout="00:05:00"
receiveTimeout="00:00:10"
maxReceivedMessageSize="2147483647"
transferMode="Streamed">
<readerQuotas maxArrayLength="2147483647"
maxStringContentLength="2147483647" />
</binding>
</webHttpBinding>
</bindings>
<extensions>
<behaviorExtensions>
<add name="silverlightFaults"
type="CoolSQL.Server.WCF.SilverlightFaultBehavior, CoolSQL.Server.WCF" />
</behaviorExtensions>
</extensions>
<diagnostics>
<messageLogging logEntireMessage="true"
logMalformedMessages="false"
logMessagesAtServiceLevel="true"
logMessagesAtTransportLevel="false"
maxMessagesToLog="3000"
maxSizeOfMessageToLog="2000" />
</diagnostics>
</system.serviceModel>
<startup>
<supportedRuntime version="v4.0"
sku=".NETFramework,Version=v4.0" />
</startup>
<system.diagnostics>
<sources>
<source name="System.ServiceModel.MessageLogging"
switchValue="Information, ActivityTracing">
<listeners>
<add name="messages"
type="System.Diagnostics.XmlWriterTraceListener"
initializeData="c:\messages.e2e" />
</listeners>
</source>
</sources>
</system.diagnostics>
</configuration>
I discovered how to work around this. My WCF service was implemented in its own project, and hosted in by a separate console application in the same solution. If I run the WCF service as the solution's startup project (eg. let VS host it for me) then adding the reference works fine and the correct lines are added to the client web.config. But if I host service from within my console application, while I can still add the reference, the client's web.config does not get modified. So, a workaround is to first let VS host the service, then add the reference, then change the service to be hosted (at the same address and port) in the console application.
This is surprising behaviour, and I am curious if anyone can shed any light on it?
I've got a wcf "self-hosted" service up and running and when communicating across machines i get The remote server returned an unexpected response: (405) Method not allowed. message.
This only seems to happen when running the WCF test client connecting to a remote machine. When running on the server, everything communicates fine.
i'm thinking it has something to do with security, but i'm not sure where to look.
Can anyone point out what i'm missing or doing wrong?
below is my server config file
<system.serviceModel>
<protocolMapping>
<remove scheme="http" />
<add scheme="http" binding="customBinding" bindingConfiguration="gzipCompression" />
</protocolMapping>
<bindings>
<customBinding>
<binding name="gzipCompression">
<gzipMessageEncoding />
<httpTransport maxReceivedMessageSize="2147483647" />
</binding>
</customBinding>
</bindings>
<extensions>
<bindingElementExtensions>
<add name="gzipMessageEncoding" type="Compression.GZIP.GZipMessageEncodingElement, Compression, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" />
</bindingElementExtensions>
</extensions>
<behaviors>
<!--<serviceBehaviors>
<behavior name="CadServiceBehavior">
<serviceMetadata httpGetEnabled="true" httpsGetEnabled="false"
httpGetBinding="" />
<serviceDebug includeExceptionDetailInFaults="true" />
</behavior>
</serviceBehaviors>-->
</behaviors>
<services>
<service behaviorConfiguration="CadServiceBehavior" name="CadServiceLibrary.CadServiceContract">
<endpoint address="com" binding="customBinding" bindingConfiguration="gzipCompression"
name="com" contract="CadServiceLibrary.CadServiceContract" />
<endpoint address="mex" binding="mexHttpBinding" bindingConfiguration=""
name="mex" contract="IMetadataExchange" />
<endpoint binding="wsHttpBinding" bindingConfiguration="" name="ws"
contract="CadServiceLibrary.CadServiceContract" />
<host>
<baseAddresses>
<add baseAddress="http://localhost/CadServices" />
<add baseAddress="https://localhost:450/CadServices" />
</baseAddresses>
</host>
</service>
</services>
</system.serviceModel>
I have seen this before although not sure if it is your problem:
Instead of localhost, put your server's name or IP address. If IP address, make sure the same IP address is selected in IIS (I assume you are hosting this in IIS).
When localhost is used, I have had difficulty in the past accessing it from remote machines - although listening on localhost works fine with TCP.
Trying to get the simple Hello World (via SSL) working but receiving a following error: The remote certificate is invalid according to the validation procedure.
The server App.config is:
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<system.serviceModel>
<behaviors>
<serviceBehaviors>
<behavior name="mexBehavior">
<serviceMetadata httpGetEnabled="true" />
</behavior>
</serviceBehaviors>
</behaviors>
<bindings>
<wsHttpBinding>
<binding name="SSLSecurity">
<security mode="Transport">
<transport clientCredentialType="None" />
</security>
</binding>
</wsHttpBinding>
</bindings>
<services>
<service behaviorConfiguration="mexBehavior" name="HelloServiceLibrary.HelloService">
<clear />
<endpoint address="ws" binding="wsHttpBinding" name="wsEndpoint"
contract="HelloServiceLibrary.IHelloService">
<identity>
<dns value="localhost" />
</identity>
</endpoint>
<endpoint address="https://localhost:443/hellossl" binding="wsHttpBinding" name="wssslEndpoint"
bindingConfiguration="SSLSecurity" contract="HelloServiceLibrary.IHelloService">
<identity>
<certificateReference x509FindType="FindByThumbprint" findValue="82a39faaeb18bf9585b334ca83264add3d5b26ee" />
<dns value="localhost" />
</identity>
</endpoint>
<endpoint address="mex" binding="mexHttpBinding" name="mexEndpoint"
contract="IMetadataExchange">
<identity>
<dns value="localhost" />
</identity>
</endpoint>
<host>
<baseAddresses>
<add baseAddress="http://localhost:8989/hello" />
</baseAddresses>
</host>
</service>
</services>
</system.serviceModel>
</configuration>
Please advice what am I doing wrong.
Update: the certificate is successfully deployed in Trusted Root Certification Authorities on local computer.
Add this to your WCF config and let me know the output.
<system.diagnostics>
<trace autoflush="true" />
<sources>
<source name="System.Net" maxdatasize="1024">
<listeners>
<add name="MyTraceFile"/>
</listeners>
</source>
<source name="System.Net.Sockets" maxdatasize="1024">
<listeners>
<add name="MyTraceFile"/>
</listeners>
</source>
</sources>
<sharedListeners>
<add
name="MyTraceFile"
type="System.Diagnostics.TextWriterTraceListener"
initializeData="System.Net.trace.log"
/>
</sharedListeners>
<switches>
<add name="System.Net" value="Verbose" />
<add name="System.Net.Sockets" value="Verbose" />
</switches>
</system.diagnostics>
This is a stab in the dark.
Check to make sure you installed it to all users.
Open up MMC
Add Snap In (Certificates)
- Check Computer Account (Next)
- Choose your computer
Done
Now reinstall the cert to "Trusted Root Certification Authorities" and it will be trusted for all users.
Not sure if this may help you but I looked back at how I had my app.config set for a simple secure service I wrote a few weeks ago where I was using certs. Here are a few considerations you may need to make to properly config your config for the service:
<bindings>
<wsHttpBinding>
...
<security>
<transport clientCredentialType="Certificate" />
</security>
</wsHttpBinding>
</bindings>
Now in my config I have an endpoint behavior defined which provides metadata to tell the service what the client will be using for a cert on its side:
<behaviors>
<endpointBehaviors>
<behavior name="ClientBehavior">
<clientCredentials>
<clientCertificate findValue="WcfClient" storeLocation="LocalMachine" storeName="My"
x509FindType="FindBySubjectName"/>
<serviceCertificate>
<authentication certificateValidationMode="PeerTrust" />
</serviceCertificate>
</clientCredentials>
</behavior>
</endpointBehaviors>
</behaviors>
If all you need is a secure link, i.e. encryption only, no client authentication, then you don't need to set any client credentials. This is all you should have to do:
1. configure IIS to use SSL
2. configure an HTTPS endpoint on your service
3. configure the client to use the above endpoint
That's it. If your certificate is invalid, you might have to do your custom certificate validation as described here: MSDN.
Good luck!