SharePoint在线:Windows客户端应用程序可以使用OAuth进行身份验证吗?

Mat*_*att 7 c# sharepoint oauth office365 sharepoint-online

我们使用SharePoint客户端对象模型在线构建SharePoint客户端应用程序.我们希望使用OAuth对此Windows客户端应用程序进行身份验证,但我们没有找到方法来执行此操作; MSDN上的文档含糊不清.

文章给出了一个例子,但是,当我与链接创建新的应用程序https://<TENANT>.sharepoint.com/_layouts/appregnew.aspx,"一个应用程序在客户机上运行"的选项被禁用,有没有在SharePoint Online网站的设置,使这个?

Bra*_*age 7

经过大量的努力,我得到了这个工作

我想这不是最精彩的代码,但它是:

/// <summary>
/// Sets needed values
/// </summary>
/// <param name="clientId">The ClientId from the application</param>
/// <param name="redirectUri">The RedirectUri where the browser has to be send.</param>
/// <param name="resource">The source you want to access</param>
public OneDriveConnection(string clientId, string clientSecret, string redirectUri, string resource)
{
    this._clientId = clientId;
    this._redirectUri = Uri.EscapeDataString(redirectUri);
    this._resource = Uri.EscapeDataString(resource);
    this._clientSecret = clientSecret;
}
Run Code Online (Sandbox Code Playgroud)

接下来,我创建一个浏览器,提示用户登录:

/// <summary>
/// Authorizes the application
/// </summary>
public void Authorize()
{
    /* EXAMPLE: GET https://login.windows.net/common/oauth2/authorize
        * ?response_type=code
        * &client_id=acb81092-056e-41d6-a553-36c5bd1d4a72
        * &redirect_uri=https://mycoolwebapp.azurewebsites.net
        * &resource=https:%2f%2foutlook.office365.com%2f
        * &state=5fdfd60b-8457-4536-b20f-fcb658d19458 */

    string baseUri = "https://login.windows.net/common/oauth2/authorize";
    string authorizationUri = string.Format(baseUri
        + "?response_type=code"
        + "&client_id={0}"
        + "&redirect_uri={1}"
        + "&resource={2}"
        + "&state={3}", this._clientId, this._redirectUri, this._resource, "5fdfd60b-8457-4536-b20f-fcb658d19458");

    // Create the form
    Form webBrowserForm = new Form();
    webBrowserForm.MaximizeBox = false;
    webBrowserForm.MinimizeBox = false;
    webBrowserForm.Size = new System.Drawing.Size(580, 890);
    webBrowserForm.Text = "Webbrowser";
    webBrowserForm.FormBorderStyle = FormBorderStyle.FixedDialog;
    webBrowserForm.StartPosition = FormStartPosition.CenterScreen;

    // Create the WebBrowser
    WebBrowser webBrowser = new WebBrowser();
    webBrowser.Width = 580;
    webBrowser.Height = 890;
    webBrowser.Location = new System.Drawing.Point(0, 0);
    webBrowser.ShowPageSetupDialog();

    // Hook event to the webBrowser
    webBrowser.Navigated += webBrowser_Navigated;

    // Show the webBrowser and form to the user
    webBrowserForm.Controls.Add(webBrowser);
    webBrowserForm.Show();

    // Navigate to the authorizationUri
    webBrowser.Navigate(authorizationUri);
}
Run Code Online (Sandbox Code Playgroud)

在这里,我检查是否有代码来执行GetTokenInformation方法:

/// <summary>
/// When the url has code in it and contains a session_state get the code and do the GetTokenInformation
/// </summary>
private void webBrowser_Navigated(object sender, WebBrowserNavigatedEventArgs e)
{
    if (e.Url.AbsoluteUri.Contains("code=") && e.Url.AbsoluteUri.Contains("session_state"))
    {
        string[] splited = e.Url.AbsoluteUri.Split(new char[] { '=', '&' });
        _code = splited[1];

        if (!string.IsNullOrWhiteSpace(_code)
            && !string.IsNullOrWhiteSpace(_redirectUri)
            && !string.IsNullOrWhiteSpace(_clientId))
        {
            GetTokenInformation(_code, _redirectUri, _clientId, _clientSecret);
        }
        else
        {
            _connected = false;
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

在GetTokenInformation方法中,我得到了TokenInformation,我使用Newtonsoft.Json dll将它放入TokenInformation类中

/// <summary>
/// This method gets tokeninformation: access_token, token_type, expires_in, resource, refresh_token, scope, id_token
/// </summary>
/// <param name="code">Code from the authorize request</param>
/// <param name="redirectUri">Reply url for your application</param>
/// <param name="clientId">Your applications client id in Windows Azure Directory</param>
/// <param name="clientSecret">Your applications client secret</param>
private void GetTokenInformation(string code, string redirectUri, string clientId, string clientSecret)
{
    // Get the token information that is set above in the constructor with the help of the clientId, clientSecret and code and as well as the redirectUri without it you can't connect to it otherwise it will crash if you don't do it like that
    string baseUri = "https://login.windows.net/common/oauth2/token";
    string parameters = string.Format("grant_type=authorization_code"
        + "&code={0}"
        + "&redirect_uri={1}"
        + "&client_id={2}"
        + "&client_secret={3}", code, redirectUri, clientId, clientSecret);
    string response = HttpPost(baseUri, parameters);

    if (!string.IsNullOrWhiteSpace(response))
    {
        _tokenInformation = JsonConvert.DeserializeObject<TokenInformation>(response);
        _connected = true;
    }
    else
    {
        _connected = false;
    }
}
Run Code Online (Sandbox Code Playgroud)

这是我使用Newtonsoft.Json dll的TokenInformation类:

[JsonObject(MemberSerialization.OptIn)]
class TokenInformation
{
    [JsonProperty(PropertyName = "access_token")]
    public string AccessToken { get; set; }

    [JsonProperty(PropertyName = "token_type")]
    public string TokenType { get; set; }

    [JsonProperty(PropertyName = "expires_in")]
    public int ExpiresIn { get; set; }

    [JsonProperty(PropertyName = "expires_on")]
    public int ExpiresOn { get; set; }

    [JsonProperty(PropertyName = "resource")]
    public string Resource { get; set; }

    [JsonProperty(PropertyName = "refresh_token")]
    public string RefreshToken { get; set; }

    [JsonProperty(PropertyName = "scope")]
    public string Scope { get; set; }

    [JsonProperty(PropertyName = "id_token")]
    public string IdToken { get; set; }
}
Run Code Online (Sandbox Code Playgroud)

这是我找到连接到SharePoint/Office365所需的请求:链接