sharepoint - 使用 OAuth2S2SClient 获取 AccessToken 返回 "Token Request failed"?

标签 sharepoint oauth-2.0 ms-office exchangewebservices office365

我正在尝试创建 Sharepoint ClientContext 以从 sharpoint 在线获取文档列表。 为此,我使用了 TokenHelper.cs 类。 如果您还没有看过该类,返回共享点上下文的代码如下所示:

/// <summary>
/// Uses the specified access token to create a client context
/// </summary>
/// <param name="targetUrl">Url of the target SharePoint site</param>
/// <param name="accessToken">Access token to be used when calling the specified targetUrl</param>
/// <returns>A ClientContext ready to call targetUrl with the specified access token</returns>
public static ClientContext GetClientContextWithAccessToken(string targetUrl, string accessToken)
  {
    Uri targetUri = new Uri(targetUrl);
    ClientContext clientContext = new ClientContext(targetUrl);

    clientContext.AuthenticationMode = ClientAuthenticationMode.Anonymous;
    clientContext.FormDigestHandlingEnabled = false;
    clientContext.ExecutingWebRequest +=
              delegate(object oSender, WebRequestEventArgs webRequestEventArgs)
                {
                    webRequestEventArgs.WebRequestExecutor.RequestHeaders["Authorization"] =
                        "Bearer " + accessToken;
                };
    return clientContext;
  }

但在调用此方法之前我需要获取访问 token ,为此我使用了 TokenHelper 类中的以下方法:

/// <summary>
/// Uses the specified authorization code to retrieve an access token from ACS to call the specified principal 
/// at the specified targetHost. The targetHost must be registered for target principal.  If specified realm is 
/// null, the "Realm" setting in web.config will be used instead.
/// </summary>
/// <param name="authorizationCode">Authorization code to exchange for access token</param>
/// <param name="targetPrincipalName">Name of the target principal to retrieve an access token for</param>
/// <param name="targetHost">Url authority of the target principal</param>
/// <param name="targetRealm">Realm to use for the access token's nameid and audience</param>
/// <returns>An access token with an audience of the target principal</returns>
public static OAuth2AccessTokenResponse GetAccessToken(string authorizationCode, string targetPrincipalName, string targetHost, string targetRealm, Uri redirectUri)
   {
     if (targetRealm == null)
     {
       targetRealm = Realm;
     }

     string resource = GetFormattedPrincipal(targetPrincipalName, targetHost, targetRealm);
     string clientId = GetFormattedPrincipal(ClientId, null, targetRealm);

     // Create request for token. The RedirectUri is null here.  This will fail if redirect uri is registered
     OAuth2AccessTokenRequest oauth2Request = OAuth2MessageFactory.CreateAccessTokenRequestWithAuthorizationCode(clientId, ClientSecret, authorizationCode, redirectUri, resource);

     // Get token
     OAuth2S2SClient client = new OAuth2S2SClient();
     OAuth2AccessTokenResponse oauth2Response;
     try
       {
         oauth2Response = client.Issue(AcsMetadataParser.GetStsUrl(targetRealm), oauth2Request) as OAuth2AccessTokenResponse;
       }
     catch (WebException wex)
       {
         using (StreamReader sr = new StreamReader(wex.Response.GetResponseStream()))
         {
           string responseText = sr.ReadToEnd();
           throw new WebException(wex.Message + " - " + responseText, wex);
         }
       }
 return oauth2Response;
 }

当我跟踪我的代码时,我可以看到以下行引发异常:

oauth2Response = client.Issue(AcsMetadataParser.GetStsUrl(targetRealm), oauth2Request) 作为 OAuth2AccessTokenResponse;

token 请求失败。 H结果:-2146233088 来源:Microsoft.IdentityModel.Extensions 内部异常:远程服务器返回错误:(400) Bad Request。

有什么想法吗?

最佳答案

请确保您将正确的参数传递给该方法,我能够使用此方法获得访问 token ,几乎没有反复试验。我的方法调用签名是

var accessToken = TokenHelper.GetAccessToken(authCode, "00000003-0000-0ff1-ce00-000000000000", targetUri.Authority, realm, redirectUri).AccessToken;

authorizationCode 是您在成功通过 SharePoint 身份验证并重定向到您的应用程序页面时获得的代码。

string authCode = Request["code"];

targetPrincipalName 是一个常量。

targetHost 就像“tenant.sharepoint.com”

realm 的获取方式如下(这是一个常量,您可以在租户内重复使用):

Uri targetUri = new Uri("https://<tenant>.sharepoint.com/sites/<sitename>");
string realm = TokenHelper.GetRealmFromTargetUrl(targetUri)

redirect uri是当前页面的uri,不带任何查询字符串。

redirectUri = new Uri(Request.Url.GetLeftPart(UriPartial.Path))

有关详细信息,请参阅本文。 http://msdn.microsoft.com/en-us/library/office/jj687470(v=office.15).aspx

关于sharepoint - 使用 OAuth2S2SClient 获取 AccessToken 返回 "Token Request failed"?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23737158/

相关文章:

xml - 如何从 dateTime 值中获取时间?

sharepoint - SP2013 SharePoint 托管的应用程序模式对话框错误 : Cannot read 'hiddenButtonValueBeforeDialog'

html - float 菜单内容高度

java - 让 oauth2 与 spring-boot 和 rest 一起工作

python - Google App Engine 中的 OAuth 2.0 提供程序。没有谷歌帐户 - Python

c# - 将 byte[] 作为文件打开,而不是首先将其实际保存为文件

javascript - 获取 Sharepoint 中文档的文档类型图标

android - 如何授予对关联/辅助 Google 帐户的访问权限

c# - 如何让 excel 插件从工作表中读取行直到没有更多数据?

java - 用 java 确定 microsoft office 的版本