c# - ASP.NET MVC 应用程序应用程序/json 响应内容神秘地被文本/html 内容覆盖
问题描述
我已经在 ASP.NET MVC 应用程序中构建了 oauth2 服务器的功能。
它一切正常,并指定了所有非错误产生的正面案例。但是我遇到了一个问题,似乎 MVC 想要在混合中很晚才指定 application/json 的地方注入 text/html。
这很奇怪,因为如果我使用诸如soap UI之类的工具进行测试以发布到我的端点,并且soap UI与我的服务器运行在同一台机器上运行,错误结果会完美地返回并按照指定的方式返回。但是,如果我在另一台机器上(甚至在我的网络上)使用soap UI 进行测试,那么我尝试编写的JSON 将被一些注入的文本/html 覆盖。
首先是我为这个问题简化的代码片段。返回 JsonResult 的控制器操作如下所示:
public JsonResult RefreshOauth2Token(string grant_type, string client_id, string client_secret, string refresh_token)
{
try
{
var resultFromMyDB = DoMyBusinessToRefreshToken(string grant_type, string client_id, string client_secret, string refresh_token);
// This positive case works perfectly.
return Json(new
{
access_token = resultFromMyDB.AccessToken,
token_type = resultFromMyDB.TokenType,
expires_in = resultFromMyDB.ExpiresInSeconds,
refresh_token = resultFromMyDB.RefreshToken
});
}
catch (Exception e)
{
string error;
string errorDescription = e.Message;
switch (e)
{
case MyInvalidClientException:
error = "invalid_client";
Response.StatusCode = 401;
break;
case MyInvalidGrantException:
error = "invalid_grant";
Response.StatusCode = 400;
break;
case MyInvalidRequestException:
error = "invalid_request";
Response.StatusCode = 400;
break;
case MyUnsupportedGrantTypeException:
error = "unsupported_grant_type";
Response.StatusCode = 400;
break;
case MyUnsupportedTokenTypeException:
error = "unsupported_token_type";
Response.StatusCode = 400;
break;
default:
error = "server_error";
Response.StatusCode = 500;
break;
}
Response.SuppressFormsAuthenticationRedirect = true;
// When I trace code to this point, everything looks fine.
// But for some reason something subverts my JSON much farther down the pipeline....
return Json(new { error, error_description = errorDescription });
}
}
这是在我的试用版中发布的请求的样子:
POST https://localhost/oauth2token HTTP/1.1
Accept-Encoding: gzip,deflate
Content-Type: application/x-www-form-urlencoded
Content-Length: 245
Connection: Keep-Alive
User-Agent: Apache-HttpClient/4.5.5 (Java/12.0.1)
grant_type=refresh_token&client_id=ObsfucatedForStackOverflow&client_secret=ObsfucatedForStackOverflow&refresh_token=ObsfucatedForStackOverflow
这是正确的结果,适当地指示错误,并呈现为 JSON:
HTTP/1.1 401 Unauthorized
Cache-Control: no-cache, no-store
Pragma: no-cache
Content-Type: application/json; charset=utf-8
Expires: -1
X-UA-Compatible: IE=Edge
Date: Thu, 25 Mar 2021 22:24:06 GMT
Content-Length: 71
{"error":"invalid_client","error_description":"Invalid Oauth2 Client."}
但是如果我现在转移到另一台机器上运行soapUI,发布请求,这次发布为:
POST https://my.machine.com/oauth2token HTTP/1.1
Accept-Encoding: gzip,deflate
Content-Type: application/x-www-form-urlencoded
Content-Length: 245
Connection: Keep-Alive
User-Agent: Apache-HttpClient/4.5.5 (Java/12.0.1)
grant_type=refresh_token&client_id=ObsfucatedForStackOverflow&client_secret=ObsfucatedForStackOverflow&refresh_token=ObsfucatedForStackOverflow
响应保持 401 的状态码(正确),但不知何故 application/json 内容类型已被 text/html 覆盖,实际内容也已被覆盖:
HTTP/1.1 401 Unauthorized
Cache-Control: no-cache, no-store
Pragma: no-cache
Content-Type: text/html
Expires: -1
X-UA-Compatible: IE=Edge
Date: Thu, 25 Mar 2021 22:29:46 GMT
Content-Length: 1293
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1"/>
<title>401 - Unauthorized: Access is denied due to invalid credentials.</title>
<style type="text/css">
<!--
body{margin:0;font-size:.7em;font-family:Verdana, Arial, Helvetica, sans-serif;background:#EEEEEE;}
fieldset{padding:0 15px 10px 15px;}
h1{font-size:2.4em;margin:0;color:#FFF;}
h2{font-size:1.7em;margin:0;color:#CC0000;}
h3{font-size:1.2em;margin:10px 0 0 0;color:#000000;}
#header{width:96%;margin:0 0 0 0;padding:6px 2% 6px 2%;font-family:"trebuchet MS", Verdana, sans-serif;color:#FFF;
background-color:#555555;}
#content{margin:0 0 0 2%;position:relative;}
.content-container{background:#FFF;width:96%;margin-top:8px;padding:10px;position:relative;}
-->
</style>
</head>
<body>
<div id="header"><h1>Server Error</h1></div>
<div id="content">
<div class="content-container"><fieldset>
<h2>401 - Unauthorized: Access is denied due to invalid credentials.</h2>
<h3>You do not have permission to view this directory or page using the credentials that you supplied.</h3>
</fieldset></div>
</div>
</body>
</html>
这不是期望的行为,但对于我的生活,我无法弄清楚是什么在注入 html 代码。有没有可能它甚至不是 MVC 而是 IIS?如何通过注入我不想停止注入的东西来强制这种试图“帮助”我的行为?我只想不理会 JSON。
请注意,注入的 HTML 不是来自表单身份验证。如果您查看上面的 c# 源代码,您将看到表单身份验证被禁止。(没有那行代码,就会注入一个完全不同的 HTML 页面)。
非常感谢任何帮助。
解决方案
原来微软提供了另一个标志来抑制这种行为。
此外:
Response.SuppressFormsAuthenticationRedirect = true;
原来你还需要设置:
Response.TrySkipIisCustomErrors = true;
为了让 IIS 远离您的业务。
推荐阅读
- neo4j - 密码问题,仅在与所有节点连接时才返回结果
- android - Android - 生物特征信息是否与设备上的特定用户或一般设备相关联?
- reactjs - 来自API的分页反应如何检测最后一项
- angular - selectedRowIndex 启用 Angular 测试按钮
- mysql - 存储过程中的 MySQL 事务
- android - 代号一中的存储持久性
- swift - Swift 中类似 Apple Music 的 NavigationBar
- security - Sharepoint 列表和访问权限
- flutter - 当从列表中删除上一个项目时,ListView 将下一个项目的动画值设置为 1.0 (Flutter)
- sql - 用于 float8 数据类型的 MD5 在 Redshift 和 Postgres 之间有所不同