SharePoint OPTIONS预检请求

时间:2014-11-19 00:58:19

标签: sharepoint servicestack cors sharepoint-2013

我在SharePoint 2013网站中托管了服务堆栈服务。尝试向其中一个服务发出跨域请求时,会按预期进行预检OPTIONS请求。

问题是响应总是以401 Unauthorized的形式返回,因为身份验证信息不会随请求一起发送。我已经尝试通过servicestack放置一些请求过滤器来尝试绕过身份验证,但这些过滤器没有触发 - 似乎服务堆栈之前发送响应的东西。

是否有任何方法可以指定不需要对sharepoint站点的OPTIONS个请求进行身份验证?如果没有,有没有人有这种情况的解决方法?

我试过愚弄'浏览器通过在我的ajax请求中将数据类型从application/json更改为text/plain来不发送预检请求,但是我发送的数据未被反序列化为正确的RequestDTO用于服务调用在服务器端。

任何帮助都将不胜感激。

1 个答案:

答案 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' />