我在SharePoint 2013网站中托管了服务堆栈服务。尝试向其中一个服务发出跨域请求时,会按预期进行预检OPTIONS
请求。
问题是响应总是以401 Unauthorized
的形式返回,因为身份验证信息不会随请求一起发送。我已经尝试通过servicestack放置一些请求过滤器来尝试绕过身份验证,但这些过滤器没有触发 - 似乎服务堆栈之前发送响应的东西。
是否有任何方法可以指定不需要对sharepoint站点的OPTIONS
个请求进行身份验证?如果没有,有没有人有这种情况的解决方法?
我试过愚弄'浏览器通过在我的ajax请求中将数据类型从application/json
更改为text/plain
来不发送预检请求,但是我发送的数据未被反序列化为正确的RequestDTO用于服务调用在服务器端。
任何帮助都将不胜感激。
答案 0 :(得分:3)
我们最终必须编写自己的HTTP模块才能支持选项请求。我们基本上添加一个键,指定允许CORS请求的域(可以支持多个),然后注册此HTTP模块:
public class ECSPreFlightModule : IHttpModule
{
/// <summary>
/// You will need to configure this module in the Web.config file of your
/// web and register it with IIS before being able to use it. For more information
/// see the following link: http://go.microsoft.com/?linkid=8101007
/// </summary>
public void Dispose()
{
//clean-up code here.
}
private const string OptionsHeader = "OPTIONS";
private const string OriginHeader = "ORIGIN";
private const string AccessAllowOrigin = "Access-Control-Allow-Origin";
private string AllowedOriginUrlsArray
{
get
{
return GetWebConfigValue("CORSAllowedOriginUrls");
}
}
private string GetWebConfigValue(string key)
{
var configuration = WebConfigurationManager.OpenWebConfiguration("~");
object o = configuration.GetSection("system.web/httpModules");
var section = o as HttpModulesSection;
return section.CurrentConfiguration.AppSettings.Settings[key].Value;
}
public void Init(HttpApplication context)
{
context.PreSendRequestHeaders += (sender, e) =>
{
var splitUrls = AllowedOriginUrlsArray.Split('|');
var response = context.Response;
var originHeader = context.Request.Headers.Get(OriginHeader);
if (!String.IsNullOrEmpty(originHeader) && splitUrls.Length > 0)
{
foreach (var url in splitUrls)
{
var urlLower = url.ToLower();
var originHeaderLower = originHeader.ToLower();
// if the method being requested is an OPTIONS request and the url is the url specified in the web.config then return an OK response.
if (context.Request.HttpMethod.ToLowerInvariant() == OptionsHeader.ToLowerInvariant() &&
(urlLower == originHeaderLower))
{
response.StatusCode = (int)HttpStatusCode.OK;
}
// If the originating header url is equal to the url specified in the web.config then grant the access control
if (originHeaderLower == urlLower)
{
response.AddHeader(AccessAllowOrigin, originHeader);
break;
}
}
}
};
}
}
}
上述模块包含在一个sharepoint功能中,该功能在激活后对web.config进行了相应的更改,即注册模块并添加以下键:
<add name='Access-Control-Allow-Credentials' value='true' />
<add name='Access-Control-Allow-Headers' value='Authorization, X-Requested-With, Content-Type, Origin, Accept, X-RequestDigest' />
<add name='Access-Control-Allow-Methods' value='GET,POST,OPTIONS,PUT, DELETE' />