Reputation: 63495
This question has broadened in scope from previous revisions. I have tried to simplify the issue so it can be easily reproduced by anyone.
Using Fiddler, I can replay an arbitrary request to my default page after erasing my Authorization
header from the HTTP request, and I am able to get a response of 200 OK
with valid data.
Here are the steps to reproduce this exact behavior:
1. Create a "New Website" in ASP.NET, feel free to name it "InsecureWebsite"
2. Edit web.config
to deny all unauthenticated users:
<authentication mode="Windows" />
<authorization>
<deny users="?"/>
<allow users="*"/>
</authorization>
3. Publish the website to an arbitrary directory on a DEV server and create a virtual directory for the application
4. Ensure the application has script access (.ASP) and Integrated Windows Authentication enabled
5. Open Fiddler to capture the traffic
6. Load the page in your favorite browser and look at the "Inspectors" tab within Fiddler, you'll see a request similar to:
GET /InsecureWebsite/ HTTP/1.1 Host: dev.subdomain.example.com User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9.1) Gecko/20090624 Firefox/3.5 (.NET CLR 3.5.30729) Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8 Accept-Language: en-us,en;q=0.5 Accept-Encoding: gzip,deflate Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7 Keep-Alive: 300 Connection: keep-alive Authorization: NTLM {Base64-encoded authentication data}
The initial request to Default.aspx
will return a 401 Unauthorized
, will go into negotiation, and then finally return a 200 OK
.
In Fiddler I can then erase the Authorization
header directly from a replayed request to Default.aspx
and still get a 200 OK
. How is that possible?
It turns out that Fiddler uses the same underlying connection when making the requests, so once the connection is authenticated, any request on the same connection will also be authenticated as the same user as the initial request. You can turn this feature off in Fiddler here:
Screenshot of Fiddler options http://john.cognitivedelay.com/images/fiddler-options.gif
Once this has been unchecked, any replayed requests from within Fiddler will return a 401 Unauthorized
as I would expect.
Thanks to all who offered their time to respond!
Upvotes: 2
Views: 1278
Reputation: 45152
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...)
Upvotes: 2
Reputation: 31
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;
}
Upvotes: 2
Reputation: 60570
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.
Upvotes: 1
Reputation: 5226
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.
Upvotes: 1
Reputation: 16031
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
Upvotes: 1