Sharepoint Office 365 OAuth服务身份验证到list.asmx

时间:2016-02-19 10:00:05

标签: web-services sharepoint oauth office365

我正在尝试从外部网站访问Office 365中的Sharepoint列表数据。我在Azure Active Directory中注册了我的应用程序,并且我已经完成了创建和信任证书以及获取访问令牌的所有过程。

Add-Type -Path ".\Microsoft.IdentityModel.Clients.ActiveDirectory.dll"

$authenticationContext = New-Object Microsoft.IdentityModel.Clients.ActiveDirectory.AuthenticationContext -ArgumentList "https://login.microsoftonline.com/{myTenantId}/", $false

$cer = New-Object System.Security.Cryptography.X509Certificates.X509Certificate2
$cer.Import(".\WithPrivateKey.pfx", "privateKey", [System.Security.Cryptography.X509Certificates.X509KeyStorageFlags]::MachineKeySet)

$clientAssertion = New-Object Microsoft.IdentityModel.Clients.ActiveDirectory.ClientAssertionCertificate -ArgumentList "{myClientId}", $cer

$authenticationResult = $authenticationContext.AcquireToken("https://{tenantName}.sharepoint.com", $clientAssertion)

$headers = New-Object "System.Collections.Generic.Dictionary[[String],[String]]"
$headers.Add("Authorization", "Bearer " + $authenticationResult.AccessToken)

我可以通过在请求标头中显示访问令牌来成功调用Sharepoint REST Api。

$response = Invoke-RestMethod -Uri https://{myTenantName}.sharepoint.com/sites/devSite/_vti_bin/ListData.svc/TestList -Method Get -Headers $headers 

但是,每当我尝试在那些服务上调用任何方法时,我都无法访问asmx端点,例如Lists.asmx,我获得了401 UNAUTHORIZED

$body = '<?xml version="1.0" encoding="utf-8"?>
<soap12:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap12="http://www.w3.org/2003/05/soap-envelope">
  <soap12:Body>
    <GetList xmlns="http://schemas.microsoft.com/sharepoint/soap/">
      <listName>TestList</listName>
    </GetList>
  </soap12:Body>
</soap12:Envelope>'

$response = Invoke-WebRequest -Uri https://{myTenantName}.sharepoint.com/sites/site/_vti_bin/Lists.asmx -Method Post -ContentType 'application/soap+xml' -Headers $headers -Body $body

2 个答案:

答案 0 :(得分:6)

在深入了解.net Sharepoint客户端sdk之后,我发现SharepointOnlineCredential类是如何做到这一点的,从而允许访问Sharepoint SOAP Services。

因此,正如Fei Xue所说,Azure AD令牌无法访问Sharepoint SOAP服务(尽管令牌有效以允许访问REST服务......)。要访问Sharepoint Online服务,您需要使用某种声明身份验证,方法是请求用户同意或直接使用已知用户和密码。

由于我们无法在我们的php应用程序中使用.net SDK,因此我们调查了SDK如何在直接使用用户凭据时创建获得身份验证的请求:

首先将您的身份验证凭据作为SAML-WSSecurity POST请求发送到身份验证端点https://login.microsoftonline.com/rst2.srf

POST https://login.microsoftonline.com/rst2.srf 
Content-Type: application/soap+xml; charset=utf-8
Content-Length: [calculate]
Host: login.microsoftonline.com

<?xml version="1.0" encoding="UTF-8"?>
<S:Envelope xmlns:S="http://www.w3.org/2003/05/soap-envelope" xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" xmlns:wsp="http://schemas.xmlsoap.org/ws/2004/09/policy" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" xmlns:wsa="http://www.w3.org/2005/08/addressing" xmlns:wst="http://schemas.xmlsoap.org/ws/2005/02/trust">
  <S:Header>
    <wsa:Action S:mustUnderstand="1">http://schemas.xmlsoap.org/ws/2005/02/trust/RST/Issue</wsa:Action>
    <wsa:To S:mustUnderstand="1">https://login.microsoftonline.com/rst2.srf</wsa:To>
    <ps:AuthInfo xmlns:ps="http://schemas.microsoft.com/LiveID/SoapServices/v1" Id="PPAuthInfo">
      <ps:BinaryVersion>5</ps:BinaryVersion>
      <ps:HostingApp>Managed IDCRL</ps:HostingApp>
    </ps:AuthInfo>
    <wsse:Security>
            <wsse:UsernameToken wsu:Id="user">
                <wsse:Username>[user]</wsse:Username>
                <wsse:Password>[password]</wsse:Password>
            </wsse:UsernameToken>                
</wsse:Security>
  </S:Header>
  <S:Body>
    <wst:RequestSecurityToken xmlns:wst="http://schemas.xmlsoap.org/ws/2005/02/trust" Id="RST0">
      <wst:RequestType>http://schemas.xmlsoap.org/ws/2005/02/trust/Issue</wst:RequestType>
      <wsp:AppliesTo>
        <wsa:EndpointReference>
          <wsa:Address>sharepoint.com</wsa:Address>
        </wsa:EndpointReference>
      </wsp:AppliesTo>
      <wsp:PolicyReference URI="MBI"></wsp:PolicyReference>
    </wst:RequestSecurityToken>
  </S:Body>
</S:Envelope>

xml格式的响应将附带安全令牌:

....
<wst:RequestedSecurityToken>
    <wsse:BinarySecurityToken Id="Compact0">t=EwA4A06hBwAUNfDkMme61kIdXqvj9tWnUbHtXWEAAREB5clgLb8J/VvxRFIKLUnd9SRyoBHmTHFk0viit2FMlGXak5NJKJhicT8MiZmgA2HoTrJM1EgXCNUpmWqrX1LQRNfs0PHEV4XncjI9lnphsSTiFSCDjmdCKtW4TmV8n18xJHvBtDUWdvCT2lBti8/gf1oiqD5lQBPtxr+d4OwNtJHADEKpC/YIoatcKqgxI480tlWOZHpEL1wifo5EDMDRRc985ObMCZ31fPdSpA7WIbDzlZYX9ou6Cq7EybrIHsAcr5cPIJ8y0FRUacma9+dMxqr/lILAIyAYz/GdTNffa2Q3zJOSWW5RcnigtCApHgf83HjW8DqC6NgTrXs6rpUDZgAACC/4JZlSLB3JCALIntkKmNtRl2JLvwUljkXrP5jg5ipK/J/fGF3oc46aP/YT3VnrrD6TCV5ZECki5ycYZ6JR5RDK6OSqI9c5FDfFS/YmSCcdcaJ1cG2Ug3Oz3w14mznYGwmvrgyGvw35aoyjnKZALw8OQ2Ddi97gbe03L4rrM7CxTGwEPgoKCK7USkwxZT+myLJASVhd29+eNsTqd7wuphhLrzbgYZ+7swlJb3oIJw/2T7YvJ4fTPByaLxGaBt7iry74aSh/RnXdH3snOQnsr63bXqqoDJGcj7A3aIpElw2LlW2/PGh84zke3corp2q/jg7PEKCnV8PYN2xiwSfqY9vNCny14xhHEPsK8FWDBOPDpgeC18qz+FpTN0rGUMXl20bxJGxGqnQ+s8k0Gu9yTxoZKWPSeVihJk6qUQo6KJb/NE/QRco94QDUjMYi+gccGN0D1ouUe+O0fb0InXeM+98qfXJLQAjoUtgS8rRJUAqFk5XVwebGbx0ICRv3Q/wiJ7T5yUryMBTtwbaGf/07QuGTv9CW2UTsV9zT1nMSRDfUpelZrgZt6huLnDRLC8yVHfXjndMwONdymxWcD9sLb8EcNmTUFHDfBrv8XFb50PNJAV4qvK8CgVmWu2C2GWXoZfYkaR6o6jpliQdT5NcNnb9wNy36OqDnIWl0ZNM1SOzVX0yQOLeaf8+1bslaafyYMAbhcAI=&amp;p=
   </wsse:BinarySecurityToken>
</wst:RequestedSecurityToken>                
...

然后使用从先前响应中提取的安全令牌,您需要向租户凭证端点发送GET请求:https://yourtenantname.sharepoint.com/_vti_bin/idcrl.svc/

您需要发送一个格式为: BPOSIDCRL +空格+令牌的授权标头。像:

GET https://yourtenantname/_vti_bin/idcrl.svc/ 
Host: yourtenant.sharepoint.com
Authorization: BPOSIDCRL t=EwA4A06hBwAUNfDkMme61kIdXqvj9tWnUbHtXWEAAREB5clgLb8J/VvxRFIKLUnd9SRyoBHmTHFk0viit2FMlGXak5NJKJhicT8MiZmgA2HoTrJM1EgXCNUpmWqrX1LQRNfs0PHEV4XncjI9lnphsSTiFSCDjmdCKtW4TmV8n18xJHvBtDUWdvCT2lBti8

对此请求的响应将设置一个我们需要捕获的cookie,并在我们对soap服务的下一个请求中使用:

Set-Cookie: SPOIDCRL=77u/PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz48U1A+VHJ1ZSwwaC5mfG1lbWJlcnNoaXB8MTAwMzdmZmU5NTc2YzdlZUBsaXZlLmNvbSwwIy5mfG1lbWJlcnNoaXB8Y2xvdWRAYXNlbWJsaWFkZXYub25taWNyb3NvZnQuY29tLDEzMTAxMjE4ODQ0Mzc0NDcxMjsxMzA5NTg5NTQ0NTAwMDAwMDAsRmFsc2UsUCtRcmlFSFRkRnZCNkJEREZFek1mK3RVaGlzZTZtdnl1R0N4aXpjaWpyRUdxZk1BN1RpdTJNdGN0VE42TVNjdi9Cbjd2OXRxS2VPaTBzWTdlTnRqNkFESmRubFM2S0ttVjdoeHRWNjdtY3FlQVQzYWJGeDFEVFd5dEJsOWZ3MDJkZ2JTakV3eUM3WTRIWXg0ek5UYUtvUTZacGFXR0NjZ0svZEtEbloya3ozdGFBblVPM1gvUkxBeUorYkZac2RGclBCRGF4aDNTMGpBTml2VTBzb0pJR0FFRmdsQzVaMWhxU28rekZFMU5UV01oMXphMjNPYUU0TjJUNHVjd1BlaEREKzR4Ry9yMWdXMC9zOWdTaGxTMlc1U29iVDhTY2NyYi80aG9Xb1Y2TWxva0t1bXBNOWc4cCtxb0xFL3dtaElDUm9MRGhQSXR1anhoSjlqb2lZY1RBPT0saHR0cHM6Ly9hc2VtYmxpYWRldi5zaGFyZXBvaW50LmNvbS9fdnRpX2Jpbi9pZGNybC5zdmMvPC9TUD4=; path=/; secure; HttpOnly

最后,通过将此cookie附加到Sharepoint Services的每个请求,我们得到经过身份验证的响应:

POST https://yourtenantname.sharepoint.com/_vti_bin/Lists.asmx HTTP/1.1
Host: yourtenantname.sharepoint.com
Content-Type: application/soap+xml; charset=utf-8
Content-Length: [calculate]
Cookie: SPOIDCRL=77u/PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz48U1A+VHJ1ZSwwaC5mfG1lbWJlcnNoaXB8MTAwMzdmZmU5NTc2YzdlZUBsaXZlLmNvbSwwIy5mfG1lbWJlcnNoaXB8Y2xvdWRAYXNlbWJsaWFkZXYub25taWNyb3NvZnQuY29tLDEzMTAxMjExNjM5MjM3NTM1ODsxMzA5NTg5NTQ0NTAwMDAwMDAsRmFsc2UsdEFEQUZZSnZiMFF6cWxFSFlKOGRPN1d1cnJ5RzJvcGxTelBueWFMUzhrNitjenBGT0JVK292M1VkSWhydGU3TXFMOHRJaFFzazRrNHd5REFqMklDUDcyMWpES3hKWmZRZjdaUlZQeisrUi92c09Qak13em5ITkg4bHVEQXdKcVlLdE16NStoaU84cUtTRzNZWEJYbWF4SDk1cDZtSDlaMVRzaFVDRXZMZ3ZIbkt6aWlPclh4UDE2RDBmZHlTRWxsU0Radmt2Tkg0UHBLT2VGbjI5S25qSk9veDVha21TZVlIbTY2ZnF5S0tpOUJmMHdjRmlyelNRZzBWZTc4NW1JZ1ZaQUY2VTArVEI0QVRvVXRVVFFqTnd4ODJEZE9jbWlqQ25NUTUzUHUrWEFIT25lenFVb1dPTXovVWk5V2VSTUMvMWZiOUpsUmZMNlZaNjNaZDRVazB3PT0saHR0cHM6Ly9hc2VtYmxpYWRldi5zaGFyZXBvaW50LmNvbS9fdnRpX2Jpbi9pZGNybC5zdmMvPC9TUD4=; path=/; secure; HttpOnly

<?xml version="1.0" encoding="utf-8"?>
<soap12:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap12="http://www.w3.org/2003/05/soap-envelope">
  <soap12:Body>
    <GetListCollection xmlns="http://schemas.microsoft.com/sharepoint/soap/" />
  </soap12:Body>
                </soap12:Envelope>

答案 1 :(得分:0)

ADAL从Azure AD获取的令牌仅用于Office 365 REST API(上面的代码使用OAuth2.0获取REST API的JSON Wet Token)。此令牌不适用于SharePoint Web服务。

要使用SharePoint Web服务,我们需要使用SharePoint进行身份验证 SharePoint声明身份验证。有关SharePoint身份验证的更多详细信息,请参阅以下链接:

https://msdn.microsoft.com/en-us/library/hh147177.aspx#SPO_RA_OverviewSPAuthentication