I'm beginning to have doubts as to if this is possible but I'm hoping that someone out there has a deeper understanding of the mechanics than I do.
We are planning to host a pure javascript form in a SharePoint site that is secured using ADFS. This form needs to make calls to a WCF REST service. We want to be able to use the same FedAuth cookie / SAML token issued to the user from ADFS in the WCF service for authentication but so far I have not really found a way to pass it using javascript.
So to break it down, how do you call a WIF / SAML secured WCF REST service from javascript?
Related
I need to secure a WCF Service that uses webHttpBinding with tokens, but having a hard time figuring out how to do so. It is my understanding that the recommend way of doing this is by using JWT Tokens?
I have an STS (IdentityServer) that issues JWT tokens to my Mobile Client (Sencha Touch Application) through OAuth 2.0, and this application needs to call a webHttpBinding based WCF Service.
Now I want to secure this using tokens, and I know Microsoft has released a JWT Security Token Handler NuGet package.
I have added this security token handler in the "securityTokenHandlers" tag under my "identityConfiguration" tag in the web.config, but I feel a bit lost on how to actually use the token handler to validate the token, extracting the claims and setting the IClaimsPrinicipal object.
Most examples I have been able to find use WebAPI and are for ASP.NET applications, but in my case I need to just secure an "ordinary" WCF Service using a webHttpBinding.
Any help on how to accomplish this, would be greatly appreciated.
You won't find many samples with OAuth implementation over SOAP services. OAuth was created primarily for clients that could not handle SOAP and its associated WS-Security complexity.
Although not common, it is still possible, you just need to implement your own WCF pipeline hook (IDispatchMessageInspector) to get the token from HTTP header and then use the JWT classes to set your claims.
I have not used this code sample, but it looks like it will do what you want.
http://blogs.msdn.com/b/pavelkhodak/archive/2013/07/26/enable-http-bearer-jwt-token-authentication-for-rest-service-using-webhttpbinding-in-wcf.aspx
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.
When i try to invoke a WCF service from an asp.net application (RP) which is authenticated by another asp.net application(IP) , I'm getting an error message with content of Login page (It is trying to reach the login page because it could not authenticate the request).
Identity Provider : _http://localhost/AuthenticatonWS/Login.aspx
Relying party Website : _http://localhost/RPWebsite/Default.aspx
WCF Service : _http://localhost/RPWebsite/Service1.svc
(In my solution I'm calling service1.svc from default.aspx.cs)
I don't want the service to be anonymous. Currently the site (RPWebsite) uses STS and trusts local Identity provider, but in production it can trust any external identity provider thru ADFS.
Can any one guide me how i can pass the token information to the service from aspx page, I did try several examples from internet but i could not get it working.
The problem could very well be that the RPWebsite uses ClaimsAuthorizationModule in <system><httpModules> or <system.webserver><modules> in web.config. This causes any web service call to be redirected to the STS for authentication, as if it were an interactive browser request, as you observed.
Alternatively, this module can be added in the WIF-specific section of web.config, that is, in <microsoft.identityModel><service>, and in this case this module is only used for claims-based WCF web service calls. You add it in the following form: <claimsAuthorizationManager type="MyNamespace.CustomClaimsAuthenticationManager, MyAssembly"/>. (This type must extend ClaimsAuthorizationManager, as described in the WIF documentation page "ClaimsAuthenticationManager, ClaimsAuthorizationManager, and OriginalIssuer".)
Reference: Vittorio Bertocci, "Programming WIF", p. 43.
I think there are several options:
Using Persistent Authentication Cookies that support multiple client sessions. Or support sharing session between your RP and WCF service, so that WCF can re-utilized the authentication cookies issued for RP when RP makes a call to WCF service. To be honest, I have never tried to implement this in action. It is just my theory.
Create an separate authentication service which require no user-interaction (such as entering username/password). And then you have plenty of way to call WCF from your RP:
From your RP, ask the authentication service to issue a token for WCF; attach the token into request header of WCF call (e.g.: Authorization); then call WCF service. This requires a custom HttpModule to accept custom request header containing token at WCF service.
From your RP, you can also store UserName/Password, or an unique user identity claim which could identify the user; attach those information into request header of WCF call (e.g.: Authorization); then call WCF service. This also requires custom HttpModule to accept custom request header at WCF service.
I would recommend the second option, which you could find more useful information and guideline from Dominick Baier's blog.
Just my 2 cents.
I want to port an existing ASP.NET Web Service to WCF so the resulting Web Service (1) is RESTful, (2) uses JSON as its request/response format, (3) has a custom authentication mechanism.
After a lot of googling, random coding, and wanting to hit my head against the wall, I found that...
A webHttpBinding has to be used to make the Web Service RESTful. But...
webHttpBinding does not support HTTPS hosts.
webHttpBinding does not support UserName authentication.
webHttpBinding does not even support message security.
An endpoint behavior with <enableWebScript/> has to be used to support ASP.NET AJAX. But...
What is "ASP.NET" AJAX?
What if I want to consume the Web Service using "regular" AJAX?
And, most importantly...
Can WCF do what I want to do in first place?
If not, what other platforms could I use?
I've written WCF service that does both SOAP and REST with XML and JSON, and custom auth. I've pushed the custom authentication into HTTP module, which does basic auth over https. See Custom HTTP Basic Authentication for ASP.NET Web Services on .NET 3.5/VS 2008 and WCF POX, JSON and SOAP Coexist.
In the setup you describe, the web servier (i.e. IIS) will be responsible for encryption (HTTPS) and authentication (e.g. basic authentiction). IIS can be extended with a custom authentication mechanism (just google for "IIS module handler").
It's a bit strange that it has to be delegated to IIS and is not part of WCF. But it's no problem at all.
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