ASP.NET MVC 应用程序应用程序/json 响应内容神秘地被文本/html 内容覆盖
Posted
技术标签:
【中文标题】ASP.NET MVC 应用程序应用程序/json 响应内容神秘地被文本/html 内容覆盖【英文标题】:ASP.NET MVC app application/json response content mysteriously being overwritten by text/html content 【发布时间】:2021-06-22 18:54:44 【问题描述】:我已经在 ASP.NET MVC 应用程序中构建了 oauth2 服务器的功能。
一切正常,并指定所有非错误产生的积极案例。但是我遇到了一个问题,似乎 MVC 想要注入 text/html 我在混合中很晚才指定 application/json 的地方。
这很奇怪,因为如果我使用诸如soap UI 之类的工具进行测试以发布到我的端点,并且soap UI 与我的服务器运行在同一台机器上运行,那么错误结果会完美地返回并按照指定的方式返回。但是,如果我在另一台机器上(甚至在我的网络上)使用soap UI 进行测试,那么我尝试编写的JSON 将被一些注入的文本/html 覆盖。
首先是代码 sn-p,我为这个问题简化了它。返回 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=ObsfucatedFor***&client_secret=ObsfucatedFor***&refresh_token=ObsfucatedFor***
这是正确的结果,适当地指示错误,并呈现为 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=ObsfucatedFor***&client_secret=ObsfucatedFor***&refresh_token=ObsfucatedFor***
响应保持 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">
<!--
bodymargin:0;font-size:.7em;font-family:Verdana, Arial, Helvetica, sans-serif;background:#EEEEEE;
fieldsetpadding:0 15px 10px 15px;
h1font-size:2.4em;margin:0;color:#FFF;
h2font-size:1.7em;margin:0;color:#CC0000;
h3font-size:1.2em;margin:10px 0 0 0;color:#000000;
#headerwidth:96%;margin:0 0 0 0;padding:6px 2% 6px 2%;font-family:"trebuchet MS", Verdana, sans-serif;color:#FFF;
background-color:#555555;
#contentmargin:0 0 0 2%;position:relative;
.content-containerbackground:#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 页面)。
非常感谢任何帮助。
【问题讨论】:
【参考方案1】:原来微软提供了另一个标志来抑制这种行为。
除了:
Response.SuppressFormsAuthenticationRedirect = true;
原来你还需要设置:
Response.TrySkipIisCustomErrors = true;
为了让 IIS 远离您的业务。
【讨论】:
以上是关于ASP.NET MVC 应用程序应用程序/json 响应内容神秘地被文本/html 内容覆盖的主要内容,如果未能解决你的问题,请参考以下文章
如何从 ASP.net MVC 程序中获取纯 c# 程序中的 JSON 数据?
从 ASP.net Core 2 MVC 应用程序中的 appSettings.json 存储/检索 ConnectionString
在ASP.NET MVC中全局应用JSON Serializer设置
ASP.NET MVC 应用程序应用程序/json 响应内容神秘地被文本/html 内容覆盖