Custom "Basic" Authentication for my WCF services. REST and RIA. Possible? - wcf

My server side contains WCF4 REST services and I'm going to add RIA services for my future SL4 application. Currently I'm doing Basic authentication like this:
var auth = HttpContext.Current.Request.Headers.GetValues("Authorization");
And so on.. You get the idea.. I call this on every request. If header not present or I can't validate UN/Password - I do this:
outgoingResponse.Headers.Add("WWW-Authenticate: Basic realm=\"Secure Area\"");
That got me by so far but I'm refactoring my server side. Implementing IoC for linked services. Created custom ServiceHost, ServiceHostFactory, InstanceProvider and all is well.
Now I need to figure how to properly handle authentication and authorization with WCF so I don't have to manually inspect headers. I do have my custom MembershipProvider so there have to be some method that get's UN/PW to process.
Any pointers? I looked at http://www.codeproject.com/KB/WCF/BasicAuthWCFRest.aspx but it uses RequestInterceptor and it is not available in WCF4. I found ServiceAuthenticationManager and ServiceAuthorizationManager but there is no samples available on how to code and wire those..
Can anybody suggest which way I should go?

Try to use this custom HTTP module. It will add new authentication mode to IIS and it will allow you using custom credentials validation.

I had all types of issues using the built-in annotations for WCF in a recent SOAP/C# project. I know this isn't the best solution, but for my purposes, I enabled basic authentication in IIS7 for my application, disabled anonymous authentication and created Active Directory users for the external clients that would call the web service endpoints. I then changed the application's permissions in IIS7 (it uses file system permissions) to allow a group containing those users.
This moves authentication outside your application, which may not be what you want, but does allow you to easily add users via the IIS7 console and deployment tools that can copy those permissions. The advantage is that you don't have to redeploy your application for permission changes. The disadvantage is you can't do fine grained permission control per function.

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.

development setup for wcf with username security on VS2010 and IIS express

Here's the end game... I need a wcf service application with username/password security over ssl. Pretty basic stuff, but I'm at my wit's end trying to make this work. I'm trying to implement the HOWTO guide from microsoft's patterns and practices as listed here:
How to: Use Username Authentication with Transport Security in WCF Calling from Windows Forms.
I've follwed each of the steps exactly... except steps 9 - 12. Those steps implement a custom authentication and authorization class. I'm having errors both with the implmentation of these custom classes and without.
First, without the custom classes... Without the custom authorization and authentication I can compile my wcf project and create the service reference in the console client application. When I run my console application it works, but when I decorate my wcf method to restrict the permissions, it appears that the client is never passing the credentials to the wcf service. If it leave the decoration off the method and step trace into the wcf method, if find that the ServiceSecurityContext.Current.PrimaryIdentity.Name is blank. I'm decorating with:
[PrincipalPermission(SecurityAction.Demand, Role = "sysadmin")]
(and yes, I've used the ASP.net configuration to create the role and the account in that role.)
Second, with the custom classes... If I include the HttpModules element as listed in step 10, I get an error stating that IIS express 7.5 doesn't do it this way any more and I need to move the configuration. With a little bit of hunting I found that I needed to move the item to . But it still complains that is can't reference the module. If I leave out the authentication module and try to just reference the authorization module, I get the same error.
I tried to include the entire web.config, but this editor didn't want to take it all. Suffice it to say that it's exactly like the msdn article except for moving the module tag.

WCF Data Services with Integrated Authentication issue

I have a web project that has Anonymous access and Integrated Windows authentication enabled. I built a WCF Data Service and since it allows only one authentication, I enabled Integrated authentication on the service. I am able to view the service in browser. However when I try to query the service for any Entity, it gives me Forbidden error. I tried to enable Anonymous access on service too, but it does not work.
Do I need to give it some other access or it is not possible to enable one authentication on the service itself keeping the project virtual directory as Anonymous and Integrated.
Update: I do no have any operations in my Data Service. For the entities, I have already set the "All" permission on all entities.
Only one authentication method is permitted on a WCF Data Service.
If you choose to go the Integrated Security route then you need to set the credentials after constructing the DataServiceContext.
Something like this would work for using the current user's Windows identity.
employeeEntities = new EmployeeDataService.EmployeeEntities(new Uri("http://.../employeedata.svc"));
employeeEntities.Credentials = CredentialCache.DefaultCredentials;

Using WCF authentication service for web application

I am using a WCF authentication service I set up with a web application. I have successfully set up and tested the AuthenticationService and RolesService. The web application can successfully call methods like ValidateUser and GetRolesForCurrentUser through the WCF services.
I want to integrate the WCF authentication service with my web.config and site.map. Do I need to write a custom provider, or is there some way I can modify the web.config of the web application to use the WCF authentication service as its membership provider?
This way I can set what roles have access to what directories based off the WCF authentication service.
Application Services are not intended as a replacement for the provider stack.
They are meant to augment and enable usage from context other than .aspx.
In most cases you may simply use the default provider stack (Membership/Roles/Profiles).
You simply need to pass the cookies that you get when you call 'Login' via app services around in the context of the service call.
See here for some more information about adding cookies to a WCF call.
If you are using AJAX to call the services, you don't have to do anything, simply authenticate via ajax and then call via ajax.
Skys answer doesn't seem to answer the question?
It seems to me that there is a genuine need to call the WCF AuthenticationService from an ASP.NET application?
Consider a three tier application where all database access is mandated to be performed by the application tier. There is a single database (data tier) containing business data as well as membership data.
I have written a three tier implementation whereby a custom MembershipProvider on the presentation tier invokes the AuthenticationService on the application tier which in turn runs my custom authentication routine.
I could quite easily create a custom WCF service (eg not AutheticationService) which does this authentication but I try to use .NET objects where possible.
it would be nice if I could tell ASP.NET to use the AutheticationService without needing a custom membership provider but I dont think this is possible?

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