asp.net - 在 IIS 上运行的 ASP.NET Web API 2 应用程序向 IIS express 上的本地应用程序返回 OK 数据,但在将请求应用程序部署到 IIS 后未经授权
问题描述
我有两个应用程序和一个数据库,一旦部署到不同服务器上的 IIS,我正试图访问所有“Play nice”。目标是让用户最初通过 Windows 进行身份验证,然后仍然让服务进行通信。我们希望用户 EID 作为每个步骤/请求的身份持久存在,但如果这是我们必须使用某种通用 AppPool 帐户的情况,我认为我们对此持开放态度。
当我从本地启动的应用程序从 IIS express 本地调用 Odata Web API 时,没有错误。该数据库是一个已经运行了一段时间的 MS SQL Server 数据库,包含一些应用程序使用的大量数据,并在使用 Telerik Fiddler 等查询时按预期返回数据给应用程序 1 。
应用程序和数据库都在不同的服务器上运行。
基本请求方案如下:
客户端设备(用户在此处针对 AD 进行身份验证)->GET->Application 2->GET->Application 1->SQLQUERY/DbContextRequest->SQL Server
因此,客户端设备发出获取请求(来自移动应用程序),该请求被发送到Application 2的 API 端点,然后调用Application 1 API 端点以从数据库中检索数据并返回到Application 2,其中在将数据发送回客户端设备之前,会进行少量数据组织。
细分:
应用一: ASP.NET Web API使用Odata控制器接收请求
应用 2:使用RestSharp发送请求的ASP.NET Web API 。
到目前为止,应用程序 1已经部署到其服务器数月,没有出现任何问题,但这是我们第一次尝试从另一个 Web 服务(应用程序 2 )调用应用程序 1。
应用程序 2可以毫无问题地调用我们公司托管的其他 Web 服务,只有这个(应用程序 1)返回“未经授权”。
故障应用程序(应用程序 1)当前部署到 IIS。当我从在 IIS express 中运行应用程序 2 的本地应用程序机器向应用程序 1 发送 GET 请求时,数据按预期返回。在我的本地机器上使用 Fiddler 也可以毫无问题地从应用程序 1返回数据。
但是,一旦我将Application 2部署到 IIS,一旦部署到 IIS,带有 Odata 控制器(Application 1 )的应用程序就会对从Application 2发送到Application 1的任何请求返回“未经授权” 。
我使用log4Net并确定无论我是否使用模拟,我都是未经授权的,即使以同一用户(通过日志验证)或 AppPool 身份发送请求也是如此。我的 AD 帐户和 AppPool ID 帐户都可以完全访问返回“未授权”的应用程序 1的文件夹。
我正在使用RestSharp库发送请求:
[HttpGet]
[ResponseType(typeof(WorkOrderModel))]
public IHttpActionResult GetWorkOrderDEBUG()
{
const string id = "1000";
var client = new RestClient(Constants.ODATA_WEBSERVICEDOMAIN)
{
// Authentication needed when querying ODATA
Authenticator = new NtlmAuthenticator()
};
var request = new RestRequest(Constants.ODATA_WEBSERVICE_PATH + "(" + id + ")", Method.GET);
// add http header or request to remove odata metadata
request.AddHeader("Accept", "application/json; odata.metadata=none");
request.RequestFormat = DataFormat.Json;
// Logging for debugging after deployment
log.Debug("CURRENT IDENTITY: " + Environment.UserName);
log.Debug("CURRENT OTHER IDENTITY: " + System.Security.Principal.WindowsIdentity.GetCurrent().Name);
log.Debug("CURRENT MAYBE IDENTITY: " + GetUser());
log.Debug("BaseUrl Path and Query: " + client.BaseUrl.PathAndQuery.ToString());
log.Debug("Authenticator: " + client.Authenticator.ToString());
log.Debug("Request Format: " + request.RequestFormat.ToString());
log.Debug("Resource: " + request.Resource.ToString());
// RestSharp execute request
var response = client.Execute(request);
// Logging for debugging after deployment
if (response.ErrorMessage != null)
{
log.Debug("ErrorMessage: " + response.ErrorMessage.ToString());
}
if (response.ErrorException != null)
{
log.Debug("ErrorException.Message: " + response.ErrorException.Message.ToString());
if (response.ErrorException.InnerException != null)
{
log.Debug("InnerException.Message: " + response.ErrorException.InnerException.Message.ToString());
}
}
if (response.Content != null)
{
log.Debug("Content: " + response.Content.ToString());
}
log.Debug("ContentType: " + response.ContentType.ToString());
//log.Debug("Headers: " + response.Headers.ToString());
//log.Debug("Request: " + response.Request.ToString());
log.Debug("ResponseStatus: " + response.ResponseStatus.ToString());
log.Debug("ResponseURI-Path and Query: " + response.ResponseUri.PathAndQuery.ToString());
log.Debug("ResponseURI-OriginalString: " + response.ResponseUri.OriginalString.ToString());
log.Debug("ResponseURI-Segments: " + response.ResponseUri.Segments.ToString());
log.Debug("Server: " + response.Server.ToString());
log.Debug("Status Code: " + response.StatusCode.ToString());
log.Debug("Status Description: " + response.StatusDescription.ToString());
var content = response.Content;
//if (content != null)
//{
// log.Debug(content.ToString());
//}
var workOrder = JsonConvert.DeserializeObject<WorkOrderModel>(content);
log.Debug(workOrder.ToString());
return Ok(workOrder);
}``
这是我的网络配置:
<system.web>
<authentication mode="Windows" />
<authorization>
<allow users="*" />
<deny users="?" />
</authorization>
<identity impersonate="true" />
<customErrors mode="Off" />
<compilation debug="true" targetFramework="4.6.1" />
<httpRuntime targetFramework="4.6.1" />
<httpModules>
<add name="ErrorLog" type="Elmah.ErrorLogModule, Elmah" />
<add name="ErrorMail" type="Elmah.ErrorMailModule, Elmah" />
<add name="ErrorFilter" type="Elmah.ErrorFilterModule, Elmah" />
</httpModules>
</system.web>
<system.webServer>
<validation validateIntegratedModeConfiguration="false" />
我认为 webservice/server/controller/method 路径是可以的,因为它们在直接查询Application 1的 Odata Web API Controller 时工作正常,而它在我的本地机器上使用 Telerik Fiddler 或 SwaggerUI 在服务器/IIS 上运行,所以我不关心那里...
以下是一些错误日志:
DEBUG 2019-11-15 17:00:56,786 1397487ms
Controller GetWorkOrder - CURRENT IDENTITY: myid123
DEBUG 2019-11-15 17:00:56,786 1397487ms Controller GetWorkOrder - CURRENT OTHER IDENTITY: MBULOGIN\myid123
DEBUG 2019-11-15 17:00:56,786 1397487ms Controller GetWorkOrder - BaseUrl Path and Query: /app/odata/
DEBUG 2019-11-15 17:00:56,786 1397487ms Controller GetWorkOrder - Authenticator: RestSharp.Authenticators.NtlmAuthenticator
DEBUG 2019-11-15 17:00:56,786 1397487ms Controller GetWorkOrder - Default Parameters:System.Collections.Generic.List`1[RestSharp.Parameter]
DEBUG 2019-11-15 17:00:56,786 1397487ms Controller GetWorkOrder - Parameters: System.Collections.Generic.List`1[RestSharp.Parameter]
DEBUG 2019-11-15 17:00:56,786 1397487ms Controller GetWorkOrder - Request Format: Json
DEBUG 2019-11-15 17:00:56,786 1397487ms Controller GetWorkOrder - Resource: WorkOrders(100000)
DEBUG 2019-11-15 17:00:56,802 1397503ms Controller GetWorkOrder - Content: <!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>
DEBUG 2019-11-15 17:00:56,802 1397503ms Controller GetWorkOrder - ContentType: text/html
DEBUG 2019-11-15 17:00:56,802 1397503ms Controller GetWorkOrder - Headers: System.Collections.Generic.List`1[RestSharp.Parameter]
DEBUG 2019-11-15 17:00:56,802 1397503ms Controller GetWorkOrder - Request: RestSharp.RestRequest
DEBUG 2019-11-15 17:00:56,802 1397503ms Controller GetWorkOrder - ResponseStatus: Completed
DEBUG 2019-11-15 17:00:56,802 1397503ms Controller GetWorkOrder - ResponseURI-Path and Query: /app/odata/WorkOrders(1000000)
DEBUG 2019-11-15 17:00:56,802 1397503ms Controller GetWorkOrder - ResponseURI-OriginalString: https://example.com/app/odata/WorkOrders(1000000)
DEBUG 2019-11-15 17:00:56,802 1397503ms Controller GetWorkOrder - ResponseURI-Segments: System.String[]
DEBUG 2019-11-15 17:00:56,802 1397503ms Controller GetWorkOrder - Server: Microsoft-IIS/8.5
DEBUG 2019-11-15 17:00:56,802 1397503ms Controller GetWorkOrder - Status Code: Unauthorized
DEBUG 2019-11-15 17:00:56,802 1397503ms Controller GetWorkOrder - Status Description: Unauthorized
在不模拟发送 GET 请求时,来自 log4net 的错误日志与上述相同,只是身份更改为 AppPool 的身份。
我不明白从 IIS 到Application 1的 Odata Web Api 控制器的请求与从我在 IIS express 中运行该应用程序的机器本地发出的请求相比有什么不同,在使用模拟之后更是如此。一旦被模拟,在本地运行没有问题的同一帐户是“未经授权的”。
我在 IIS GUI 中检查了应用程序的授权策略,两个 IIS 实例都允许 Windows Auth。
这是服务器/IIS 设置吗?如果是这样,适用于哪个应用程序?我真的不确定还有什么要调查的,与我的本地计算机相比,似乎有某种信息与来自应用程序 2的 GET 请求一起发送,当它来自 IIS 时,触发请求未被授权。 ..但它可能是什么?
解决方案
推荐阅读
- delphi - 德尔福 & 印地 & utf8
- c++ - N-API 包含一个 .so 或 dll
- wordpress - 如何在shopify中添加前端产品页面图片上传和注释文本区域框
- c++ - substr 无缘无故地切断了部分字符串。或者至少原因让我无法理解
- java - 简单的 JAVA 问题。但对我来说很难
- python - 如何将文本(url)从树莓派远程传输到我的笔记本电脑
- arrays - 无法读取未定义的属性“unshift”
- python - Python:实例方法绑定如何在内存中发生
- javascript - Angular 6 Module - 角度未定义
- typescript - 不能将 pouchdb 与 Typescript 一起使用?类型问题?