I have an ASP.NET web service that I can access via a windows program but now I want to secure the web service. I can secure the web service using forms authentication. How do you access the secured web service from a windows forms application?
3 Answers
Although this is not the right approach, tt is theoretically possible to use forms authentication in the manner you describe. This could be accomplished by either:
- Using a WebRequest to send your requests in raw form to the web service. This will involve inspecting the response, extracting the relevant forms-authentication fields, and sending a response back which logs the user in. This will generate a cookie which you must send along with each subsequent response to the service
- Generate the FormsAuhentication authentication cookie yourself. This is complex as it involves synchronising the machine key on the calling application, and artificially manipulating the headers being sent to the machine hosting the service.
- Display the forms-authentication form for the user to log in to at the beginning of a session requiring interaction with the web-service. You can then harvest the generated cookie and present it to the service in HTTP headers as in option (2).
As you can see, these methods are highly complex, and are fundamentally a hack to use forms-authentication where it was never intended.
Microsoft intended us to use either Windows authentication, or SSL certs to secure access to ASP.NET web services. See HTTP Security and ASP.NET Web Services on MSDN.
If you are able to use WCF, then a few more options present themselves, including the ability to build a custom authentication mechanism into the SOAP, with some support from WCF.
For the most part, securing web services is one of the trickiest parts of the job. Many live solutions which I have seen are compromises such as the ones above.
It seems the answer is no. Forms authentication is a cookie-based mechanism, and your WinForms app won't be able to hold and relay the cookies (without some serious workarounds, if at all).
A potential workaround that I wrote up when researching your question attempted to use a NetworkCredential
object, but that didn't work. Also tried was the ClientCredentials
in .NET 4.0.
var ss = new MySecureWebService.MyServiceSoapClient();
ss.ClientCredentials.UserName.UserName = "abc";
ss.ClientCredentials.UserName.Password = "123";
string asmxReturn = ss.HelloWorld(); //exception returned here
The console app was still presented with the login html page when calling the webmethod.
Other Suggestions
- If you have the source to your web service, extract its logic out into an assembly of its own. Reference that assembly in your WinForms app, and it's just as if you're calling the web service.
I understand that your goal is to reuse the app that's deployed, but the next best thing would be to use the same logic/implementation via .dll reference.