我正在创建一个使用CSOM连接到SharePoint Online的守护程序应用程序。我的应用程序将在Internet代理后面的企业环境中运行。我使用提供的TokenHelper和SharePointContext类的标准SharePoint加载项模型,它使用Microsoft.IdentityModel.Extensions.dll。
我已经将TokenHelper操纵在两个地方使用代理:GetRealmFromTargetUrl中的WebRequest和AcsMetadataParser中的WebClient。
然而,它似乎并不起作用,因为在我看来,DLL使用了另一个Web请求。以下是触发异常的执行中的StackTraces:
Exception Message: Token request failed.
Stack Trace:
at Microsoft.IdentityModel.S2S.Protocols.OAuth2.OAuth2S2SClient.Issue(String securityTokenServiceUrl, OAuth2AccessTokenRequest oauth2Request)
at ScriptTask_d38d98a4cb054097ac7c2ece4802bf9a.spo.TokenHelper.GetAppOnlyAccessToken(String targetPrincipalName, String targetHost, String targetRealm)
at ScriptTask_d38d98a4cb054097ac7c2ece4802bf9a.ScriptMain.Main()
Inner Exception Message: Unable to connect to the remote server
Inner Stack Trace:
at System.Net.HttpWebRequest.GetRequestStream(TransportContext& context)
at System.Net.HttpWebRequest.GetRequestStream()
at Microsoft.IdentityModel.S2S.Protocols.OAuth2.OAuth2WebRequest.GetResponse()
at Microsoft.IdentityModel.S2S.Protocols.OAuth2.OAuth2S2SClient.Issue(String securityTokenServiceUrl, OAuth2AccessTokenRequest oauth2Request)
我想知道是否有解决方法?
答案 0 :(得分:0)
绕过它。
而不是这个电话:
oauth2Response =
client.Issue(AcsMetadataParser.GetStsUrl(targetRealm),
oauth2Request) as OAuth2AccessTokenResponse;
我创建了一个静态方法IssueToken和一个虚拟"映射"具有以下代码的类:
private static OAuth2AccessTokenResponse IssueToken(string sts, OAuth2AccessTokenRequest oauth2Request) {
string requestString = "grant_type=" + System.Web.HttpUtility.UrlEncode(oauth2Request.GrantType) +
"&client_id=" + System.Web.HttpUtility.UrlEncode(oauth2Request.ClientId) +
"&client_secret=" + System.Web.HttpUtility.UrlEncode(oauth2Request.ClientSecret) +
"&resource=" + System.Web.HttpUtility.UrlEncode(oauth2Request.Resource);
string tokenResponse;
byte[] byteArray = Encoding.UTF8.GetBytes(requestString);
WebRequest request = WebRequest.Create(sts);
request.Proxy = new System.Net.WebProxy { Address = new Uri(InternetProxy) };
request.Method = "POST";
request.ContentType = "application/x-www-form-urlencoded";
request.ContentLength = byteArray.Length;
using (Stream reqStream = request.GetRequestStream()) {
reqStream.Write(byteArray, 0, byteArray.Length);
}
using (WebResponse response = request.GetResponse()) {
using (Stream respStream = response.GetResponseStream()) {
using (StreamReader reader = new StreamReader(respStream)) {
tokenResponse = reader.ReadToEnd();
}
}
}
JavaScriptSerializer jss = new JavaScriptSerializer();
OAuth2AccessTokenResponseDummy dummy = jss.Deserialize<OAuth2AccessTokenResponseDummy>(tokenResponse);
OAuth2AccessTokenResponse oauth2Response = new OAuth2AccessTokenResponse () {
TokenType = dummy.token_type,
ExpiresIn = dummy.expires_in,
NotBefore = jss.Deserialize<DateTime>(@"""\/Date(" + dummy.not_before + @")\/""").ToLocalTime(),
ExpiresOn = jss.Deserialize<DateTime>(@"""\/Date(" + dummy.expires_on + @")\/""").ToLocalTime(),
Scope = dummy.resource,
AccessToken = dummy.access_token
};
return oauth2Response;
}
private class OAuth2AccessTokenResponseDummy {
public string token_type { get; set; }
public string expires_in { get; set; }
public string not_before { get; set; }
public string expires_on { get; set; }
public string resource { get; set; }
public string access_token { get; set; }
}
此外,我已将Web代理添加到GetClientContextWithAccessToken的委托中:
public static ClientContext GetClientContextWithAccessToken(string targetUrl, string accessToken) {
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;
webRequestEventArgs.WebRequestExecutor.WebRequest.Proxy = webProxy;
};
return clientContext;
}