sharepointへcurlでファイルをuploadする
sharepointにcurlでファイルを upload する
ってなことをやって見ました。sharepointのRESTAPIをcurlで利用します。SAMLに認証ってややこしい。
この記事で記述されている方法は
williamvanstrien.blogspot.com
ここに書かれている内容を元にしています。
プレイヤの整理
認証を通すためと、ファイルを突っ込むためにプレイヤは4人でてきます。
- クライアント
- カスタムSTS
- O356の認証(login.microsoftonline.com)
- エンドポイント(tenant.sharepoint.com)
カスタムSTS( Security Token Service) は利用形態によってはないところもあるかも。
手順
手順はこんなかんじ。
- クライアントからO365へ customSTS のURL を聞く
- 上記で帰ってきたレスポンスから customSTS のURLを抜きだす。
- customSTS へ SAML;assersion をリクエストする。
- customSTSから帰ってきた SAML:assersion を使って、endpointにSPOIDCRLクッキー値を得る。
- endpoint から帰ってきた SPOIDCRLクッキー値を使って endpointへREST APIを発行する。
図で示すとこんなです。
じゃあ、手順を具体的に。
認証
まずは認証手順から。最終的にはSPOIDCRLクッキー値を得ることが目的です。
カスタムSTSのURIを得る
これは利用している環境にdependですが、sharepointで認証するときにActiveDIretoryと連携していたりする環境だと該当するかと。
こんなリクエストをcurlで投げます。loginのところは自分が利用している環境に合わせて変えてください。
$ curl -X POST -H "Content-Type: application/x-www-form-urlencoded" \ -d "login=hoge@example.com&xml-1" \ https://login.microsoft.com/GetUserRealm.srf -w "\n"
XML形式でレスポンスが帰ってきます。
<STSAuthURL>〜</STSAuthURL>タグのところがカスタムSTSのURLです。
sedで抜き出すならこんな。
STSURL=$(上記のcurlコマンド | sed -n 's:.*<STSAuthURL>\(.*\)</STSAuthURL>.*:\1:p'
例として、このURIが https://adfs.ad.example.com だったとします。
SAML:assersionリクエスト用のXMLファイルを作成する。
上記手順で取得したカスタムSTSに対してSAM:assertionをリクエストします。リクエストするためにXMLファイルが必要ですが、以下手順で作成します。
以下の内容をfile1として保存。
<wsse:Username>のところと<wsse:Password>のところは自分の認証情報へ変更してください。
<?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:saml="urn:oasis:names:tc:SAML:1.0:assertion" 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:wssc="http://schemas.xmlsoap.org/ws/2005/02/sc" 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://<sts_address>/adfs/services/trust/2005/usernamemixed</wsa:To> <wsa:MessageID>b07da3ec-9824-46a5-a102-2329e0c5f63f</wsa:MessageID> <ps:AuthInfo xmlns:ps="http://schemas.microsoft.com/Passport/SoapServices/PPCRL" Id="PPAuthInfo"> <ps:HostingApp>Managed IDCRL</ps:HostingApp> <ps:BinaryVersion>6</ps:BinaryVersion> <ps:UIVersion>1</ps:UIVersion> <ps:Cookies></ps:Cookies> <ps:RequestParams>AQAAAAIAAABsYwQAAAAxMDMz</ps:RequestParams> </ps:AuthInfo> <wsse:Security> <wsse:UsernameToken wsu:Id="user"> <wsse:Username>hoge@example.com</wsse:Username> <wsse:Password>password</wsse:Password> </wsse:UsernameToken> <wsu:Timestamp Id="Timestamp">
以下の内容をfile2として保存。
</wsu:Timestamp> </wsse:Security> </s:Header> <s:Body> <wst:RequestSecurityToken Id="RST0"> <wst:RequestType>http://schemas.xmlsoap.org/ws/2005/02/trust/Issue</wst:RequestType> <wsp:AppliesTo> <wsa:EndpointReference> <wsa:Address>urn:federation:MicrosoftOnline</wsa:Address> </wsa:EndpointReference> </wsp:AppliesTo> <wst:KeyType>http://schemas.xmlsoap.org/ws/2005/05/identity/NoProofKey</wst:KeyType> </wst:RequestSecurityToken> </s:Body> </s:Envelope>
file1とfile2の間に以下のコマンドの出力結果をはさみます。
echo "<wsu:Created>`date -u +'%Y-%m-%dT%H:%M:%SZ'`</wsu:Created>" echo "<wsu:Expires>`date -u +'%Y-%m-%dT%H:%M:%SZ' --date='-15 minutes ago'`</wsu:Expires>"
こんなかんじで。
$ cat file1 > saml_request.xml $ echo "<wsu:Created>`date -u +'%Y-%m-%dT%H:%M:%SZ'`</wsu:Created>" >> saml_request.xml $ echo "<wsu:Expires>`date -u +'%Y-%m-%dT%H:%M:%SZ' --date='-15 minutes ago'`</wsu:Expires>" >> saml_request.xml $ cat file2 >> saml_request.xml
customSTSへリクエスト
SMAL:assertionを要求します。
$ curl -X POST -H "Content-Type: application/soap+xml; charset=utf-8" -d "@saml_request.xml" https://adfs.ad.example.com -w "\n"
これもXMLでレスポンスがあります。
<saml:Assertion>タグのところがSAML:assertionです。
タグつきで保存しておきます。sedで抜き出すならこんな。
$ SAML=$(上記curl | sed 's/^.*\(<saml:Assertion.*saml:Assertion>\).*$/\1/' )
バイナリセキュリティトークン用のXMLファイルを作成
上記でgetしたSAML;assertionを使ってバイナリセキュリティトークンを得ます。
セキュリティトークンをリクエストするためのSAML:assertionが入ったXMLファイルを用意します。
以下の内容をfile3として保存。
<?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>
以下の内容をfile4として保存。
</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>
file3とSAML:assertion値とfile4を連結します。
こんな。
$ cat file3 > bst.xml $ 上記curl | sed 's/^.*\(<saml:Assertion.*saml:Assertion>\).*$/\1/' >> bst.xml $ cat file4 >> bst.xml
バイナリセキュリティトークンを得る
上記手順で作成したXMLファイルを利用してバイナリセキュリティトークンを得ます。
$ curl -X POST -H "Content-Type: application/soap+xml; charset=utf-8" \ -d "@bst.xml" https://login.microsoftonline.com/RST2.srf -w "\n"
レスポンスがXMLで帰ってきます。
<wsse:BinarySecurityToken> タグのところがバイナリセキュリティトークンです。
こんどはタグはいりません。中身だけ保存。
SPOIDCRLクッキー値を得る
やっと欲しいものが入手できる。上記手順でgetしたバイナリセキュリティトークンを使って、エンドポイントに対してSPOIDCTLクッキー値をリクエストします。
$ curl -i -X GET -H "Authorization: BPOSIDCRL ${BinarySecurityToken}" \ -H "X-IDCRL_ACCEPTED: t" -H "User-Agent:" https://example.sharepoint.com/_vti_bin/idcrl.svc/
このsvcの後のスラッシュがないとエラーになったりします。なんだその仕様。
このレスポンスのヘッダに"set-cookie: SPOIDCRL"という行があるので、その行をそのままどこかへ保存。
内容はこんな感じなはず。
Set-Cookie: SPOIDCRL=(なんだかアルファベットと数字がたくさん); path=/; secure; HttpOnly