Authenticate every call in WCF - 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).

Related

ASP.NET Client Application Services Authentication and WCF

I have a WPF application that uses Client Application Services to allow authentication (username/password logon) against a related web application that uses Forms authentication and the SqlMembershipProvider/SqlProfileProvider/SqlRoleProvider. This all works and I can reliably validate a user/password combination.
The WPF application also calls a number of WCF services that are exposed by the same web application as is used for the CAS authentication. I now want to be able to pass through the authentication details (from Client Application Services) to the WCF services in order that I can identify the user that was authenticated within those services. I also need to be able to prevent the WCF services from being used if no authentication has taken place.
I have found a couple of .NET 3.5 examples where CAS authentication is used against .asmx web services, or authentication is provided against WCF Data Services which does not use ClientBase and has authentication facilities built in, but I cannot find any examples with pure WCF. Can anybody point me toward instruction that will enable this scenario? I am using .NET 4.0 for this project.
I have also found this stackoverflow question but again this is answered for .asmx web services and not for WCF.
The closest I have gotten involves the creation of an OperationContextScope and then copying the cookie header from the ClientFormsIdentity object to an HttpRequestMessageProperty and adding this to the OutgoingMessageProperties of the current OperationContext. I then call one or more methods of the service within the lifespan of the OperationContextScope. Thing is, when I then get to the WCF service, I still cannot see anything that resembles authentication in such a way as I can identify the original user. This methodology has been taken from various examples but I am obviously missing a step at the WCF end.
I think you need to switch to the Web API that Microsoft is now having people use for WCF Services. Check out Using Forms Authentication with Web API and http://aamirposwal.blogspot.com/2012/05/aspnet-web-api-custom-authorize-and.html
Found it.
In my binding, I specified allowCookies="true".
According to Wiktor Zychla, "setting the AllowCookies property on a BasicHttpBinding to true turns on the automatic cookie management" - this means that any attempt to set a cookie in code will be ignored and this is what I was doing.

WCF web services, JSON and Membership/Roles issue

We write a WCF web service.
How can we call it's methods in JSON format?
An additional issue is how can we secure our web services.
I'd like to use Microsoft Membership and Roles providers for users authentication and authorization. The question is how to do this. Is it possible to do authentication and authorization behind-the-scenes (in context of WCF), or I must call ValidateUser() and IsUserInRole() in every web method for every user call?
Whether I restricted to use webHttpBinding (over wsHttpBinding) because our client-side programmer familiar with AJAX/JSON? Whether there are any restrictions of webHttpBinding concerning using Membership/Roles comparably comparably to wsHttpBinding?
Thanks a lot in advance!
Ilan.

iPad to WCF Services authentication

I am currently working on a project that has an iPad application that uses JSON to call WCF services hosted with IIS. One of the requirements is that the WCF services needs to use IIS Basic Authentication to login. Once the user has been authenticated from the database, a few values need to set to a cookie for return trips to other WCF functions (similar to asp.net session variables). Is this possible with WCF and using cookies to hold state? If not, any recommended method?
Thank you.
WCF absolutely supports basic authentication. http://msdn.microsoft.com/en-us/library/ms733775.aspx has details on this. WCF will then identify this user on all messages that come through.
If you want to implement a customer authorization mechanic, you will need to implement ServiceAuthorizationManager. I've recently done something similar where I have iOS clients that use OAuth to authenticate with our services. I have this implemented a ServiceAuthorizationManager to determine who they are and what privileges that they have. Might be worth looking into.

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.

Basic Authentication with WCF REST service to something other than windows accounts?

Is there a clean way to expose a WCF REST service that requires basic authentication, but where we handle the actual validation of the username/password ourselves? It seems that when you tell WCF in config that you want to use basic authentication, it forces you to turn on basic authentication in IIS and IIS can only do basic authentication against window accounts.
The only hack we have found is to lie to WCF and tell it there is no security on the service and then do authentication outside of the WCF stack using a generic IHttpModule (which has a proprietary config file to indicate which URLs have which authentication/authorization requirements).
It seems like there should be a better way. Anyone have one?
The WCF REST Contrib library enables this functionality:
http://github.com/mikeobrien/WcfRestContrib
It also allows you to secure individual operations.
is the username and password set on the client like:
cc.ClientCredentials.UserName.UserName = ReturnUsername();
cc.ClientCredentials.UserName.Password = ReturnPassword();
Or are they embedded in the body of the REST message?
If the former, you can use a custom UserNamePasswordValidator:
http://msdn.microsoft.com/en-us/library/aa702565.aspx
If the latter, you can set the service to no security, and use a custom ServiceAuthorizationManager to validate the contents of the message:
http://msdn.microsoft.com/en-us/library/ms731774.aspx
Hope one or the other helps! I'd try to post sample code & config, but I'm # home and dont have access to code, which is all # work.
See Custom Basic Authentication for RESTful services. Pablo's approach uses the interceptor functionality that is provided via the REST starter kit to solve the problem. If you do not want to depend on the REST starter kit, then you can create your own service host and use the inteceptor functionality provided.
If you host it on IIS, using custom http module is the way to go. You can bring over the principal over to WCF side to do code access security. See HTTP Basic Authentication against Non-Windows Accounts in IIS/ASP.NET (Part 3 - Adding WCF Support). Also see Custom HTTP Basic Authentication for ASP.NET Web Services on .NET 3.5/VS 2008.
If you are not using IIS, you should be able to implement userNameAuthentication. See Finally! Usernames over Transport Authentication in WCF.
Yes absolutely there is a way. You need to configuring a custom userNamePasswordValidationMode value for your service and point it to a class with an overridden method that can inspect and validate the credentials provided. When making a RESTful call, these credentials when using Basic authentication in its proper form should be in the request header. With this custom method you can inspect the credentials and then authenticate the client to your service. No Windows accounts or domain even needed.
The nice thing is you can then take that security context to the next level and provide fine-grained authrization at the method level. You might have instances where a large pool of clients are able to access the service, but not all methods within (i.e. paid clients vs. unpaid). In this case you can also provide authorization at the method level as well if needed.
Below is a step-by-step solution (with too many steps to embed) by me that contains both the needed configuration and security required to have a complete solution. The problem is often Basic authentication is used without securing the Transport with a SSL certificate and this is bad. Make sure to follow all the steps and you will implement Basic authentication without the need of any type of Windows accounts or configuration on your WCF RESTful based service.
RESTful Services: Authenticating Clients Using Basic Authentication