Invoke soap wcf service in Fiddler like in Wcf test client - wcf

I have service which should support SOAP and REST.
web.config
<system.web>
<webServices>
<protocols>
<add name="HttpGet" />
<add name="HttpPost" />
</protocols>
</webServices>
<httpRuntime executionTimeout="90" maxRequestLength="1048576" useFullyQualifiedRedirectUrl="false" minFreeThreads="8" minLocalRequestFreeThreads="4" appRequestQueueLimit="100"/>
<compilation debug="true" targetFramework="4.0"/>
and contract
[OperationContract]
[WebInvoke(UriTemplate = "/GetData")]
List<FieldInfo> GetSerializedData();
When I invoke REST service in Fiddler Request builder I get result in JSON and XML clearly. But I can not find way to invoke soap endpoint,always get 404 error
Not Found
Not Found
HTTP Error 404. The requested resource is not found.
For me it is strange cause in WCF TEST Client return SOAP withou problem, so why Fiddler have problem. I invoke in Fiddler directly wcf service methods on bindings.

Related

Why won't Authorization Rules in IIS restrict access to my WCF service?

I have a standalone WCF service hosted in IIS 10. I would like to restrict access to the web service to a select group of users. I was able to do this for a web application by doing the following in IIS:
Authentication: Windows Authentication only (disabled Anonymous Authentication)
Authorization Rules: Allow a predefined group (i.e., Roles)
However, when I do the above steps for the web service, and changed clientCredentialType="Windows" in its web.config, it still allows any user from the domain to talk to it. Am I missing something obvious? Do web services function differently than web applications in terms of configuring authorization? Given my setup I would expect only users in the MyTestGroup to be able to talk with the web service, and all others getting 401 - Unauthorized.
As an aside, I tried setting up "Deny Everyone" rules but domain users could still talk to the web service, so I feel like the Authorization settings aren't being effectuated somehow. Looking for any insight on this.
Here are the relevant web.config contents:
<system.serviceModel>
<services>
<service name="StudyManagement.StudyManagement">
<endpoint address="" binding="basicHttpBinding" bindingConfiguration="secureHttpBinding" name="StudyManagement" contract="StudyManagement.IStudyManagement" />
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior>
<serviceMetadata httpGetEnabled="false" httpsGetEnabled="true" />
<serviceDebug includeExceptionDetailInFaults="true" />
</behavior>
</serviceBehaviors>
</behaviors>
<protocolMapping>
<add binding="basicHttpsBinding" scheme="https" />
</protocolMapping>
<bindings>
<basicHttpBinding>
<binding maxReceivedMessageSize="1048576" />
<binding name="secureHttpBinding">
<security mode="Transport">
<transport clientCredentialType="Windows" />
</security>
</binding>
</basicHttpBinding>
</bindings>
<serviceHostingEnvironment aspNetCompatibilityEnabled="false" minFreeMemoryPercentageToActivateService="0" />
</system.serviceModel>
<system.webServer>
<modules runAllManagedModulesForAllRequests="true" />
<directoryBrowse enabled="false" />
<security>
<authorization>
<remove users="*" roles="" verbs="" />
<add accessType="Allow" users="" roles="MyAllowGroup" />
</authorization>
</security>
</system.webServer>
You can refer to this website to re-create the authorization rules. In addition, the authorization of wcf services can use ServiceAuthenticationmanager, examples and tutorials.
The following Microsoft documentation helped to answer my question:
WCF services and ASP.NET
Important takeaways:
The ASP.NET HTTP runtime handles ASP.NET requests but does not participate in the processing of requests destined for WCF services, even though these services are hosted in the same AppDomain as is the ASP.NET content. Instead, the WCF Service Model intercepts messages addressed to WCF services and routes them through the WCF transport/channel stack.
Within an AppDomain, features implemented by the HTTP runtime apply to ASP.NET content but not to WCF. Many HTTP-specific features of the ASP.NET application platform do not apply to WCF Services hosted inside of an AppDomain that contains ASP.NET content. Examples of these features include the following:
File-based authorization: The WCF security model does not allow for the access control list (ACL) applied to the .svc file of the service when deciding if a service request is authorized.
Configuration-based URL Authorization: Similarly, the WCF security model does not adhere to any URL-based authorization rules specified in System.Web’s configuration element. These settings are ignored for WCF requests if a service resides in a URL space secured by ASP.NET’s URL authorization rules.
Solution:
Use ASP.NET Compatibility Mode by configuring web.config:
<system.serviceModel>
<serviceHostingEnvironment aspNetCompatibilityEnabled="true" />
</system.serviceModel>
Unlike the default side-by-side configuration, where the WCF hosting infrastructure intercepts WCF messages and routes them out of the HTTP pipeline, WCF services running in ASP.NET Compatibility Mode participate fully in the ASP.NET HTTP request lifecycle. In compatibility mode, WCF services use the HTTP pipeline through an IHttpHandler implementation, similar to the way requests for ASPX pages and ASMX Web services are handled. As a result, WCF behaves identically to ASMX with respect to the following ASP.NET features:
File-based authorization: WCF services running in ASP.NET compatibility mode can be secure by attaching file system access control lists (ACLs) to the service’s .svc file.
Configurable URL authorization: ASP.NET’s URL authorization rules are enforced for WCF requests when the WCF service is running in ASP.NET Compatibility Mode.
I recommend reading the entire article for additional information. It's a short and helpful read.
Thanks to #Shiraz Bhaiji for the article reference on WCF Authorization using IIS and ACLs.

How to register a custom binding extension in code for a self hosted WCF service?

I need a suggestion to register my custom binding extension for my Silverlight duplex commnication (to use PollingDuplexHttpBinding) for my self hosted WCF service.
Below are the binding details, which I got from this msdn page.
<!-- Register the binding extension from the SDK. -->
<extensions>
<bindingExtensions>
<add name="pollingDuplexHttpBinding"
type="System.ServiceModel.Configuration.PollingDuplexHttpBindingCollectionElement,System.ServiceModel.PollingDuplex, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" />
</bindingExtensions>
</extensions>
I need add the above xml code through the codebehind into my custom binding.

Can't define the endpoint after creating my WCF

I wanna learn WCF so I decided to try out creating some application that uses it. Well what I have in mind is I have 2 databases and I wanna create also an SSIS custom data source extension that calls the web service and passes the data (from one database) to an SSIS ADO.Net Data source (into the second database).
Now I created the 2 databases using SQL Server with one table in each. Then I Added a Connection in Visual Studio and then specified the server instance. (didn't create any .mdf files). I added this connectionString in the Web.Config file
<connectionStrings>
<add name="dbconnection" connectionString="
Data Source = SARE-VAIO;
Integrated Security = true;
Initial Catalog = Database1"/>
</connectionStrings>
When I wrote my service which basically populates Database1 with data, I wanted to define the endpoints but when I clicked on the "Edit WCF Configuration" it says 'No Service' is defined? What possibly am I doing wrong here? I want to create an error free service to be able to use it as a source in the SSIS package.
PS. My service has a basicHttpsBinding
UPDATE: I'm using VS 2012 with .Net Framework 4.5
UPDATE 2:
I skipped the endpoint definition for now and went ahead with testing and deploying my WCF. When I invoke the service it says the following error
Failed to invoke the service. Possible causes: The service is offline or inaccessible;
the client-side configuration does not match the proxy; the existing proxy is invalid.
Refer to the stack trace for more detail. You can try to recover by starting a new proxy,
restoring to default configuration, or refreshing the service.
Here is my web.config file
<?xml version="1.0"?>
<configuration>
<connectionStrings>
<add name="dbconnection" connectionString="Data Source = SARE-VAIO; Integrated Security = true; Initial Catalog = Database1"/>
</connectionStrings>
<appSettings>
<add key="aspnet:UseTaskFriendlySynchronizationContext" value="true" />
</appSettings>
<system.web>
<compilation debug="false" targetFramework="4.5" />
<httpRuntime targetFramework="4.5"/>
</system.web>
<system.serviceModel>
<behaviors>
<serviceBehaviors>
<behavior>
<!-- To avoid disclosing metadata information, set the values below to false before deployment -->
<serviceMetadata httpGetEnabled="true" httpsGetEnabled="true"/>
<!-- To receive exception details in faults for debugging purposes, set the value below to true. Set to false before deployment to avoid disclosing exception information -->
<serviceDebug includeExceptionDetailInFaults="false"/>
</behavior>
</serviceBehaviors>
</behaviors>
<protocolMapping>
<add binding="basicHttpsBinding" scheme="https" />
</protocolMapping>
<serviceHostingEnvironment aspNetCompatibilityEnabled="true" multipleSiteBindingsEnabled="true" />
</system.serviceModel>
<system.webServer>
<modules runAllManagedModulesForAllRequests="true"/>
<directoryBrowse enabled="true"/>
</system.webServer>
</configuration>
To answer your questions
(1) Why WCF configuration editor shows 'No service is defined' error : Your web.config does not have any services and endpoints defined explicitly (Note: When you host this in IIS you will still get some endpoints added due to the defaults endpoint feature. But config editor tool shows only explicitly defined endpoints). That's the reason the config editor tool shows this message. But you can use the tool to add services and endpoints.
(2) After deploying the service see if the service successfully activated. You can do this by browsing to the metadata URL (your config has metadata enabled). Make sure your service WSDL help page and WSDL shows up fine. If not fix that issue first.
(3) If you are looking a default https endpoint after hosting it in IIS, make sure your IIS has https binding configured with an SSL certificate.
Hope this helps!
Thanks!

WCF Authentication Service Proxy - CookieContainer not available

I have enabled the ASP.Net authentication service, as recommended by msdn. I am then attempting to use the service via a console app or winforms app (by adding a service reference to my local WCF service). I am doing custom authentication and transport security (so I am handling the AuthenticationService.Authenticating event in my Global.asax which works fine).
The authentication itself works fine, but the proxy created by adding the Service Reference does not include the CookieContainer property. This is obviously a problem when I try to pass the cookie token to subsequent services which require authentication.
Also, in the following client code, the IsLoggedIn() returns false, I'm guessing this is related to no cookie container being present.
ServiceReference1.AuthenticationServiceClient client =
new ServiceReference1.AuthenticationServiceClient();
bool isLoggedIn = client.Login("test", "test", "", true); //returns TRUE
bool check = client.IsLoggedIn(); //returns FALSE
Here is my web.config on the service:
<configuration>
<system.web>
<compilation debug="true" targetFramework="4.0" />
</system.web>
<system.web.extensions>
<scripting>
<webServices>
<authenticationService enabled="true"
requireSSL = "false"/>
</webServices>
</scripting>
</system.web.extensions>
<system.serviceModel>
<services>
<service name="System.Web.ApplicationServices.AuthenticationService"
behaviorConfiguration="AuthenticationServiceTypeBehaviors">
<endpoint contract="System.Web.ApplicationServices.AuthenticationService"
binding="basicHttpBinding"
bindingConfiguration="userHttps"
bindingNamespace="http://asp.net/ApplicationServices/v200"/>
</service>
</services>
<bindings>
<basicHttpBinding>
<binding name="userHttps" allowCookies="true">
<!--<security mode="Transport" />-->
</binding>
</basicHttpBinding>
</bindings>
<behaviors>
<serviceBehaviors>
<behavior name="AuthenticationServiceTypeBehaviors">
<serviceMetadata httpGetEnabled="true"/>
</behavior>
</serviceBehaviors>
</behaviors>
<serviceHostingEnvironment aspNetCompatibilityEnabled="true"/>
</system.serviceModel>
</configuration>
EDIT: Something else I should add, I did a Fiddler session of the service calling the Login method, and the cookie is being set and sent back to the client. But what am I supposed to do with no CookieContainer?
When this option is enabled the client will make sure all cookies received from a given web
service are stored and properly sent on each subsequent request in a transparent fashion.
But there is a catch: the cookie is only handled in the conversation with one web service.
What if you need to send the same cookies to different web services?
If you need to send the same cookies to multiple services, read this article: http://megakemp.wordpress.com/2009/02/06/managing-shared-cookies-in-wcf/
You need to configure the binding to allow cookies.
<system.ServiceModel>
<bindings>
<basicHttpBinding allowCookies="true">
</bindings>
Apparently, when adding a Service Reference (.Net 3.5+) to a WCF service on a client, the proxy class derives from System.ServiceModel.ClientBase. This class does not have a CookieContainer property (because the ClientBase supports non-HTTP protocols that have no concept of cookies).
http://netpl.blogspot.com/2011/11/managing-cookies-in-wcf-client.html
I could add a Web Reference instead, which would use the .Net 2.0 proxy class (and has CookieContainer property exposed) http://msdn.microsoft.com/en-us/library/bb628649.aspx. But I will most likely revisit my approach entirely and use custom headers and service behaviors to accomplish my goal.
Another option is to access the cookie container for the underlying channel like this:
var cookieManager = client.InnerChannel.GetProperty<IHttpCookieContainerManager>();
cookieManager.CookieContainer.Add(new Cookie(....));
For the above manager to be present, you need to set AllowCookies to true, e.g.:
<system.ServiceModel>
<bindings>
<basicHttpBinding allowCookies="true">
</bindings>

Webservice does not seem to be doing any authentication despite config in IIS7.5

The Problem
I have a WCF webservice that I am hosting as a webservice in IIS7.5. I want this service to only be accessible by two groups. The webservice is running successfully, although there does not seem to be any authentication being done.
I was under the impression ( having read gobs of MSDN pages attesting to this) that all one really had to do was enable Windows Authentication on the Application site, disable Anonymous Authentication, set the mode to windows in the web.config and add Allow/Deny rules to the authorization section as diaplayed below:
<system.web>
<authentication mode="Windows" />
<compilation debug="false" strict="false" explicit="true" targetFramework="4.0" />
<pages /> <!-- Omitted -->
<authorization>
<allow roles="Managers" />
<allow roles="Operations" />
<deny users="*" />
<deny users="?" />
</authorization>
</system.web>
With the above steps and web.config changes done, and after going to the Authorization page in IIS and reloading the Auth rules, calling the service through the WCFTestclient shows it working flawlessly. Except I am not part of either of those two groups...
The Questions
It looks like it is just letting anyone in. My questions are these:
Is there a way to see passed and failed authentication checks on the webservice? (If so, I can see if any kind of authentication is going on).
Does the above look correct? It seems a bit simple, but given the Microsoft Method, it is not far fetched that something so standard would be fairly simple to set up.
Bottom-line
I have a service with the above web.config file, and an IIS7.5 instance with Windows Authentication installed and enabled. Anonymous Authentication is disabled. Auth rules are defined for two groups to have access, and all others to be denied and yet despite the fact that I am in those groups, I can access the service.
EDIT:
So I appear to have authentication working. If I only have the Allow All Users rule in place, I have access to the webservice. If I enact a Deny All Users rule, I no longer have access. However, if I add my account ("domain\MyAccount" as an allow (regardless of position in the web.config) I still don't have access.
What I have changed to get here,
Added the following to the service definition:
<AspNetCompatibilityRequirements(RequirementsMode:=AspNetCompatibilityRequirementsMode.Required)> _
Added the following to the web.config:
<system.web>
<authentication mode="Windows"/>
<authorization>
<deny users="*"/>
<allow users="sierra\cblissittekeps"/>
</authorization>
</system.web>
and
<system.servicemodel>
<bindings>
<basicHttpBinding>
<binding name="ADServiceBinding">
<security mode="TransportCredentialOnly">
<transport clientCredentialType="Windows"/>
</security>
</binding>
</basicHttpBinding>
</bindings>
<system.servicemodel>
Alright! So apparently the steps I took in the original post are not in fact enough. You have to add that aspnetcompatabilityrequirements attribute to the service class (which implements your service iterface), you have to add to the serviceHostingEnvironment tag an aspNetCompatibility attribute:
<serviceHostingEnvironment multipleSiteBindingsEnabled="true"
aspNetCompatibilityEnabled="true" />
And, something that no-one seems to mention, the order of your Allow/Deny rules makes a difference. Adding an allow AFTER a Deny All Users means that all users are still denied. Putting it before means that all users are denied except the ones in the allow.