Public WCF service requires authentication, despite no security being specified - asp.net

I have published a WCF service (MyService.svc) on an ASP.NET site, in a sub-folder called WebServices.
When running on the local ASP.NET web server it works fine. When published to an IIS-run site and I try to access, for example, /WebServices/MyService.svc/jsdebug, I get 401 Unauthorized. The rest of the site works fine.
Does anyone have any idea why?
Here are the contents of MyService.svc:
<%#ServiceHost
Language="C#"
Debug="true"
Service="MyApp.Core.MyService, MyApp.Core"
Factory="System.ServiceModel.Activation.WebScriptServiceHostFactory"
%>
MyApp.Core.MyService is a class implementing IMyService (which has the attribute ServiceContract and method declarations with the attribute OperationContract).

By default, a WCF service will do Windows authentication unless configured otherwise. I think the following should do the trick:
<bindings>
<wsHttpBinding>
<binding name="wsHttp">
<security mode="None"/>
</binding>
</wsHttpBinding>
</bindings>
..and configure your endpoint to use this binding config.

There are 3 possible places where the call is getting blocked:
The IIS Settings, check that anonymous authentication is enabled
NTFS File access settings, check that the user that is the identity of the application pool has read access.
the web.config, check that authentication mode is None.
All of the above are before it gets to what could be blocking it in the WCF configuration. But from your comment to blowdart it looks like you have not configured WCF security.
Check also your IIS log for 401 errors. And check if this post is relevant.

And what does the web.config say? Do you have authentication there, either on the service itself, or the directory? Is transport security on or off? Message security?
The svc files do not configure security, that's part of the config file

Related

How to force soap header authentication for my scenario?

The problem is: I need to connect to a soap web service; generated by java code; using ASP.Net client via C# through MS Visual Studio 2013.
Try 1, The usual way:
I have added a web service reference using the wsdl and by assigning the credentials like:
Credentials.Username.Username = "test";
Credentials.Password.Password = "test";
When executing, the following exception is being encountered:
The login information is missing!
Try 2:
I have searched for similar problems like:
how-to-go-from-wsdl-soap-request-envelope-in-c-sharp
Dynamic-Proxy-Creation-Using-C-Emit
c# - Client to send SOAP request and received response
I had chosen to generate a proxy class using the wsdl tool, then added the
header attribute, but I have found the following note from Microsoft:
Note: If the Web service defines the member variables representing the SOAP headers of type SoapHeader or SoapUnknownHeader instead of a class deriving from SoapHeader, a proxy class will not have any information about that SOAP header.
Try 3:
I have tried to change the service model in the client web.config:
<bindings>
<basicHttpBinding>
<binding name="CallingCardServicePortBinding">
<security mode="TransportWithMessageCredential" >
<message clientCredentialType="UserName"/>
</security>
</binding>
</basicHttpBinding>
</bindings>
Then added the credentials like the first try, but the following error appears:
MustUnderstand headers:[{http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd}Security] are not understood
So, now I don't know what to do !
I have no control over the web service and I need to build a client that understands it.
Help Please!
The Soap Request template is the following:
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ser="...">
<soapenv:Header>
<credentials>
<userName>someUserName</userName>
<password>somePassword</password>
</credentials>
</soapenv:Header>
<soapenv:Body>
<ser:someRequest>
.......
.......
.......
</ser:someRequest>
If the destination web service uses authentication, then just ASMX won't do, since it is not aware of authentication, encryption etc. You have 2 options:
Use Microsoft WSE: http://www.microsoft.com/en-us/download/details.aspx?id=14089
this is nothing but an extension of ASMX which makes it Security/Encryption aware. (and some other features) technically, you'll be adding a reference to the WSE DLL and your Soap Proxy will extend from the WSE SOAP Client instead of the System one.
once you do that, the proxy class will have additional username/password properties that you can use to authenticate properly.
set the properties and see the outgoing request using fiddler. if the header is not what you want (because of namespaces etc.), then you can write a custom outgoing message inspector and modify the soap request nicely.
The other option (preferred) is to use WCF.
ASMX and WSE are older than WCF. WCF tries to bring all the web service nuances under one roof. if you get a WCF service reference, it (svcutil.exe) will automatically create the proxy class and the right bindings for you. (mostly custom)
once you do that, try setting the user name and password.
if that doesn't work, (i have frequently struggled to generate the right soap header for remote java based services that require username/password authentication), you can define a static header chunk in the web.config/app.config, that'll be sent as part of every request.
e.g.
<client>
<endpoint>
<headers>
<credentials>
<userName>someUserName</userName>
<password>somePassword</password>
</credentials>
</headers>
</endpoint>
</client>

Consume SOAP based web service with https

I'm integrating af ASP.NET application, which must consume a 3rd party SOAP web service, which can only be accessed by HTTPS. I add a service reference i VS2012 with the HTTPS URL and VS find the service just fine. But when I use the proxy that VS create to use the web service, it uses regular HTTP.
I suspect that I should alter the binding in the web.config, but I can't seem to figure out what to do. How do I set up the web service to use HTTPS?
You need to make sure that the binding the client uses has security mode="Transport" set up (and that the client binding matches the server binding), something like this for example:
<binding name="yourClientSecureBinding">
<security mode="Transport">
<transport clientCredentialType="None"/>
</security>
</binding>
and that the client indeed accesses the httpS:// address of the web service:
<client>
<endpoint bindingConfiguration="yourClientSecureBinding"
address="https://..."
... />
</client>
You are not providing any code, so for starters have a look at these posts: here (Microsoft developer network - Transport Security with an Anonymous Client) and here (Https with BasicHTTPBinding).

Forms Authentication Cookie and WCF

I have an asp.net 4.0 application (client) that makes ajax/json calls to a http facade that then passes on the calls to our wcf service layer.
Users must authenticate on the client using forms authentication. The idea then being that the authentication cookie will be passed to and be accessible at the http facade. [Design based on Dino Esposito's book - Microsoft ASP.NET and AJAX: Architecting Web Applications]
The problem is, that at the facade, HttpContext.Current.User.Identity.Name is an empty string and IsAuthenticated is false.
I have enabled compatibility by adding the following to my system.ServiceModel section in my web.config (http facade level):
<system.serviceModel>
<serviceHostingEnvironment aspNetCompatibilityEnabled="true" />
</system.serviceModel>
I have decorated my service with the following:
[AspNetCompatibilityRequirements(RequirementsMode =
AspNetCompatibilityRequirementsMode.Required)]
When I am debugging in the ajax/facade app I can see that cookies exist at HttpContext.Current.Request.Cookies. It appears that Anonymous is being used and not my authenticated user.
Both applications are running on the same IIS server.
Calls to the AJAX enabled wcf service are made via serviceProxy.js. Perhaps this method is not passing the necessary cookie?
WCF tracing is currently showing '..ASPXANONYMOUS=.....; ASP.NET_SessionId=....; .ASPXAUTH=.....' in the message log.
I get the feeling I am missing something simple but am too close to the problem.
Any suggestions welcomed.
I am not sure I completely understand the context of what you are trying to accomplish, but if these are two separate applications you are going to need to share machine keys in order to decrypt/encrypt the auth cookies in both.
in your web.config, make sure you have the following set:
<machineKey
validationKey="[generated key]"
validation="HMACSHA512"
decryptionKey="[generated key]"
decryption="AES"
/>
see how to generate these keys (and more info about them) on this codeproject article:
ASP.Net machineKey Generator - CodeProject
Let me know if this helps...

Making WCF service work

I'm using Visual Studio Express 2010, I've created WCF service called OperatorService.svc. Two files were added to my App_Code IOperatorService.cs and OperatorService.cs.
My web.config was updated with
<system.serviceModel>
<services>
<service name="OperatorService">
<endpoint address="https://ssl.mysite.com/WCF/OperatorService"
binding="ws2007HttpBinding"
bindingConfiguration="SecurityByTransport"
contract="IOperatorService" />
</service>
</services>
<bindings>
<basicHttpBinding>
<binding name="SecurityByTransport">
<security mode="Transport">
<transport clientCredentialType="None" />
</security>
</binding>
</basicHttpBinding>
</bindings>
</system.serviceModel>
Now when i'm trying to access this service online, get an error to create EndPoint but i can't figure our how to create EndPoint especially when WCF address is SSL HTTPS: enabled website.
Can someone help meh?
The endpoint address, if you are IIS hosting, should be either left empty or a relative address.
WCF services can have base addresses. A base address defines a core part of the address space that the service can listen on and endpoints are defined relative to that base address. If you leave the address empty then the endpoint listens on the base address.
When you are self hosting you can specify a base address in a couple of different ways: in the ServiceHost constructor or in the config file. However, if you are IIS hosting then the base address is already a given - it is the location of the .svc file
As far as HTTPS goes, if you say that you are using transport security then the base address will automatically map to HTTPS as long as that is enabled as a protocol in web application in IIS manager. However, if you are using the Visual Studio Web Development Server (aka Cassini) then that does not support SSL
Launch the WCF config tool (SvcConfigEditor.exe, it is a available in the menu of Visual Studio, otherwise the path should be C:\Program Files\Microsoft SDKs\Windows\v6.0\Bin) and open your config file, it is GUI tool to help you make a correct config.
The error in the config file is an incomplete endpoint element, you need to specify some attributes on the endpoint to make it work. The easiest way is to use the config tool, but of course it can be hand written. MSDN has a reference on the syntax.

ASP.NET, WCF: ASP.NET application consuming WCF service hosted in a local windows service

I have a WCF service running locally hosted by a windows service on machine A.
I have an ASP.NET application hosted in IIS on machine B.
My question is this, if I run the ASP.NET application via a browser on machine A, will it be able to consume the local WCF service?
As long as the address of the service used in the page points to machine A, you should be fine.
Yes, as long as your configuration is valid, it doesn't matter where on which server the service is used.
And yes - the client will all have to use the same config - you basically need to specify the "ABC's of WCF" - address, binding (and possibly binding configuration) and contract - the WHERE, HOW and WHAT of your service.
You can share a lot of the config - especially binding configurations - between server and client with this method: externalize certain parts of the config.
In your server, have something like:
<system.serviceModel>
<bindings configSource="bindings.config" />
</system.serviceModel>
and then in your bindings.config file, define:
<bindings>
<basicHttpBinding>
<binding name="BasicNoSecurity">
<security mode="None" />
</binding>
</basicHttpBinding>
</bindings>
That way, you can copy that file bindings.config to the clients, and reference it from the client's config file, too - sharing the same information and making sure it's the same and up to date on both ends of the communication.
This also works for any other of the subsections under <system.serviceModel> (like behaviors, extensions and so forth).

Resources