how to restrict a wcf service to one client application only - c#

We have a WCF Service, using WSHttpBinding and security mode set to Transport, as we are using SSL. We have also been asked to make sure the service can only be called by the 1 web application that uses it, is there any way to block other applications from talking to it?
The application and service are all running within a company intranet, but there would be other applications on that intranet as well, so they want us to block them out. we tried setting the transport's clientCredentialType ="Windows" but that keeps bringing up a prompt to login whenever accessing the site, the users do not want that, as they are already logging in once the site comes up.

start here to get an overview
http://wcfsecurityguide.codeplex.com/
Some light reading...
the quick answer lies in how can you uniquely identify the Web application ?
Does it have its own APP pool on an IIS server ? And therefore could have its own user.
IS this user on The same Active directory. Then your can base the security on the Application user.
You could potentially use a firewall to make sure the traffic only comes that Web server.
You could uses an X.509 cert issued to that server and change the Binding to required X.509.
Without knowing more about the environment its hard to know what to recommend.
The guide is good. Start at solutions at a glance(page 13) to get a feel about your options and jump around from there. Unless you are patient enough to read the guide ;-)

Related

Web application that prompts credentials off network and uses Windows credentials on the network

I am implementing a C# MVC 4 application hosted in IIS 7.5 to replace the company intranet. The requirement is that when a user is at their personal workstation logged in with their windows credentials they will not be prompted to login(this is not optional the customer is firm on this as they believe this is how SharePoint works. Though I cannot confirm), however when they are on a mobile device or on a personal computer off the local network they will be promoted for their credentials. Also, while off the network the user should be able to log out, and the application should log out automatically after a period of inactivity. All users who have access to the application will have AD credentials.
I attempted to get a working solution with windows authentication, but it is my understanding that windows authentication is not intended for use outside a local network. Even if I could get the desired authentication results with this option there is no ability to log out without a significant amount of kludge and hacking with JS.
It appears that by default forms authentication is the answer, but is there a way to utilize the users windows credentials and authenticate against active directory with those without prompting the user to login while on the network?
Unfortunately even after I called Microsoft I was unable to find a good work around for this issue. They did suggest Active Directory Federation Service. This was not an option for us.
There is also a great blog post that does the opposite of what I am looking for but could probably be manipulated to work.
After working with my product owner we settled on a true forms authentication model. The way I was able to appease them was for users on the local network I am setting the time out for the forms authentication token and cookie to a longer duration and refreshing the duration so that if users are active on the application often enough they may never be prompted to log in.
This may not be the most elegant solution, but it has allowed us to meet the requirements set by the product owner. If anyone has additional suggestions I would love to hear them.

Users are being logged out of web site due to round robin load balancer

Our operator has implemented a Round Robin load balancer on our web portal and it seems to be causing some problems I can't get to the bottom of.
I'm able to identify which server we're on and as we navigate around the site we stay on server A. If I leave it for 5 minutes and try another page I'll get pushed to server B, logged out and shown the log in page.
I've got them to make sure the MachineKey in the machine.config is the same on both servers and I've tested locally that the session isn't being used - I can turn the session off completely locally and it still works. I've verified on both servers it is creating an ASPXAUTH cookie on the domain so we should be classed as authenticated on both servers - but keep loosing my authentication every time I change server.
Any ideas on what could be causing the logging out? I'm guessing it's my misunderstanding about how ASPXAUTH works.
Sessions are handled separately from Forms Authentication. There is a good explanation of this here.
The most common reason for Forms Authentication failures on load-balanced environments is lack of synchronization of the MachineKey element. You've stated that you've got the server operators to ensure that the MachineKey is synchronized, but have you verified this yourself in some way? Is this the case on ALL the web servers? From previous dealings with a couple of commercial web hosts, I've found that it is (unfortunately) difficult to take their assurances at face value.
Another thing to check is if the FormsAuthentication configuration (timeout, path, name, etc.) is the same on all of the hosts.
Are the patch levels the same on all of the hosts? You might want to see if the compatibility switch mentioned here is applicable in your situation.
Assuming that the hosting setup is correct, maybe you have initialization code on the page that logs you out if some condition is not fulfilled?
Try to take a look at the server logs and trace the sequence of HTTP requests involved during a failed page request. That might produce a clue.
Edit: This guide to troubleshooting Forms Authentication problems is detailed, and quite helpful: Troubleshooting Forms Authentication
Check for any other application functionality which depends on cookies. The web server on Server B will not recognize cookies that came from Server A. If any part of your authentication depends on cookies being populated, then that could cause your problem.
You have probably already ensured that the domain used for cookies is the same on all of the load balanced servers, but I thought I'd mention that. If the domains aren't compatible, then the browser will simply not send cookies to the server.

Granting ASP.NET access to download file from sharepoint website

I have an ASP.NET application which I am testing on the ASP.NET Development server. The application is meant to download a file from an intranet sharepoint site. I am using WebClient.DownloadFile() for this purpose. But I am getting the following exception-
"The remote server returned an error: (401) Unauthorized."
The account with which I am logged into Windows while running the application has access to the resource which I want to download.
I tried ro run the application on IIS 7.5 as well, giving the application pool the required identity to download the file. But still got the same error.
Any idea what exactly is the problem and how to overcome it? Thanks in advance!
It's a problem with double hop delegation. Look at this: http://weblogs.asp.net/owscott/archive/2008/08/22/iis-windows-authentication-and-the-double-hop-issue.aspx
Assuming normal Windows (NTLM) authentication on SharePoint site.
Most likley you are hitting by design behavior "double hop delegation" sometimes called "one hop NTLM hell" - credentials passed from client (browser) to server (your ASP.Net application) can't be used outside of the box. As result your ASP.Net application autorizes as more or less anonymous user and can't authorize on SharePoint site.
Common way to solve it - have some sort of trusted account and run your site's code under that account. Than when accessing the site you run code under process' account (not impersonating the user). You'll need to review code to have reasonable security measures as bugs will allow anyone use your site to access SharePoint/other resources under that special account.
Problem got resolved by setting UseDefaultCredentials property of the WebClient to true
This is a Kerberos issue, as Kirill mentioned. Before you start setting SPNs and the like, please follow the advice on this link first.
I recently had a frustrating week of trying to get Kerberos to work on a locked down domain and at the end of it all I found all I had to do was set useAppPoolCredentials to true.
If that doesn't help, this link provided quite useful to me as well.
Good luck!

How can I run a command line process that requires AD authentication from a .NET web service?

This is almost identical to this question asked by another user, and is the sequel to a question I asked previously.
Basically, my company recently bought Tidal Scheduler. We need to launch jobs ad hoc from other process, e.g.: BizTalk, .NET web apps, etc. Our plan was to wrap a .net web service around the C++ API. That is apparently going away version.next, so we are instead trying to wrap a .net web service around their command line interface.
The client requires Active Directory authentication. Using pretty much every method below for impersonation we have been unable to successfully call the CLI from our .net web service. From what I read in the question linked above, we are trying to impersonate a user with more rights than the ASPNET account, and this causes a security hole.
Is there a better way to do this? Is there a way to make it work with the road we have already traveled? Any help is appreciated, we have sunk way to much time into this.
Side note: we did make this happen using PsExec, but at this point it's such a huge hack-around (it's a big enough hack-around as it is) that we would very much prefer not to use this in our environment.
One possible method would be to run the web service in an App Pool that has the credentials of the user you need to impersonate. (This is assuming the authentication is the result of trying the operation and failing as the account running the current web service....if it requires authentication even when running as the user you're impersonating, you're out of luck.)
The impersonated user will need to be a member of the IIS_WPG group on the box the web service is running under. It may also need a few local permissions. Just make sure the user you are impersonating as very limited rights on the box itself.
Perhaps what you need is a windows service that has your credentials. Then your web service can call your WIndows Service to execute whatever it is you want to do. A Windows Service is a project template in Visual Studio and the docs on MSDN are very straightforward.

Can AD be used over the internet to authenticate a user?

Right now we have AD/Exchange to manage all of our users logins/e-mail on-site at the office. The major app that everyone uses maintains its own login accounts and all users have a tendency to forget login information for at least one of the two logins.
What I'm considering doing is using AD to authenticate the user in the application so that they don't even have to login to the app after they've logged into their machine.
The problem is that there are small number of users that work off-site (the app can work over the internet) and just use the machine's local account (which is causing problems of its own).
What I'm wondering is, will using AD to authenticate users on-site still be an option if a user works off-site?
The answer to almost any question posed to a programmer is "Yes..." It's what comes after the ellipses that is important. You may not want to do the things that come after the ellipses.
Based on the information in your question I think the answer is "No" but there are several scenarios where we could change that to a "yes".
If the AD account is only being used to authenticate that a user knows the password, then you could make a web service, host it in your domain, set it up to use windows authentication and SSL, modify the application to prompt the user for credentials, and call a method in the web service using those credentials. In that scenario, a successful call to the web service means that the user is authenticated. You could use the user's credentials to continue from there.
Detecting weather the application needs to prompt the user for credentials or not could be done by attempting to call the web service with the user's logged in credentials first. If this call fails then you know you need to prompt the user.
Not knowing the rest of the details of your application however means that there are many scenarios where this would not be enough.
I have done something very similar to what I described above. My scenario was the reverse: the application worked over the internet but I wanted it to be easier to log in in the cases where the machine has domain membership.
As an aside, the members who work from home: are they using laptops that are part of the domain or are they using machines that are not connected? In this case you may be able to use cached credentials but you should ask that question over at ServerFault.
Yes, you can definitely do that. It'll be a bit of work though.
What your app would have to do is either find out automagically whether it's directly connected to the office LAN, or working away from the office. Or you could have the user tell you, of course :-)
If it's on the LAN, no problem - you authenticate against AD.
If it's away from the office, you could e.g. call a WCF service on the company LAN, pass your Windows credentials, and have it authenticate you against the company AD. If you provide the right set of credentials, you'll be authenticated and allowed to work - if you're not allowed to log in, the call to the WCF service would fail.
You could do this almost automatically by using Windows credentials - in which case the "remote" user would still have to log on to your domain and use his / her normal Windows credentials; or you can pass username/password over the wire to WCF, or even install a certificate on the remote user's machine that WCF will then map to an AD account on the server side.
The options are plentiful! :-)
Marc

Categories