Empty HttpContext when calling WCF webservice - wcf

I recently wrote a webservice to be used with Silverlight which uses the ASP.net membership and roles.
To validate the client in the service I look at the HTTPContext.Current.User (Which works when the service is called from Silverlight)
However, I've been trying to call the same service from an asp.net postback. But when I step-thru to the service the HTTPContext.Current has an emplty string for the username.
I'm guessing there is something that I'm not doing in the web.config file which is causing the httpContext to not be sent through the proxy to my service?
Any ideas would be appreciated. I need to be able to validate the client somehow using asp.net membership and roles and have it work from both an asp.net client and a silverlight client.

I have solved it!
Looks like by default the Silverlight application was sending all the browsers cookies to the service. One of these cookies is the ".ASPXAUTH" cookie to authenticate against the membership and roles.
The asp.net application however was not sending the cookies to the service. To send the authorisation cookie I used the following code before calling my webservice method.
using (OperationContextScope scope = new OperationContextScope(ws.InnerChannel))
{
HttpRequestMessageProperty httpRequest = new HttpRequestMessageProperty();
OperationContext.Current.OutgoingMessageProperties.Add(HttpRequestMessageProperty.Name, httpRequest);
HttpCookieCollection cc = Page.Request.Cookies;
if (Request.Cookies[".ASPXAUTH"] != null)
{
HttpCookie aCookie = Request.Cookies[".ASPXAUTH"];
String authcookieValue = Server.HtmlEncode(aCookie.Value);
httpRequest.Headers.Add("Cookie: " + ".ASPXAUTH=" + authcookieValue);
}
// Webservice call goes here
}

Instead of HTTPContext try ServiceSecurityContext.Current.PrimaryIdentity

Not sure how it is working from Silverlight but not ASP.Net, but for starters here is a good blog post on how to setup WCF to work with ASP.Net membership providers. There are quite a few steps so this could be pretty easy to miss a setting.
Once you get that working correctly then I imagine both should work correctly.

I think it may be because my wcf service is in my silverlight.web project, and perhaps they are more friendly when it comes to sharing.
I may need to read up more on wcf and create a greater seperation of concerns by setting up a seperate webservice project?

Update:
Ok I've taken a look at the HTTP Post request using Fiddler
Looks like the Silverlight App is sending a 'State' with an authorization cookie and my asp.net app isn't.
Looks like I need to send the state + my authorization cookie when I call the service. I may need to formulate a new question soon...

Related

HttpRequestMessage with Windows Authentication

I'm trying to do some integration testing on an ASP.Net Core app with Windows Authentication enabled. For controller methods with the [Authorize] attribute I need to send through the current windows identity in the request.
There is lots of information on how to do this using the old HttpWebRequest method, but I can find no information on doing this through HttpRequestMessage. Presumably I have to encode and send through the current user in the authentication header? Can anyone help?
Asp.Net Core does not do impersonation for you. You need to call WindowsIdentity.Impersonate (https://msdn.microsoft.com/en-us/library/w070t6ka(v=vs.110).aspx) to apply the given identity to the current thread. Then you set up HttpClient with UseDefaultCredentials: How to get HttpClient to pass credentials along with the request?

Xamarin Android Auth0 WCF how to setup

I am trying to write an app with WCF as back end service and using Xamarin. I want to use token based authentication and i am evaluating https://auth0.com. I succeded in getting the token from auth0 in my Xamarin android app. Also looking at the tutorial I can setup the WCF web service. I am stuck at understanding how the whole thing works together? How do i use the Auth0 token received to communicate with my WCF service? Or rather how does the server know that it is the authenticated user from the token? How to use the token in my app when accessing the web service. Any one has similar arrangement before?
if you have done everything mentioned here to setup your behavior on your services then you should be able to add the token to the request header.
If you are using the webhttpbinding like they suggest then you should be able to intercept the message in a BeforeSendRequest
var header = new HttpRequestMessageProperty();
header.Headers.Add("Authorization", "Bearer " + this.token);
request.Properties.Add(HttpRequestMessageProperty.Name, header);
or if you are using WCF with soap and a wsHttpBinding or similar then you can
((HttpRequestMessageProperty)request.Properties[HttpRequestMessageProperty.Name]).Headers.Add("Authorization", "Bearer " + this.token);
Once the behavior is on your WCF service it will authenticate the token for every call made to a service that has that behavior attached to it. You can add a breakpoint in ValidateJsonWebToken.cs (which installed as part of the NuGet package from auth0) to see where it authenticates.

WCF Client, AllowCookies and clearing any current cookie?

I have a WPF client that is using WCF to call into a service hosted in IIS. My WCF client has AllowCookies='true' so that the forms authentication cookie that IIS is using is passed back and forth with each WCF call automatically. This all works just fine.
But I need the ability to clear out any forms authentication cookie my WCF client is caching so that my next request is not authenticated. Is there any way to do this?
On wcf client, you would have access to
HttpContext.Current.Request
Now this Request object contains cookies. You could loop over the cookie collection and remove the one you need.
foreach(var cookie in request.Cookies) { // }
An excellent article at code project which explains cookie management on WCF client
UPDATE
HttpContext is only available at server side, so my previous answer was incorrect as pointed by Phil.
The correct way to do it would be rather clumsy as you have get hold of HttpRequest itself
MyWebServiceClient client = new MyWebServiceClient();
using ( new OperationContextScope( client.InnerChannel ) )
{
HttpRequestMessageProperty request = new HttpRequestMessageProperty();
//get the instance of your AuthCookie and make it blank
request.Headers["AuthCookie"] = "";
OperationContext.Current.OutgoingMessageProperties[
HttpRequestMessageProperty.Name] = request;
client.InvokeSomeMethod();
}
Found this example here

WCF Authentication using basicHttpBinding and custom UserNamePasswordValidator

My first question is, is it even possible to use a custom UserNamePasswordValidor with basicHttpBinding?
I have a asp.net web site using Forms authentication and a custom membership provider. I realise that I could use the built in System.Web.ApplicationServices.AuthenticationService to authenticate my client (a WPF app) but I don't want two service calls (one for auth service, one for logic).
So it seems that a custom UserNamePasswordValidator would be perfect for the job. In my client I can then have:
var service = new MyServiceClient();
service.ClientCredentials.UserName.UserName = "username";
service.ClientCredentials.UserName.Password = "password";
MessageBox.Show(service.SayHello());
I've seen this working with wsHttpBinding but ideally would like to test without an SSL certificate.
Alternatively, is it possible to make use of the AuthenticationService from within another WCF service?
To clarify what I mean above regarding authentication service, I don't want to have 2 service calls i.e:
if (authService.Login("username", "password"))
// then call my service
I know this a minor thing but the external developer of the client app is expecting just one service that takes the credentials and returns the required data.
Thanks,
Ben
check ClearUserName binding: http://webservices20.blogspot.com/2008/11/introducing-wcf-clearusernamebinding.html It should solve your problem.
I use UserNamePasswordValidator over basicHttpBinding on a couple of my current projects. It works great; however, like Brett Robi mentioned in the comments, you need to have your Security mode set to Message or TransportWithMessageCredentials in order for the validator to be called. These security modes require SSL through.
So in short - Yes you can over basicHttpBinding; however, only with SSL. Removing the security mode and SSL removes the credential validations from being called.

Reading a cookie from a WCF RESTful webservice

Writing a suite of IIS hosted WCF webservices (both GET and POST), and I need to be able to read a cookie for an authentication token so I know the user has been auth'd previously.
Will HttpContext.Current.Cookies give me what I need or is there something cleaner and more appropriate for a WCF web service with WebGet and WebInvoke attributes?
string cookieHeader = WebOperationContext.Current.IncomingRequest.Headers[HttpRequestHeader.Cookie];
works for me