I have an ASP file that is trying to make a webservice request to an ASP.NET webservice running on the same server under the same virtual directory. In IIS the virtual directory is set up to disable anonymous access and "integrated windows authentication" is turned on.
So the problem is, when the user's machine requests to run the ASP page or even manually run the WebService.asmx .NET file, it works because the user's credentials are passed along, however when the ASP file tries to invoke the webservice we get a 401.2 - Unauthorized: Access is denied due to server configuration.
For example:
- "DIRECTORY\user1" from a browser on the user machine requests Service.asmx which works fine.
- "DIRECTORY\user1" from a browser on the user machine requests File1.asp which works fine.
- _________ from within File1.asp on the server requests Service.asmx which returns 401.2
So I assumed I needed to set NTFS permissions on WebService.asmx to allow the ASP account Read & Execute permissions, but I don't know what account it runs under, and upon further thought after reading some of the reponses, it seems like we aren't getting to the NTFS level, IIS is completely rejecting the request because anonymous access is turned off.
Does this indicate that we need to get the ASP process running under a domain account?
Classic ASP runs impersonating the user who is authenticated to the server in the HTTP session. You need to grant the users who are authenticating to run the classic ASP application permission or allow anonymous access.
If you've tried "Authenticated Users" already and it's not working then I'd say that you're not having a file permission issue.
What do you mean when you say "...the ASP file tries to invoke the webservice..."? Are you saying that the ASP script is making an HTTP request back to the server? If so, the user's credentials aren't going to get passed along in that request because "Integrated Windows authentication" doesn't give the server a plaintext password to use when authenticating to other servers (or itself).
Edit:
Per your comment, then, as stated above the server is going to have no credentials with which to authenticate the user because Integrated Windows authentication gives the server no plaintext password to pass on to other servers (or itself, which is another server in this case).
Three things you could try:
If you can get WebService.asmx to allow anonymous access your server-to-itself HTTP call should work (you'll need to explicitly allow anonymous access by allowing IUSR_xxx to read the file and by modifying the "Anonymous access and authentication control" setting for "Anonymous Access" on the file itself via the IIS management console snap-in since that file will be inheriting the enabled "Integrated Windows authentication" and disabled "Anonymous access" settings from the directory it's in).
If the control you're using to source the HTTP request supports transparently providing the credentials of the logged-in user to the remote server you could enable "Basic authentication" on the classic ASP script (which does give the server a plaintext password to pass on to other servers) so that your HTTP request control can pass that plaintext password on during the request for WebService.asmx. You'll want to require SSL on access to the classic ASP script, at that point, to keep plaintext passwords off the wire.
Finally, you could just hard-code in some basic authentication credentials in the classic ASP script and enable basic authentication on the WebService.asmx file. That means that WebService.asmx will always see access from the same user.
None of those are very nice solutions. You're running into a "classic" problem that we saw with "classic ASP" when trying to authenticate to a back-end tier (database, etc) as the user who authenticated to run the classic ASP script.
If integrated authentication is on and the user is using a browser that will do windows Integrated authentication and the user is logged in as an account that translates to one the web server (for example, the client machine is on the same domain as the web server) the your script will run as that user's account.
If any of the above is false (so the server can't agree a user account with the client browser) then what-ever you have set as the user for anonymous is used,
IUSR_<machine>
by default, or if anonymous browsing is disabled the user will get a 401.* error.This assumes that other authentication opinions are off. I'm not sure what takes precedence if you have both Windows Integrated and Basic authentication schemes enabled at the same time.
You can see the user that the web server is currently using for requests to a particular area by dropping in a script that queries the reqeust.servervariables collection and outputs the relevant value(s) - the username is in there.
Looks like you are trying to do a "double-hop" authentication. Typically this occurs in the context of a backend SQL service, but it could apply to a separate service running on the same server I think (I'm not 100% certain though). Search in MSKB for that term, "double hop" and you will get a few docs that explain how to setup delegation to allow this to work. Here's one to start with, http://support.microsoft.com/kb/326985
What you need is for the IIS server to be set for "Delegation Allowed." When the user is authenticated via Windows Integrated Authentication, they should get a Kerberos ticket (this WILL NOT work if you are getting NTLM authentication).
In order to do delegation you will need to add a SPN to the server. Make sure that the users are getting to the webpage with the actual FQDN the server has a SPN for in AD. The Service Principal Name (SPN) is what the user Kerberos agent will use to create the right Kerberos ticket which will allow the IIS server to impersonate the user when it hands off the request to the next service.
Is it important that the webservice uses the credentials of the logged in user? If you're using something like MSXML2.ServerXMLHTTPRequest to make the call to the web service, could you simply supply credentails in the .Open method to supply a fixed set of credentials to the web service?