認証トークンを使用したRest Post呼び出し
-
20-12-2019 - |
質問
クライアントアプリケーション(WPFアプリケーション)からSharepoint Online(クレームベースの認証サイト)にPost要求を送信しようとしています。この場合、'Title'を'Test'に変更するには、ListItemを更新する必要があります。
私はCookieContainerを介して取得しています MsOnlineClaimsHelperクラス これは私に認証トークンを正常に返します。
しかし、私が要求を送信しようとすると、応答は次のようになります The remote server returned an error: (403) Forbidden.
WebRequestコード
try
{
var claimshelper = new MsOnlineClaimsHelper(baseUrl, _userName, _password);
var request = (HttpWebRequest)WebRequest.Create(baseUrl + "/" + url);
request.CookieContainer = claimshelper.CookieContainer;
request.Method = "POST";
request.Headers.Add("X-HTTP-Method", "MERGE");
request.Headers.Add("If-Match", "*");
request.Accept = "application/json;odata=verbose";
using (var streamWriter = new StreamWriter(request.GetRequestStream()))
{
streamWriter.Write(json);
streamWriter.Flush();
}
var webResp = request.GetResponse() as HttpWebResponse;
var theData = new StreamReader(webResp.GetResponseStream(), true);
string payload = theData.ReadToEnd();
}
catch (Exception ex)
{
}
Rest Url:
/_api/lists/getbytitle('SampleList')/items(1)
Jsonペイロード:
string json = "{ '__metadata': { 'type': 'SP.Data.SampleListListItem' }, 'Title': 'Test'}";
エラー:
The remote server returned an error: (403) Forbidden.
解決
このエラーは、SharePoint2013RESTサービス以降に発生します が必要です。 を含むユーザ Request Digest
それぞれの値 create
, update
と delete
作戦だこの値は、SharePointによって非正規の要求を識別するために使用されます。
要求ダイジェスト値を提供する方法
で MsOnlineClaimsHelper class
(MsOnlineClaimsHelper.cs
ファイル)要求フォームダイジェスト値に次のメソッドを追加します:
/// <summary>
/// Request Form Digest value
/// </summary>
/// <returns></returns>
private string GetFormDigest()
{
var endpoint = "/_api/contextinfo";
var request = (HttpWebRequest) WebRequest.Create(_host.AbsoluteUri + endpoint);
request.CookieContainer = new CookieContainer();
request.Method = "POST";
//request.Accept = "application/json;odata=verbose";
request.ContentLength = 0;
using (var response = (HttpWebResponse)request.GetResponse())
{
using (var reader = new StreamReader(response.GetResponseStream()))
{
var result = reader.ReadToEnd();
// parse the ContextInfo response
var resultXml = XDocument.Parse(result);
// get the form digest value
var e = from e in resultXml.Descendants()
where e.Name == XName.Get("FormDigestValue", "http://schemas.microsoft.com/ado/2007/08/dataservices")
select e;
_formDigest = e.First().Value;
}
}
return _formDigest;
}
と FormDigest
プロパティ:
private string _formDigest;
public string FormDigest
{
get
{
if (_formDigest == null || DateTime.Now > _expires)
{
return GetFormDigest();
}
return _formDigest;
}
}
SharePoint2013REST APIを使用してListItemの更新操作を実行する方法
次の例は、フォームダイジェストを要求するために提供されている実装を使用して、リスト項目の更新を実行する方法を示しています
キーポイント:
X-RequestDigest
ヘッダーは、フォームダイジェスト値を指定するために使用されます- リクエスト
Content Type
指定する必要があります
例を示します。:
var userName = "username@contoso.onmicrosoft.com";
var password = "password";
var payload = "{ '__metadata': { 'type': 'SP.Data.TasksListItem' }, 'Title': 'New Tasl'}"; //for a Task Item
try
{
var claimshelper = new MsOnlineClaimsHelper(baseUrl, _userName, _password);
var request = (HttpWebRequest)WebRequest.Create(baseUrl + "/" + endpointUrl);
request.CookieContainer = claimshelper.CookieContainer;
request.Headers.Add("X-RequestDigest", claimshelper.FormDigest);
request.Method = "POST";
request.Headers.Add("X-HTTP-Method", "MERGE");
request.Headers.Add("If-Match", "*");
request.Accept = "application/json;odata=verbose";
request.ContentType = "application/json;odata=verbose";
using (var writer = new StreamWriter(request.GetRequestStream()))
{
writer.Write(payload);
writer.Flush();
}
var response = request.GetResponse() as HttpWebResponse;
//...
}
catch (Exception ex)
{
//Error handling goes here..
}