【问题标题】:New-WebServiceProxy failing to authenticate with NTLMNew-WebServiceProxy 无法通过 NTLM 进行身份验证
【发布时间】:2015-03-14 14:01:21
【问题描述】:

我正在处理一个相当特殊的问题。我们需要访问我们的 SharePoint 场上的 Lists 服务。 Web 身份验证通过 Oracle SSO 联合,但我们确实配置了可以执行 Web 请求的自动化帐户。使用 AAM,我们为服务器端自动化配置了一个“内部”URL,该 URL 直接绕过 AD,其他所有内容都被推送到 SSO。

这是我用来尝试获取列表集合的代码(已清理)。

$username = "DOMAIN\username"
$password = "somepassword"
$site = "https://sp.biz.com/sites/SiteCollection"

$credentials = New-Object -TypeName System.Management.Automation.PSCredential -ArgumentList $username, (ConvertTo-SecureString $password -AsPlainText -Force)

$proxy = New-WebServiceProxy -Uri "$site/_vti_bin/Lists.asmx" -Credentials $credentials

$proxy.GetListCollection()

我在使用该代码时遇到 403。

使用“0”参数调用“GetListCollection”的异常:“服务器无法处理请求。---> 访问被拒绝。(来自 HRESULT 的异常:0x80070005 (E_ACCESSDENIED))”

如果我将 $site 更改为使用内部 URL(通过 AAM 设置)并在其中一个前端运行它,我会成功收到列表集合。现在,起初我认为帐户和权限存在问题,但在运行 Fiddler 捕获后,我发现它根本没有进行身份验证。

当我运行以下 cURL 命令时,它会验证并返回列表集合。 Soap.xml 只是直接从 WDSL 复制的基本 GetListCollection 数据包。

curl -v -u 'username':'pass' --ntlm -X POST -H "Content-Type: text/xml" --data-binary @soap.xml https://sp.biz.com/sites/SiteCollection/_vti_bin/Lists.asmx

这是来自 cURL 的经过净化的详细输出。

* STATE: INIT => CONNECT handle 0x600056190; line 1029 (connection #-5000)
* Hostname was NOT found in DNS cache
*   Trying <IPv6>...
* STATE: CONNECT => WAITCONNECT handle 0x600056190; line 1082 (connection #0)
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
  0     0    0     0    0     0      0      0 --:--:-- --:--:-- --:--:--     0* Connected to sp.biz.com (<IPv6>) port 443 (#0)
* successfully set certificate verify locations:
*   CAfile: /usr/ssl/certs/ca-bundle.crt
  CApath: none
* SSLv3, TLS handshake, Client hello (1):
} [data not shown]
* STATE: WAITCONNECT => PROTOCONNECT handle 0x600056190; line 1222 (connection #0)
* SSLv3, TLS handshake, Server hello (2):
{ [data not shown]
* SSLv3, TLS handshake, CERT (11):
{ [data not shown]
* SSLv3, TLS handshake, Server finished (14):
{ [data not shown]
* SSLv3, TLS handshake, Client key exchange (16):
} [data not shown]
* SSLv3, TLS change cipher, Client hello (1):
} [data not shown]
* SSLv3, TLS handshake, Finished (20):
} [data not shown]
* SSLv3, TLS change cipher, Client hello (1):
{ [data not shown]
* SSLv3, TLS handshake, Finished (20):
{ [data not shown]
* SSL connection using TLSv1.2 / DES-CBC3-SHA
*        SSL certificate verify ok.
* STATE: PROTOCONNECT => DO handle 0x600056190; line 1241 (connection #0)
* Server auth using NTLM with user 'DOMAIN\username'
> POST /sites/SiteCollection/_vti_bin/Lists.asmx HTTP/1.1
> Authorization: NTLM <snip>
> User-Agent: curl/7.39.0
> Host: sp.biz.com
> Accept: */*
> Content-Type: text/xml
> Content-Length: 0
>
* STATE: DO => DO_DONE handle 0x600056190; line 1314 (connection #0)
* STATE: DO_DONE => WAITPERFORM handle 0x600056190; line 1441 (connection #0)
* STATE: WAITPERFORM => PERFORM handle 0x600056190; line 1454 (connection #0)
* HTTP 1.1 or later with persistent connection, pipelining supported
< HTTP/1.1 401 Unauthorized
* Server Microsoft-IIS/7.5 is not blacklisted
< Server: Microsoft-IIS/7.5
< SPRequestGuid: <snip>
< WWW-Authenticate: NTLM <snip>
< X-Powered-By: ASP.NET
< MicrosoftSharePointTeamServices: 14.0.0.7006
< X-MS-InvokeApp: 1; RequireReadOnly
< Date: Fri, 16 Jan 2015 01:02:56 GMT
< Content-Length: 0
< Set-Cookie: BIGipServerserver_pool=<snip>; expires=Sat, 17-Jan-2015 01:02:56 GMT; path=/
<
  0     0    0     0    0     0      0      0 --:--:-- --:--:-- --:--:--     0
* Connection #0 to host sp.biz.com left intact
* Issue another request to this URL: 'https://sp.biz.com/sites/SiteCollection/_vti_bin/Lists.asmx'
* STATE: PERFORM => CONNECT handle 0x600056190; line 1601 (connection #-5000)
* Found bundle for host sp.biz.com: 0x60006aef0
* Re-using existing connection! (#0) with host sp.biz.com
* Connected to sp.biz.com (<IPv6>) port 443 (#0)
* STATE: CONNECT => DO handle 0x600056190; line 1075 (connection #0)
* Server auth using NTLM with user 'DOMAIN\username'
> POST /sites/SiteCollection/_vti_bin/Lists.asmx HTTP/1.1
> Authorization: NTLM <snip>
> User-Agent: curl/7.39.0
> Host: sp.biz.com
> Accept: */*
> Content-Type: text/xml
> Content-Length: 353
>
} [data not shown]
* upload completely sent off: 353 out of 353 bytes
* STATE: DO => DO_DONE handle 0x600056190; line 1314 (connection #0)
* STATE: DO_DONE => WAITPERFORM handle 0x600056190; line 1441 (connection #0)
* STATE: WAITPERFORM => PERFORM handle 0x600056190; line 1454 (connection #0)
* HTTP 1.1 or later with persistent connection, pipelining supported
< HTTP/1.1 200 OK
< Cache-Control: private, max-age=0
< Content-Type: text/xml; charset=utf-8
* Server Microsoft-IIS/7.5 is not blacklisted
< Server: Microsoft-IIS/7.5
< SPRequestGuid: <snip>
< Set-Cookie: FedAuth=<snip>; expires=Fri, 16-Jan-2015 08:36:07 GMT; path=/; secure; HttpOnly
< X-SharePointHealthScore: 0
< X-AspNet-Version: 2.0.50727
< Persistent-Auth: true
< X-Powered-By: ASP.NET
< MicrosoftSharePointTeamServices: 14.0.0.7006
< X-MS-InvokeApp: 1; RequireReadOnly
< Date: Fri, 16 Jan 2015 01:02:56 GMT
< Content-Length: 104088
< Vary: Accept-Encoding
<
{ [data not shown]
* STATE: PERFORM => DONE handle 0x600056190; line 1626 (connection #0)
100  101k  100  101k  100   353   219k    762 --:--:-- --:--:-- --:--:--  219k
* Connection #0 to host sp.biz.com left intact

非常感谢任何帮助。如果缺少 cmdlet,我不反对基于 PowerShell 的 C# 解决方案。


2015 年 1 月 16 日下午 12:13 东部标准时间更新 - 我更新了问题以反映 HighlyUnavailable 的建议,并包含 Fiddler 捕获的标题。

以下是 PowerShell 脚本中经过清理的标头:

CONNECT sp.biz.com:443 HTTP/1.1
Host: sp.biz.com
Connection: Keep-Alive
HTTP/1.1 200 Connection Established
FiddlerGateway: Direct
StartTime: 12:14:46.372
Connection: close
------------------------------------------------------------------
GET https://sp.biz.com/sites/SiteCollection/_vti_bin/Lists.asmx HTTP/1.1
User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; MS Web Services Client Protocol 2.0.50727.5485)
Host: sp.biz.com
Connection: Keep-Alive
HTTP/1.1 200 OK
Cache-Control: private, max-age=0
Content-Type: text/html; charset=utf-8
Server: Microsoft-IIS/7.5
SPRequestGuid: <snip>
X-SharePointHealthScore: 0
X-AspNet-Version: 2.0.50727
X-Powered-By: ASP.NET
MicrosoftSharePointTeamServices: 14.0.0.7006
X-MS-InvokeApp: 1; RequireReadOnly
Date: Fri, 16 Jan 2015 17:14:46 GMT
Connection: keep-alive
Content-Length: 9066
Set-Cookie: BIGipServerserver_pool=<snip>; expires=Sat, 17-Jan-2015 17:14:46 GMT; path=/
Vary: Accept-Encoding
------------------------------------------------------------------
GET https://sp.biz.com/_vti_bin/Lists.asmx?disco HTTP/1.1
User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; MS Web Services Client Protocol 2.0.50727.5485)
Host: sp.biz.com
HTTP/1.1 200 OK
Cache-Control: private
Content-Type: text/xml; charset=utf-8
Server: Microsoft-IIS/7.5
SPRequestGuid: <snip>
X-SharePointHealthScore: 0
X-AspNet-Version: 2.0.50727
X-Powered-By: ASP.NET
MicrosoftSharePointTeamServices: 14.0.0.7006
X-MS-InvokeApp: 1; RequireReadOnly
Date: Fri, 16 Jan 2015 17:14:46 GMT
Connection: close
Content-Length: 747
------------------------------------------------------------------
CONNECT sp.biz.com:443 HTTP/1.1
Host: sp.biz.com
Connection: Keep-Alive
HTTP/1.1 200 Connection Established
FiddlerGateway: Direct
StartTime: 12:14:47.505
Connection: close
------------------------------------------------------------------
GET https://sp.biz.com/_vti_bin/Lists.asmx?wsdl HTTP/1.1
User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; MS Web Services Client Protocol 2.0.50727.5485)
Host: sp.biz.com
HTTP/1.1 200 OK
Cache-Control: private
Content-Type: text/xml; charset=utf-8
Server: Microsoft-IIS/7.5
SPRequestGuid: <snip>
X-SharePointHealthScore: 0
X-AspNet-Version: 2.0.50727
X-Powered-By: ASP.NET
MicrosoftSharePointTeamServices: 14.0.0.7006
X-MS-InvokeApp: 1; RequireReadOnly
Date: Fri, 16 Jan 2015 17:14:46 GMT
Connection: close
Content-Length: 72672
Set-Cookie: BIGipServerserver_pool=<snip>; expires=Sat, 17-Jan-2015 17:14:47 GMT; path=/
Vary: Accept-Encoding
------------------------------------------------------------------
CONNECT sp.biz.com:443 HTTP/1.1
Host: sp.biz.com
Connection: Keep-Alive
HTTP/1.1 200 Connection Established
FiddlerGateway: Direct
StartTime: 12:14:48.727
Connection: close
------------------------------------------------------------------
POST https://sp.biz.com/_vti_bin/Lists.asmx HTTP/1.1
User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; MS Web Services Client Protocol 2.0.50727.5485)
Content-Type: text/xml; charset=utf-8
SOAPAction: "http://schemas.microsoft.com/sharepoint/soap/GetListCollection"
Host: sp.biz.com
Content-Length: 321
Expect: 100-continue
HTTP/1.1 500 Internal Server Error
Cache-Control: private
Content-Type: text/xml; charset=utf-8
Server: Microsoft-IIS/7.5
X-AspNet-Version: 2.0.50727
X-Powered-By: ASP.NET
MicrosoftSharePointTeamServices: 14.0.0.7006
X-MS-InvokeApp: 1; RequireReadOnly
Date: Fri, 16 Jan 2015 17:14:48 GMT
Content-Length: 459
Set-Cookie: BIGipServerserver_pool=686493706.47873.0000; expires=Sat, 17-Jan-2015 17:14:48 GMT; path=/
------------------------------------------------------------------

这里是 cURL 命令的标头。

CONNECT sp.biz.com:443 HTTP/1.1
Host: sp.biz.com:443
User-Agent: curl/7.39.0
Connection: Keep-Alive
Content-Type: text/xml
HTTP/1.1 200 Connection Established
FiddlerGateway: Direct
StartTime: 12:21:07.928
Connection: close
------------------------------------------------------------------
POST https://sp.biz.com/sites/SiteCollection/_vti_bin/Lists.asmx HTTP/1.1
Authorization: NTLM <snip>=
User-Agent: curl/7.39.0
Host: sp.biz.com
Accept: */*
Content-Type: text/xml
Content-Length: 0
HTTP/1.1 401 Unauthorized
Server: Microsoft-IIS/7.5
SPRequestGuid: <snip>
WWW-Authenticate: NTLM <snip>
X-Powered-By: ASP.NET
MicrosoftSharePointTeamServices: 14.0.0.7006
X-MS-InvokeApp: 1; RequireReadOnly
Date: Fri, 16 Jan 2015 17:21:07 GMT
Content-Length: 0
Set-Cookie: BIGipServerserver_pool=<snip>; expires=Sat, 17-Jan-2015 17:21:07 GMT; path=/
Proxy-Support: Session-Based-Authentication
------------------------------------------------------------------
POST https://sp.biz.com/sites/SiteCollection/_vti_bin/Lists.asmx HTTP/1.1
Authorization: NTLM <snip>
User-Agent: curl/7.39.0
Host: sp.biz.com
Accept: */*
Content-Type: text/xml
Content-Length: 417
HTTP/1.1 200 OK
Cache-Control: private, max-age=0
Content-Type: text/xml; charset=utf-8
Server: Microsoft-IIS/7.5
SPRequestGuid: <snip>
Set-Cookie: FedAuth=<snip>; expires=Sat, 17-Jan-2015 03:20:50 GMT; path=/; secure; HttpOnly
X-SharePointHealthScore: 0
X-AspNet-Version: 2.0.50727
Persistent-Auth: true
X-Powered-By: ASP.NET
MicrosoftSharePointTeamServices: 14.0.0.7006
X-MS-InvokeApp: 1; RequireReadOnly
Date: Fri, 16 Jan 2015 17:21:07 GMT
Content-Length: 66628
Vary: Accept-Encoding
------------------------------------------------------------------

【问题讨论】:

    标签: powershell sharepoint


    【解决方案1】:

    您在这里混合了两种完全不同的技术。

    $proxy = New-WebServiceProxy -Uri "$site/_vti_bin/Lists.asmx" -UseDefaultCredential $proxy.PreAuthenticate = $TRUE $proxy.Credentials = $credentials

    UseDefaultCredential 将尝试将您当前登录的 Windows 域用户传递给该站点。但是,您也在设置凭据。通常,您会使用-Credential $credentials(参见http://technet.microsoft.com/en-us/library/hh849841.aspx

    您正在运行的 curl 命令更类似于使用 -Credential-u 是等效的。

    尝试改用$proxy = New-WebServiceProxy -Uri "$site/_vti_bin/Lists.asmx" -Credential $credentials 之类的东西。

    如果这不起作用,请编辑您的问题以包含从 Oracle SSO 连接返回的标头 - 可能是它甚至根本不要求提供凭据。

    【讨论】:

    • 感谢您的意见。我尝试了几种不同的组合,但它们似乎都不起作用。我最初的理解是,通过将-UseDefaultCredentials 放在那里,它将对第一次调用进行匿名访问,直到它获得身份验证挑战。我还在原始主题中添加了 cURL 和 PowerShell 的请求标头。
    • @TaylorB 这可能会也可能不会帮助您,但curl -u 将在第一次通话时发送凭据。 Powershell 可能不会,并且会在发送凭据之前等待 401。我wrote about this in regard to Invoke-WebRequest 但建立连接的底层代码可能与New-WebServiceProxy 相同。
    【解决方案2】:

    我从来没有为此想出解决方案,但我可以解释原因。在我们的环境中,我们针对带有 SAML v1.1 的 Oracle Identity Foundation SSO 使用基于表单的身份验证。

    当您尝试进行身份验证时,它会将您重定向到 SSO,但客户端正在尝试针对实际 Web 前端而不是 SSO 使用 NTLM。要完成这项工作,您需要在请求中包含 X-FORMS_BASED_AUTH_ACCEPTED: f 标头,以便它使用 NTLM 针对 WFE(而不是 SSO)实际进行身份验证。

    这是问题所在:您无法在 PowerShell 中将标头添加到 New-WebServiceProxy(最高 4.0 - 我还没有推出 5)。我可以为其他有问题的人提出的唯一建议是遵循 HighUnavailable 的建议,或者使用 Invoke-WebRequest 并手动构建您的 SOAP 调用。

    唯一的问题是 Invoke-WebRequest 可能会破坏您的编码,所以这是我解决它的方法。如果有人有解决编码问题的建议,我会全力以赴。

    # Set your credentials here.
    $UserName = 'BartSimpson'
    $Password = '3atmMySh0rtz!'
    $Domain   = 'SF'
    $SecurePassword = ConvertTo-SecureString -String $Password -AsPlainText -Force
    $Credentials = New-Object System.Management.Automation.PSCredential (($Domain + "\" + $UserName), $SecurePassword)
    
    # SOAP request headers and body
    $BaseHeaders = @{"X-FORMS_BASED_AUTH_ACCEPTED" = 'f';
                     "SOAPAction" = "`"http://schemas.microsoft.com/sharepoint/soap/GetListCollection`"";
                     "Content-Type" = "text/xml; charset=utf-8"}
    $SOAP = @"
    <?xml version="1.0" encoding="utf-8"?>
    <soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
      <soap:Body>
        <GetListCollection xmlns="http://schemas.microsoft.com/sharepoint/soap/" />
      </soap:Body>
    </soap:Envelope>
    "@
    # Gives us a random temp file to pipe output to
    $TmpFile = [System.IO.Path]::GetTempFileName()
    Invoke-WebRequest -Uri $URL -Headers $BaseHeaders -Credential $Credentials -Method POST -Body $SOAP -OutFile $TmpFile
    # Get the outfile with UTF8 encoding
    [xml]$Result = Get-Content -Raw -Path $TmpFile -Encoding UTF8
    # Remove the temporary file
    Remove-Item $TmpFile
    

    似乎还有很长的路要走,但如果你坚持使用 PowerShell,它就可以工作。

    我切换到python-suds 并且能够做我需要做的事情。

    【讨论】:

      【解决方案3】:

      在上面的代码中,-Credentials 中有额外的“S”。

      所以替换代码:

      $proxy = New-WebServiceProxy -Uri "$site/_vti_bin/Lists.asmx" -Credentials $credentials
      

      下面的代码:

      $proxy = New-WebServiceProxy -Uri "$site/_vti_bin/Lists.asmx" -Credential $credentials
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2018-04-29
        • 1970-01-01
        • 2012-04-01
        • 2014-01-05
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多