为什么我的 ASP.NET 页面返回“200 OK”而没有发送任何身份验证标头?
笔记:
与之前的修订相比,此问题的范围有所扩大。 我试图简化问题,以便任何人都可以轻松重现。
使用 Fiddler,我可以在删除我的授权<后重播对我的默认页面的任意请求来自 HTTP 请求的 /code> 标头,我能够获得包含有效数据的
200 OK
响应。
赏金更新
以下是重现此确切行为的步骤:
1. 在 ASP.NET 中创建一个“新网站”,随意将其命名为“InsecureWebsite”
2. 编辑web.config
拒绝所有未经身份验证的用户:
<authentication mode="Windows" />
<authorization>
<deny users="?"/>
<allow users="*"/>
</authorization>
3. 将网站发布到 DEV 服务器上的任意目录,并为应用程序创建虚拟目录
4.< /strong> 确保应用程序具有脚本访问权限 (.ASP) 并启用集成 Windows 身份验证
5. 打开 Fiddler 来捕获流量
6. 在您最喜欢的浏览器中加载页面,然后查看 Fiddler 中的“检查器”选项卡。 com/fiddler2/" rel="nofollow noreferrer">Fiddler,您将看到类似以下内容的请求:
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}
对 Default.aspx
的初始请求将返回 401 Unauthorized< /code>,将进入协商,然后最终返回
200 OK
。
然后,在 Fiddler 中,我可以直接从重播的 Default.aspx
请求中删除 Authorization
标头,并且仍然得到 200 OK
。 这怎么可能?
解决方案
事实证明,Fiddler 在发出请求时使用相同的底层连接,因此一旦连接经过身份验证,同一连接上的任何请求也将被验证为与初始请求相同的用户。 您可以在此处关闭 Fiddler 中的此功能:
Fiddler 选项的屏幕截图 http://john. recognizedelay.com/images/fiddler-options.gif
一旦取消选中此选项,Fiddler 内的任何重播请求都将返回 401 Unauthorized
,正如我所期望的那样。
感谢所有抽出时间回复的人!
Note:
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.
Bounty Update
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?
Solution
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!
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
编辑:根据更新的问题:
您是在 Fiddler 本身中进行重播,还是直接连接到网络服务器? 可能是 Fiddler 正在重用现有的 HTTP 连接(它可以作为代理)...我认为 IWA 可能会将整个连接标记为经过身份验证,而不仅仅是当前请求,这意味着同一网络上的任何未来请求连接重新使用第一次协商中的授权和身份验证...
原始答案:
尝试
看看是否有帮助?
(可能是
[PrincipalPermission(SecurityAction.Demand, Role="myDevRole")]
如果这更适合您......)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
and see if that helps?
(Possibly
[PrincipalPermission(SecurityAction.Demand, Role="myDevRole")]
if that's more appropriate for you...)Ajax 调用是在现有经过身份验证的会话的新线程上完成的,这就是为什么您在标头中看不到任何身份验证信息的原因。 会话已通过身份验证。
您可以获取经过身份验证的用户身份,然后通过引用 System.Threading.Thread.CurrentPrincipal.Identity.Name 将其传递给任何角色管理例程:
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:
您可以将身份验证信息添加到消息的标头中,然后在 Web 方法中对自己进行身份验证。
或者您可以尝试类似 this< /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
将此属性添加到 Web 方法中
[PrincipalPermissionAttribute(SecurityAction.Demand, Role = "myDevRole")]
。然后,在 Global.asax 事件 Application_AuthenticateRequest 上,您可以确保当前线程用户经过正确身份验证 - 即执行必要的操作以避免欺诈 cookie 或会话。
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.
在本地开发计算机上使用 Windows 身份验证,每个请求都来自经过身份验证的用户。 所以,拒绝用户=“?” 绝不会拒绝本地的任何请求。
如果您在未进行身份验证或未使用表单身份验证的远程 IIS 计算机上点击此选项,则需要进行身份验证才能成功请求 Default.aspx 或页面方法。
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.