2012-08-08 30 views

回答

4

我推荐使用dotnetopenauth。

不幸的是,由于项目限制,我无法使用它,所以这里是我工作代码的一个片段。我删除了一些专有代码,以便更易于阅读和使用。如果有人有问题,请告诉我,我会看看我能否提供帮助。

/// <summary> 
/// Summary description for GoToWebinarProvider 
/// </summary> 
public class GoToWebinarProvider 
{ 
    #region properties 
    private GoToWebinarAccessToken _accessToken; 
    private readonly string _apiKey = "apikey"; 

    /// <summary> 
    /// Use for debugging purposes 
    /// </summary> 
    private const bool EnableCaching = true; 

    private const string G2WApiDateTimeFormat = "yyyy-MM-ddTHH:mm:ssZ"; 
    #endregion properties 

    #region token management 
    private void OAuthenticate() 
    { 
     GoToWebinarAccessToken localToken = null; 

     //try to get access token from cache 
     if (EnableCaching) 
     { 
      localToken = GetTokenFromDb(); 

      //cache it here 
     } 
     else 
     { 
      _accessToken = GetTokenFromDb(); 
     } 

     //if the token hasn't expired yet, we have an access token, so instantiation is complete 
     if (_accessToken != null && _accessToken.ExpirationDate > DateTime.Now) 
     { 
      return; 
     } 

     //else get new token 
     var responseKey = GetResponseKey(); 

     if (responseKey != null) 
     { 
      _accessToken = GetAccessToken(responseKey); 

      if (_accessToken != null) 
      { 
       StoreTokenInDb(_accessToken); 
      } 
      else 
      { 
       throw new Exception("Could not acquire access token from GoToWebinar"); 
      } 
     } 
     else 
     { 
      throw new Exception("Could not acquire response key from GoToWebinar"); 
     } 
    } 

    private GoToWebinarAccessToken GetAccessToken(string responseKey) 
    { 
     var url = 
      String.Format(
       "https://api.citrixonline.com/oauth/access_token?grant_type=authorization_code&code={0}&client_id={1}", 
       responseKey, _apiKey); 

     const string applicationJSON = "application/json; charset=UTF-8"; 

     var httpWebRequest = (HttpWebRequest)WebRequest.Create(url); 

     httpWebRequest.ProtocolVersion = HttpVersion.Version11; 
     httpWebRequest.Method = "GET"; 

     httpWebRequest.Accept = applicationJSON; 

     try 
     { 
      var response = httpWebRequest.GetResponse(); 
      //will throw error if not 200 response 

      using (var dataStream = response.GetResponseStream()) 
      { 
       var responseText = dataStream != null ? new StreamReader(dataStream).ReadToEnd() : String.Empty; 

       var jsSerializer = new JavaScriptSerializer(); 

       var accessToken = jsSerializer.Deserialize(responseText, typeof(GoToWebinarAccessToken)) as GoToWebinarAccessToken; 

       //pad it by a minute. took time to calculate it, and each request will have latency in getting to gotowebinar 
       accessToken.ExpirationDate = DateTime.Now.AddSeconds(Convert.ToDouble(accessToken.Expires_In)).AddMinutes(-1); 

       return accessToken; 
      } 
     } 
     catch (Exception ex) 
     { 
      return null; 
     } 
    } 

    private string GetResponseKey() 
    { 
     var redirectURL = HttpContext.Current.Server.UrlEncode("http://mysite.net/Welcome.aspx"); 

     var requestURL = 
      String.Format("https://api.citrixonline.com/oauth/authorize?client_id={0}&amp;redirect_uri={1}", _apiKey, 
          redirectURL); 
     var request = CreateWebRequest(requestURL, "GET"); 

     try 
     { 
      //first request 
      var response = request.GetResponse(); 
      //will throw error if not 200 response 

      using (var dataStream = response.GetResponseStream()) 
      { 

       var responseText = dataStream != null ? new StreamReader(dataStream).ReadToEnd() : String.Empty; 

       return Login(redirectURL); 
      } 
     } 
     catch (Exception ex) 
     { 
      return null; 
     } 
    } 

    /// <summary> 
    /// Should only be called by GetResponseKey 
    /// </summary> 
    /// <param name="urlEncodedRedirect"></param> 
    private string Login(string urlEncodedRedirect) 
    { 
     var elp = new EventLogProvider(); 

     var userName = HttpContext.Current.Server.UrlEncode(SettingsKeyProvider.GetSettingsKeyInfo("GoToWebinarUserEmail").KeyValue); 
     var password = HttpContext.Current.Server.UrlEncode(SettingsKeyProvider.GetSettingsKeyInfo("GoToWebinarUserPassword").KeyValue); 
     var postData = String.Format(
       "emailAddress={0}&password={1}&client_id={2}&access_type=G2W&app_name=MyApp&redirect_url={3}&submitted=form_submitted&submit=Log+In", 
       userName, password, _apiKey, urlEncodedRedirect); 

     var request = CreateWebRequest("https://developer.citrixonline.com/oauth/g2w/authorize.php", "POST", 
             postData, "application/x-www-form-urlencoded"); 
     request.AllowAutoRedirect = false; 

     var response = request.GetResponse(); 

     using (var dataStream = response.GetResponseStream()) 
     { 
      var responseText = dataStream != null ? new StreamReader(dataStream).ReadToEnd() : String.Empty; 

      const string locationHeader = "location"; 

      if (!String.IsNullOrWhiteSpace(response.Headers.Get(locationHeader))) 
      { 
       //get redirect to login page 
       var locationRedirect = response.Headers.Get(locationHeader); 

       elp.LogEvent("I", DateTime.Now, GetType().Name, "GoToWebinar", 
          HttpContext.Current.Request.Url.ToString(), locationRedirect); 

       const string comparator = "code="; 
       var index = locationRedirect.IndexOf(comparator, StringComparison.OrdinalIgnoreCase); 

       if (index != -1) 
       { 
        return locationRedirect.Substring(index + comparator.Length); 
       } 

       throw new Exception("Could not parse response code: " + locationRedirect); 
      } 


      throw new Exception("Did not receive redirect: ", new Exception(responseText)); 
     } 
    } 

    private static GoToWebinarAccessToken GetTokenFromDb() 
    { 
     //return token 
    } 

    private static void StoreTokenInDb(GoToWebinarAccessToken accessToken) 
    { 
     //store token 
    } 
    #endregion token management 

    #region api calls 

    public IList<GoToWebinarWebinar> GetWebinars() 
    { 
     if (_accessToken == null || _accessToken.ExpirationDate < DateTime.Now) 
     { 
      OAuthenticate(); 
     } 

     var serviceEndPoint = String.Format("https://api.citrixonline.com/G2W/rest/organizers/{0}/webinars", _accessToken.Organizer_Key); 

     try 
     { 
      var httpWebRequest = CreateJSONRequest(serviceEndPoint, "GET", null); 

      var httpResponse = (HttpWebResponse)httpWebRequest.GetResponse(); 
      using (var httpResponseStream = httpResponse.GetResponseStream()) 
      { 
       if (httpResponseStream != null) 
       { 
        using (var streamReader = new StreamReader(httpResponseStream)) 
        { 
         var responseText = streamReader.ReadToEnd(); 

         var jsSerializer = new JavaScriptSerializer(); 
         var gotoWebinarList = jsSerializer.Deserialize<IList<GoToWebinarWebinar>>(responseText); 

         return gotoWebinarList; 
        } 
       } 
      } 
     } 
     catch (Exception ex) 
     { 
      //log it 
     } 

     return null; 
    } 

    #endregion api calls 

    #region web requests 
    private HttpWebRequest CreateJSONRequest(string serviceEndPoint, string httpMethod, string postData) 
    { 
     const string applicationJSON = "application/json"; 

     var httpWebRequest = (HttpWebRequest)WebRequest.Create(serviceEndPoint); 

     httpWebRequest.ProtocolVersion = HttpVersion.Version11; 
     httpWebRequest.Method = httpMethod; 

     httpWebRequest.Accept = String.Format("{0}, application/vnd.citrix.g2wapi-v1.1+json", applicationJSON); 

     httpWebRequest.ContentType = applicationJSON; 
     httpWebRequest.Headers.Add(HttpRequestHeader.Authorization, _accessToken.Access_Token); 

     if (httpMethod.Equals("POST", StringComparison.OrdinalIgnoreCase)) 
     { 
      var encoding = new ASCIIEncoding(); 

      var body = encoding.GetBytes(postData); 
      httpWebRequest.ContentLength = body.Length; 

      using (var newStream = httpWebRequest.GetRequestStream()) 
      { 
       newStream.Write(body, 0, body.Length); 
       newStream.Close(); 
      } 
     } 

     return httpWebRequest; 
    } 

    private static HttpWebRequest CreateWebRequest(string serviceEndPoint, string httpMethod) 
    { 
     //const string applicationJSON = "application/json"; 

     var httpWebRequest = (HttpWebRequest)WebRequest.Create(serviceEndPoint); 

     httpWebRequest.ProtocolVersion = HttpVersion.Version11; 
     httpWebRequest.Method = httpMethod; 

     //httpWebRequest.Accept = String.Format("{0}, application/vnd.citrix.g2wapi-v1.1+json", applicationJSON); 

     //httpWebRequest.ContentType = applicationJSON; 
     //httpWebRequest.Headers.Add(HttpRequestHeader.Authorization, _accessToken); 

     return httpWebRequest; 
    } 

    private static HttpWebRequest CreateWebRequest(string serviceEndPoint, string httpMethod, string postData, string contentType) 
    { 
     var httpWebRequest = (HttpWebRequest)WebRequest.Create(serviceEndPoint); 

     httpWebRequest.ProtocolVersion = HttpVersion.Version11; 
     httpWebRequest.Method = httpMethod; 

     if (contentType != null) 
     { 
      httpWebRequest.ContentType = contentType; 
     } 

     if (httpMethod.Equals("POST", StringComparison.OrdinalIgnoreCase)) 
     { 
      var encoding = new ASCIIEncoding(); 

      var body = encoding.GetBytes(postData); 
      httpWebRequest.ContentLength = body.Length; 

      using (var newStream = httpWebRequest.GetRequestStream()) 
      { 
       newStream.Write(body, 0, body.Length); 
       newStream.Close(); 
      } 
     } 

     return httpWebRequest; 
    } 

    #endregion web requests 

    private void LogRequest(string methodName, string dataToLog) 
    { 
     //log it 
    } 

    /// <summary> 
    /// Syntax matches JSON response 
    /// </summary> 
    private class GoToWebinarAccessToken 
    { 
     public string Access_Token; 
     public string Refresh_Token; 
     public string Organizer_Key; 
     public string Account_Key; 

     public double? Expires_In; 

     public DateTime ExpirationDate; 
    } 
}