Forms Authentication Cookie and WCF - asp.net

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...

Related

WCF request doesn't flow via asp.net pipeline

I have a WCF service hosted in an asp.net application.
Here's the service (shortened):
[AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Required)]
[ServiceContract(Name = Name, Namespace = Namespace)]
[ServiceBehavior(Name = Name, Namespace = Namespace)]
public class WcfMaintenanceFacade {...}
Here's hosting:
RouteTable.Routes.Add(new ServiceRoute("entity/maintenance/5.20", new ServiceHostFactory(), typeof(WcfMaintenanceFacade)));
And here's relevant config section:
<system.serviceModel>
<serviceHostingEnvironment aspNetCompatibilityEnabled="true"/>
</system.serviceModel>
My service instantiates, the requests are coming in, and event HttpContext.Current is not empty.
There are two (major, for me) issues that I can't solve:
HttpContext.Current.Session is empty
Global.asax's Application_BeginRequest is never called
And yes, from the call stack it seems like the request is going through WCF activation pipeline, not ASP.net pipeline. So what am I doing wrong?
About the session, you handle it with OperationContext.Current.RequestContext instead of HttpContext.Current.Session.
HttpContext: Current is always null when accessed from within a WCF
service. Use
T:System.ServiceModel.OperationContext.Current.RequestContext instead.
Read more here: https://msdn.microsoft.com/en-us/library/aa702682.aspx
Application_BeginRequest are used by ASP.Net applications, but WCF works different from common web applications, thus BeginRequest could not be hit on each request.
The ASP.NET HTTP runtime handles ASP.NET requests but does not
participate in the processing of requests destined for WCF services
.... he WCF Service Model intercepts messages addressed to WCF
services and routes them through the WCF transport/channel stack
So, your problem can be related to this issue. This information is also available at the same link.
Hope it helps with your questions.
And the answer is simple (and, well, obvious):
<system.webServer>
<modules runAllManagedModulesForAllRequests="true">
Yes. RAMMFAR.
For me it is clear that these two technologies are not supposed to be working in the same application, and that's why they have two different pipelines. Service by the nature is an isolated thing. Now you just try to find a workaround, relying on the fact they both work on same IIS.
I would recommend you rather start from the goals, from what you want to achieve. If you need new service-like functionality integrated into native ASP.NET application you can
1) use ASMX services (will give you SAOP if you need it) and/or page methods
2) try to integrate WEB API in case you need JSON service.

WCF AND ASP.NET session sharing

Here is my case, I am working on an infrastructure for a scale able application.
I am creating a simple ASP.NET client page that consumes a WCF service with an AJAX call (simple xmlhttp object not .net script manager).
I need the 2 to share sessions, so I have instructed the ASP.NET client application to store the session in SQL with the aspnet_regsql.exe tool.
I have checked that WCF service is receiving the same session ID that the ASP.NET client produces, but in the service the session keys container is empty.
I am under an impression that it might have something to do with the app name in the configuration, but I really don't know...
Any direction ?
If you must share ASP.NET session with WCF services, you need to check out WCF Services and ASP.NET on MSDN to find out how to enable the WCF ASP.NET compatibility mode.
Mostly, it boils down to:
<system.serviceModel>
<serviceHostingEnvironment aspNetCompatibilityEnabled="true" />
</system.serviceModel>
in your WCF service's service-side config. Also, you must make sure your WCF service implementation doesn't explicitly deny the ASP.NET compatibility mode.
So your WCF service class must either allow or even require the ASP.NET compatibility:
[AspNetCompatibilityRequirements(
RequirementsMode = AspNetCompatibilityRequirementsMode.Required)]
public class YourService : IYourService
or
[AspNetCompatibilityRequirements(
RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)]
public class YourService : IYourService
I have found the answer to my problem.
I needed to change the "TempGetAppID" procedure in the SQL ASPState DB created with the "aspnet_regsql.exe" tool to take the APP_NAME() and not the passed argument.
That made sure that all application now share the same session.
once I have made the change the WCF Service has started to be aware of sessions inserted in my asp.net application.
problem solved.
ALTER PROCEDURE [dbo].[TempGetAppID]
#appName tAppName,
#appId int OUTPUT
AS
SET #appName = APP_NAME()
SET #appId = NULL
SELECT #appId = AppId
FROM [ASPState].dbo.ASPStateTempApplications
WHERE AppName = #appName

Access Session in WCF service from WebHttpBinding

I'm using WCF service (via WebGet attribute).
I'm trying to access Session from WCF service, but HttpContext.Current is null
I added AspNetCompatibilityRequirements and edited web.config but I still cannot access session.
Is it possible to use WebGet and Session together?
Thank you!
Yes, it is possible. If you edit the web.config:
<system.serviceModel>
<serviceHostingEnvironment aspNetCompatibilityEnabled="true" />
</system.serviceModel>
and add the AspNetCompatiblityRequirements, the HttpContext.Current should be available.
Check everything once again, maybe you've put the attribute in the wrong place (the interface instead of the class?).
A RESTfull service with a session?
See excellent discussion here: Can you help me understand this? "Common REST Mistakes: Sessions are irrelevant"
http://javadialog.blogspot.co.uk/2009/06/common-rest-mistakes.html (point 6)
and
http://www.peej.co.uk/articles/no-sessions.html
Quote from Paul Prescod:
Sessions are irrelevant.
There should be no need for a client to "login" or "start a connection." HTTP authentication is done
automatically on every message. Client applications are consumers of
resources, not services. Therefore there is nothing to log in to!
Let's say that you are booking a flight on a REST web service. You
don't create a new "session" connection to the service. Rather you ask
the "itinerary creator object" to create you a new itinerary. You can
start filling in the blanks but then get some totally different
component elsewhere on the web to fill in some other blanks. There is
no session so there is no problem of migrating session state between
clients. There is also no issue of "session affinity" in the server
(though there are still load balancing issues to continue).

Can't get FormsAuthentication to properly work with WCF

I have both the wcf and asp.net project together in the same project. (I'm running on Azure, so this is more convenient).
I have this set in the web.config:
<system.serviceModel>
<serviceHostingEnvironment aspNetCompatibilityEnabled="true" />
</system.serviceModel>
My wcf service is decorated with:
[AspNetCompatibilityRequirements(
RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)]
With those attributes set, shouldn't the HttpContext.Current.User be automatically set for me when I run methods in my wcf service? Currently, HttpContext.Current.User is null and not being set for me automatically.
I thought if I used aspNetCompatibilityEnabled then the Application_AuthenticationRequest method would fire in the Global.asax when the wcf method is executed, but, it does not.
The .aspxauth cookie is getting correctly passed to the wcf service, and I'm able to manually decrypt the cookie and set the current user.
Suggestions of why this is not working the way I expect?
Are you getting the expected user identity in the
ServiceSecurityContext.Current.PrimaryIdentity
field which is available inside your server method's code?? It should be some form of an IIdentity descendant giving you the user info, if available.

Public WCF service requires authentication, despite no security being specified

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

Resources