我在尝试使用当前用户凭据调用自身时在IIS上的MVC4中获取经过身份验证的响应时出现问题。
我使用下面的代码。它只是使用其on的端口创建一个返回本地服务器的请求以返回给定页面。注意,更改' localhost'到HttpContext.Request.Url.Host
没有任何区别。
在Dev Server上的本地计算机上,这可行。 在使用IIS的本地计算机上,它没有,我得到401:未经授权。
在IIS上,我在web.config中有<authentication mode="Windows" />
和<identity impersonate="true" />
的基本身份验证和ASP.Net模拟。它的配置是这样的,以确保SQL Server(位于不同的计算机上)可以正确验证。
由于服务器自称,我不相信这是双跳问题吗?
有没有人对如何使用当前用户身份验证获取对服务器进行身份验证的请求有任何建议?
[Authorize]
public ActionResult GetTest()
{
try
{
string urlAddress = string.Format("http://{0}:{1}/{2}", "localhost", HttpContext.Request.Url.Port, "api/diagnostic/get");
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(urlAddress);
request.Proxy = null; // Important! Stops the object searching for settings that cause a big slowdown.
request.Credentials = CredentialCache.DefaultCredentials;
request.PreAuthenticate = true;
using (HttpWebResponse response = (HttpWebResponse)request.GetResponse())
{
if (response.StatusCode == HttpStatusCode.OK)
{
using (Stream receiveStream = response.GetResponseStream())
{
if (receiveStream == null)
{
throw new Exception("ReceiveStream is null.");
}
StreamReader readStream = response.CharacterSet == null
? new StreamReader(receiveStream)
: new StreamReader(receiveStream, Encoding.GetEncoding(response.CharacterSet));
string data = readStream.ReadToEnd();
response.Close();
readStream.Close();
return Content(data);
}
}
}
return Content("Error");
}
catch (Exception e)
{
return Content(e.Message);
}
}
答案 0 :(得分:0)
您可能需要将验证集成模式配置设置为false。
<system.webServer>
<validation validateIntegratedModeConfiguration="false" />
有关原因的解释,请参阅此文章: https://knpuniversity.com/search?q=restful
答案 1 :(得分:0)
由于授权不想工作,我不得不解决它。当我从同一台服务器请求数据时,我不需要创建HttpRequest,我可以直接访问控制器。
显然它比简单的WebRequest更复杂,但它确实带来了返回类型正是控制器返回的优点。
参数的处理可能不完整,但它对我有用。
var httpContext =
new HttpContextWrapper(
new HttpContext(
new HttpRequest(null, "http://servername/api/diagnostic/get", // interestingly the actual servername is not required.
"parameter=1¶meter2=foo"),
new HttpResponse(new StringWriter())));
var routeData = RouteTable.Routes.GetRouteData(httpContext);
var req = new RequestContext(httpContext, routeData);
var controller =
(ControllerBase)
ControllerBuilder.Current.GetControllerFactory()
.CreateController(new RequestContext(httpContext, routeData), routeData.Values["controller"].ToString());
var context = new ControllerContext(req, controller);
controller.ControllerContext = context;
var desc = new ReflectedControllerDescriptor(controller.GetType());
var action = desc.FindAction(context, routeData.Values["action"].ToString());
var queryString = httpContext.Request.QueryString;
var parameters = action.GetParameters()
.ToDictionary(p => p.ParameterName,
p =>
p.ParameterType.IsEnum
? Enum.ToObject(p.ParameterType, Convert.ChangeType(queryString.GetValues(p.ParameterName)[0], TypeCode.Int32))
: Convert.ChangeType(queryString.GetValues(p.ParameterName)[0], p.ParameterType));
var result = action.Execute(context, parameters);