+1  A: 

You could potentially add authentication information to the header of the message, then authenticate yourself in the webmethod.

or you could try something like this or this

MasterMax1313
+1  A: 

Add this attribute to the web method [PrincipalPermissionAttribute( SecurityAction.Demand, Role = "myDevRole" )].

Then on Global.asax event Application_AuthenticateRequest you can make sure that current thread user is authenticated correctly - i.e. do what is necessary to avoid fraud cookies or sessions.

Ivan Zlatanov
I tried this exactly and got the same results. Currently, I'm attempting to recreate the behavior I am experiencing and will update the question
John Rasch
+2  A: 

Edit: per updated question:

Are you doing the replay in Fiddler itself, or by making a direct connection to the webserver? It might be that Fiddler is reusing an existing HTTP connection (which it can do, as a proxy)... I think IWA might mark the whole connnection as authenticated, not just the current request, which means that any future requests on the same connection re-use the authorization and authentication from the first negotiation...

Original answer: Try

[WebMethod(EnableSession=true)]  
[PrincipalPermission(SecurityAction.Demand, Authenticated=true)]

and see if that helps?

(Possibly [PrincipalPermission(SecurityAction.Demand, Role="myDevRole")] if that's more appropriate for you...)

Stobor
+2  A: 

The Ajax call is done on a new thread for an existing authenticated session, That's why you don't see any authentication information in the headers. The session is already authenticated.

You can get the authenticated user's identity, and then pass that on to any role management routines, by referencing System.Threading.Thread.CurrentPrincipal.Identity.Name:

[WebMethod(EnableSession = true)]   
public static string WhoAmI()
{
    // Return the identity of the authenticated windows user.
    Return System.Threading.Thread.CurrentPrincipal.Identity.Name;
 }
Neil
I've recently determined that the scope of the problem is beyond the `WebMethod` call.
John Rasch
I think you're performing 'session hijacking' with fiddler running as a proxy. After the session is authenticated, you are using fiddler in place of your browser to perform requests. Opening a new browser session from the desktop, or using a different browser, should show you that a new session will be created and need authentication.
Neil
So back to your original question regarding the JQuery Ajax call to the webmethod. It's still not sending headers, right? It's still not getting a 401, because it's already authenticated.
Neil
The Ajax call was being authenticated like any other page (as I had always thought was the case), except the requests I was creating in Fiddler were using a previously authenticated TCP connection. When that feature was disabled, the Ajax request along with all other requests behave as expected.
John Rasch
+1  A: 

Using Windows authentication on your local development machine, every request is going to be from an authenticated user. So, deny users="?" will never deny any requests locally.

If you were hitting this on a remote IIS machine you aren't authenticated with or were to use Forms Authentication, it would require authentication before you could successfully request either Default.aspx or the page method.

Dave Ward
+1 - Excellent point, but I am uploading to a dev IIS server and am still able to replay requests without an `Authorization` header and get a `200 OK` response. I will update the question to add the steps I've taken to publish
John Rasch
If it's allowing you to load Default.aspx without authentication, *something* must be representing you to the server as authenticated. I think your problem's scope isn't as narrow as the service call itself.
Dave Ward
@Dave - you're right again, I can reproduce the behavior by erasing the `Authenticate` header and sending another request to `Default.aspx`, this will drastically change the question since it no longer focuses on just the WebMethod call.
John Rasch
To isolate your repro to test just page method authentication, how about moving your page method to an ASPX page in a different subdirectory and only apply the deny users="?" to that subdirectory. If you then make the unauthenticated $.ajax call from a page in the root, it should properly respond with a 401.
Dave Ward