如何强制Microsoft.IdentityModel.S2S.Protocols.OAuth2.OAuth2S2SClient.Issue使用Web代理?

时间:2016-07-12 10:04:11

标签: c# sharepoint csom

我正在创建一个使用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)

我想知道是否有解决方法?

1 个答案:

答案 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;
}