【问题标题】:Consuming custom REST service hosted inside Sharepoint 2010 with Windows Authentication使用带有 Windows 身份验证的 Sharepoint 2010 中托管的自定义 REST 服务
【发布时间】:2012-12-25 11:16:36
【问题描述】:

在使用 Windows 身份验证的 Sharepoint 2010 应用程序中托管了此自定义 WCF REST 服务。

我需要在 .NET 项目(即控制台项目)中使用此服务,但凭证让我抓狂。我收到很多 400 - bad request401 - unauthorized 回复(取决于我是否包含一些身份验证)。

让我举个例子:

siteUri 是 SP 站点(根/主页)的 url,methodUri 是返回 XML 的服务方法的 url。

同样,此站点已通过 Windows 身份验证。如果我打开浏览器并转到methodUri,我会得到:

请求错误

服务器在处理请求时遇到错误。见服务器 日志以获取更多详细信息。

但是,如果我转到 siteUri,Sharepoint 主页会加载,然后我可以再次浏览到 methodUri,现在我可以正确获得 XML 响应。

因此,似乎浏览到主页会存储一些 cookie,然后在向 web 方法发出请求时使用这些 cookie。检查 Fiddler 中的请求我可以确认这一点:

第一个 methodUri 请求失败并显示 400 代码,并且请求标头中没有任何 Cookie。然后,当我浏览主页 (siteUri) 时,有一些请求/响应似乎是身份验证本身。响应头包括:

WWW-Authenticate: Negotiate oRswGaADCgEAoxIEEAEAAABDh+CIwTbjqQAAAAA=
Set-Cookie: WSS_KeepSessionAuthenticated={b89d78b2-063d-4ac4-810e-bde4e04a829e}; path=/
Persistent-Auth: true

最后,当再次浏览到methodUri 时,第一个响应是 401 - 未经授权,但之后有另一个请求包含此标头

Cookie: WSS_KeepSessionAuthenticated={b89d78b2-063d-4ac4-810e-bde4e04a829e}
Authorization: Negotiate oXcwdaADCgEBoloEWE5UTE1TU1AAAwAAAAAAAABYAAAAAAAAAFgAAAAAAAAAWAAAAAAAAABYAAAAAAAAAFgAAAAAAAAAWAAAABXCiOIGAbEdAAAAD37/i76Dl3jNyK8bIRz57fmjEgQQAQAAAPUXp1AtIpqEAAAAAA==

最终被接受,服务以相应的 XML 响应。

所以浏览器足够聪明,可以处理这种来回的请求/响应来验证当前的 windows 用户。

我的问题是,如何在 .NET(3.5 或 4)中执行此操作,但不使用默认凭据,我需要指定用户名、密码和域。

我花了 5 天时间处理这个问题,我可以使用 HttpWebRequest 中的默认网络凭据使其工作,但是当我手动设置凭据时(使用与当前登录用户相同的凭据)它不起作用。

我只是觉得这整个事情过于复杂了(感谢微软),因为我来自开源(ruby、python)背景,而且这类事情很简单。

希望我很清楚,如果您需要任何额外信息,请询问。我愿意为此付出我的全部名誉。

谢谢

【问题讨论】:

  • 您能否发布一些有关如何设置客户端的代码?

标签: .net sharepoint-2010 httpwebrequest windows-authentication wcf-rest


【解决方案1】:

嗯,我已经修好了。

这是我最终使用的代码。感谢 Microsoft 让事情变得如此简单且解释清楚。

var siteUri = @"http://sharepoint-site-uri";
var methodUri = @"http://sharepoint-site-uri/namespace/service/method";
string responseXml = null;

var request = (HttpWebRequest)WebRequest.Create(siteUri);
var cc = new CredentialCache { { new Uri(siteUri), "NTLM", new NetworkCredential("user", "pwd", "domain") } };
request.Credentials = cc;

try
{
    // first site request
    var response = (HttpWebResponse)request.GetResponse();
    if (response.StatusCode == HttpStatusCode.OK)
    {
        request = (HttpWebRequest)WebRequest.Create(uri);
        request.CookieContainer = new CookieContainer();

        // copy the authentication cookies from the response
        foreach (Cookie c in response.Cookies)
        {
            request.CookieContainer.Add(c);
        }

        request.ContentType = "application/xml; charset=utf-8";

        // second request, now against the service url
        using (var reader = new StreamReader(request.GetResponse().GetResponseStream()))
        {
            // get the response text
            responseXml = reader.ReadToEnd();
        }
    }
}
catch (Exception e)
{       
   // handle error
}

【讨论】:

    猜你喜欢
    • 2011-06-24
    • 2016-02-15
    • 2011-07-05
    • 1970-01-01
    • 2011-01-13
    • 2011-07-21
    • 1970-01-01
    • 1970-01-01
    • 2019-05-19
    相关资源
    最近更新 更多