Sharing ASP.NET Session State With WCF Session - wcf

How can I share my asp.net session with wcf session .
Say I have a Session["UserId"] in my asp.net application . I want to access this inside the WCF Signature .
I enabled aspNetCompatibilityEnabled="true" in Webconfig & [ServiceContract(SessionMode=SessionMode.Required)] in WCF.
I don't want to pass this session as an argument .
How can I achieve this?

You can't share an ASP.NET Session with WCF instance since they are in different Application Domains and could well be on different machines.
Here's a good article on Instance Context Sharing which will get you some way with "persistence session" in WCF. Then it's a question of passing shared data over the wire (or by using a common resource/database etc)

If you add this under <serviceModel> in your Web.config, it will work.
<serviceHostingEnvironment aspNetCompatibilityEnabled="true" />
It probably decreases performance a bit.

Related

WCF - Is the services element mandatory

I think my question is rather simple, so I'll stick to the point:
Is it by any means possible to expose a service without specifying the services element and only the serviceHostingEnvironment element? I.e. would the below configuration be enough to host a WCF service? I'm asking because i've seen applications that - as far as I can tell - lack the services element, and I thought that was mandatory.
<serviceHostingEnvironment multipleSiteBindingsEnabled="true">
<serviceActivations>
<add relativeAddress="Service.svc" service="Namespace.To.My.Service" />
</serviceActivations>
</serviceHostingEnvironment>
With WCF 4.0 you don't need explicit service configuration as opposed to prior versions. It automatically adds default endpoints if no endpoints are defined explicitly.
Whatever configuration you mentioned in question is called File-less activation and you can activate service without even having physical .svc file. In WCF 4 you can define virtual service activation endpoints like one you have defined.
WCF detects what contracts are implemented by service and then method AddDefaultEndpoints adds one default endpoint per base address for each service contract implemented by the service. Note that this behavior is only when no explicit endpoints are added (either programmatically or through configuration). Should you add one explicit endpoint WCF stops adding default endpoints and it gives control to developer to customize it further.

how to use ASP.NET session in WCF?

how can I use ASP.NET session in WCF? or is there any alternative way to use "ASP.NET Session" like structure in WCF such as data storage?
Try having a look as ASPCompatibityMode with WCF and you then turn it on and share the session in the service method
You cannot use the ASP.NET session, since you can easily run a WCF service without having the ASP.NET engine fired up, eg. using a netTcpBinding.
There is however session handling native in WCF, where you can specify this on the service contract using the SessionMode parameter on the ServiceContract attribute.
See http://msdn.microsoft.com/en-us/library/ms733040.aspx for more details
In case anyone is still facing this issue (trying to use a SESSION variable in a .NET Web App consuming a WCF Service). Don't worry about the [AspNetCompatibilityRequirements .......] or adding aspNetCompatibilityEnabled="true" in the web.config.
After playing around with all that for a while I found out all I had to do was change each [WebMethod] within the _______.ASMX.CS to [WebMethod (EnableSession=true)].
So change [WebMethod] to [WebMethod (EnableSession=true)]. That's it.
I found out that from http://weblogs.asp.net/stevewellens/archive/2009/04/05/using-session-state-in-a-web-service.aspx
Thanks!
Bonsai

ASP.NET, SilverLight, WCF & Forms Authentication - How to configure endpoints?

I have this existing environment:
1) ASP.NET 3.5 web application
2) forms authentication with the SqlMembershipProvider
I need to add the following:
1) a Silverlight charting object embedded in a web page.
2) a WCF service to be consumed by:
a) the Silverlight component embedded in an authenticated
web page, as mentioned above
b) server-based WCF clients with certificate based authentication
My question is - what is the easiest/best way to configure the WCF endpoints for the Silverlight object to authenticate to the WCF service using the security context of the already logged-in user (via the page that’s hosting the Silverlight object) without having to use the user's username/password again?
I've researched a lot of the MSDN and Patterns & Practices material and I thought I had a decent grasp of many of the potential authentication scenarios. But I can't seem to figure out a way to tie them together for the scenario I've outlined. I've found other people posting similar questions to mine but none of the answers I've read seem to fully answer their questions either. (Maybe I'm making this harder than it needs to be?)
I would think that the solution would be to somehow use the authentication token/cookie generated in the asp.net form login and somehow pass that to the Silverlight object which then includes it in the WCF request. But I don't see how to configure the WCF endpoint to use that token.
(In some of my other projects I've implemented the server-to-server scenario in 2.b above using certificate-based authentication, so I'm not too worried about adding that to the current mix I've outlined.)
Thanks in advance for any insight or pointers to the path forward.
Terry
Thanks codemeit for trying to help but I finally figured out what I was doing wrong - it was pilot error.
In trying to configure the endpoints for my Silverlight app I was testing with an asp.net page. I finally realized that when I test that way, the client endpoint is no longer originating from the authenticated browser - the client endpoint is the IIS server which in turn executes the request against the WCF server endpoint. So the security context changes and HttpContext.Current.User.Identity is always empty at the WCF server endpoint.
Once I got my test SL app running in the browser, it automatically inherited the security context of the authenticated browser and then HttpContext.Current.User.Identity was correct and authenticated at the WCF server endpoint.
Have you tried to enable your WCF services with aspNet compatibility, then see if the following is true.
string currentUserName = HttpContext.Current.User.Identity.Name;
bool isLoggedIn = HttpContext.Current.User.Identity.IsAuthenticated;
if these properties are being populated with the expected values, then this is the one you are after.
To enable aspNet Compatibility
add to web.config
<serviceHostingEnvironment aspNetCompatibilityEnabled="true" />
add to the service impl class
[AspNetCompatibilityRequirements
(RequirementsMode=AspNetCompatibilityRequirementsMode.Required)]
In this case, the endpoint would be using basicHttpBinding, and you could check the authentication at run time within WCF.

Authenticate every call in WCF

I have a silverlight application that calls my wcf services so its a basichttpbinding. and we use forms authentication. I want to do a authentication check for every call that I receive except for the "AuthenticationService" (as this is the method which will do the basic authentication for login) so after user logs in and tries to call other services then I want this authentication check to be performed so that only authenticated users will be granted access to them. Is there is any best way to implement this... ???
After searching through various blogs, I came to know that we can use HttpContext.Current....IsAuthenticated property to check if user is authenticated or not. But my question is how secure and valid is HttpContext? Can we rely on that? or should we be using OperationContext? (and yes aspnetcompatability is set to true).
Please suggest!!
Thanks in advance
Sai
If you're hosting your WCF services in the ASP.NET runtime (i.e. <serviceHostingEnvironment aspNetCompatibilityEnabled="true" />) then you should absolutely be able to rely on ASP.NET's security system.
Check out this answer I gave to another question on how to leverage ASP.NET security for ASMX services. The same approach can be used to secure a WCF service as long as you're enabling ASP.NET as your service hosting environment.
Here are some articles that may help:
http://msdn.microsoft.com/en-us/library/dd560702(VS.95).aspx
http://silverlightuk.blogspot.com/2008/03/silverlight-wcf-and-aspnet.html
http://smehrozalam.wordpress.com/2009/01/07/securing-silverlight-application-and-wcf-service-using-aspnet-authentication-techniques/
Short answer is you can use the asp.net controls to do authorization, or use HttpContext.Current directly (as long as AspNetCompatMode is enabled).

How to get working path of a wcf application?

I want to get the working folder of a WCF application. How can I get it?
If I try
HttpContext.Current.Request.MapPath(HttpContext.Current.Request.ApplicationPath)
I get a null reference exception (the Http.Current object is null).
What I meant with the working folder was the folder where my WCF service is running. If I set aspNetCompatibilityEnabled="true", I get this error:
The server did not provide a meaningful reply; this might be caused by a contract mismatch, a premature session shutdown or an internal server error.
I needed the same information for my IIS6 hosted WCF application and I found that this worked for me:
string apPath = System.Web.Hosting.HostingEnvironment.ApplicationPhysicalPath;
As always, YMMV.
Please see ongle's answer below. It is much better than this one.
Updated after more information
The following worked for me. I tested it with a new WCF Service I hosted on IIS through a Service1.svc.
Add <serviceHostingEnvironment aspNetCompatibilityEnabled="true"/> to web config. <system.serviceModel>..</ ..> existed already.
Add AspNetCompatibilityRequirementsAttribute to the service with Mode Allowed.
Use HttpContext.Current.Server.MapPath("."); to get the root directory.
Below is the full code for the service class. I made no changes in the IService1 interface.
[AspNetCompatibilityRequirements(RequirementsMode=AspNetCompatibilityRequirementsMode.Allowed)]
public class Service1 : IService1
{
public void DoWork()
{
HttpContext.Current.Server.MapPath(".");
}
}
And below is an excerpt from the web.config.
<system.serviceModel>
<!-- Added only the one line below -->
<serviceHostingEnvironment aspNetCompatibilityEnabled="true"/>
<!-- Everything else was left intact -->
<behaviors>
<!-- ... -->
</behaviors>
<services>
<!-- ... -->
</services>
</system.serviceModel>
Old answer
What do you mean by the Working Folder? WCF services can be hosted in several different ways and with different endpoints so working folder is slightly ambiguous.
You can retrieve the normal "Working folder" with a call to Directory.GetCurrentDirectory().
HttpContext is an ASP.Net object. Even if WCF can be hosted on IIS, it's still not ASP.Net and for that reason most of the ASP.Net techniques do not work by default. OperationContext is the WCF's equivalent of HttpContext. The OperationContext contains information on the incoming request, outgoing response among other things.
Though the easiest way might be to run the service in ASP.Net compatibility mode by toggling it in the web.config. This should give you access to the ASP.Net HttpContext. It will limit you to the *HttpBindings and IIS hosting though. To toggle the compatibility mode, add the following to the web.config.
<system.serviceModel>
<serviceHostingEnvironment aspNetCompatibilityEnabled="true"/>
</system.serviceModel>
Depending on what you want. I usually want to resolve a url like "~/folder/file". This is what worked.
System.Web.Hosting.HostingEnvironment.MapPath("~/folder/file");
More general, I am using this one
AppDomain.CurrentDomain.BaseDirectory
The aspNetCompatibilityEnabled="true" should have resolved my problem, but I got this error:
The server did not provide a meaningful reply; this might be caused by a contract mismatch, a premature session shutdown or an internal server error.
I resolved my problem with getting the physical path of my running WCF service by getting it from my current app domain:
AppDomain.CurrentDomain.BaseDirectory
In order to reference ASP.NET features like the HttpContext object, you need to run your WCF app in ASP.NET compatibility mode. This article explains how to do this.
Use HostingEnvironment.ApplicationPhysicalPath in WCF to find your application physical path.
Use namespace
using System.Web.Hosting;