2012-11-27 87 views
3

在上一個DotNetOpenAuth包中,GoogleClient擴展了OpenIdClient,有人知道我在哪裏可以找到實現Google Oauth2的擴展DotNetOpenAuth OAuth2Client的實現?DotNetOpenAuth Google OAuth2

+0

可能重複[OAuth2用戶和DotNetOpenAuth - 實施谷歌定製的客戶端(http://stackoverflow.com/questions/13727466/oauth2-and-dotnetopenauth-implementing-google-custom-客戶端) –

+1

更好:https://github.com/mj1856/DotNetOpenAuth.GoogleOAuth2 –

回答

-2

OAuth2 and DotNetOpenAuth - implementing Google custom client

public class GoogleOAuth2Client : OAuth2Client 
{ 
    #region Constants and Fields 

    /// <summary> 
    /// The authorization endpoint. 
    /// </summary> 
    private const string AuthorizationEndpoint = "https://accounts.google.com/o/oauth2/auth"; 

    /// <summary> 
    /// The token endpoint. 
    /// </summary> 
    private const string TokenEndpoint = "https://accounts.google.com/o/oauth2/token"; 

    /// <summary> 
    /// The _app id. 
    /// </summary> 
    private readonly string _clientId; 

    /// <summary> 
    /// The _app secret. 
    /// </summary> 
    private readonly string _clientSecret; 

    #endregion 

    public const string ProviderAppendix = "__provider__=google"; 

    public GoogleOAuth2Client(string clientId, string clientSecret) 
     : base("google") 
    { 
     if (string.IsNullOrWhiteSpace(clientId)) throw new ArgumentNullException("clientId"); 
     if (string.IsNullOrWhiteSpace(clientSecret)) throw new ArgumentNullException("clientSecret"); 

     this._clientId = clientId; 
     this._clientSecret = clientSecret; 
    } 

    protected override Uri GetServiceLoginUrl(Uri returnUrl) 
    { 
     StringBuilder serviceUrl = new StringBuilder(); 

     serviceUrl.AppendFormat("{0}?scope=https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fuserinfo.email+https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fuserinfo.profile", AuthorizationEndpoint); 
     serviceUrl.Append("&state=google"); 
     serviceUrl.AppendFormat("&redirect_uri={0}", returnUrl.ToString().ToLower()); 
     serviceUrl.Append("&response_type=code"); 
     serviceUrl.AppendFormat("&client_id={0}", _clientId); 

     return new Uri(serviceUrl.ToString()); 
    } 

    protected override IDictionary<string, string> GetUserData(string accessToken) 
    { 
     var client = new RestClient("https://www.googleapis.com"); 
     var request = new RestRequest(String.Format("/oauth2/v1/userinfo?access_token={0}", accessToken), Method.GET); 
     IDictionary<String, String> extraData = new Dictionary<String, String>(); 

     var response = client.Execute(request); 
     if (null != response.ErrorException) 
     { 
      return null; 
     } 
     else 
     { 
      try 
      { 
       var json = JObject.Parse(response.Content); 

       string firstName = (string)json["given_name"]; 
       string lastName = (string)json["family_name"]; 
       string emailAddress = (string)json["email"]; 
       string id = (string)json["id"]; 

       extraData = new Dictionary<String, String> 
      { 
       {"accesstoken", accessToken}, 
       {"name", String.Format("{0} {1}", firstName, lastName)}, 
       {"firstname", firstName}, 
       {"lastname", lastName}, 
       {"email", emailAddress}, 
       {"id", id}           
      }; 
      } 
      catch (Exception ex) 
      { 
       Ccl.Log.Logging.Error("Error requesting OAuth user data from Google", ex); 
       return null; 
      } 

      return extraData; 
     } 
    } 

    protected override string QueryAccessToken(Uri returnUrl, string authorizationCode) 
    { 
     StringBuilder postData = new StringBuilder(); 
     postData.AppendFormat("client_id={0}", this._clientId); 
     postData.AppendFormat("&redirect_uri={0}", HttpUtility.UrlEncode(returnUrl.ToString().ToLower())); 
     postData.AppendFormat("&client_secret={0}", this._clientSecret); 
     postData.AppendFormat("&grant_type={0}", "authorization_code"); 
     postData.AppendFormat("&code={0}", authorizationCode); 

     string response = ""; 
     string accessToken = ""; 

     var webRequest = (HttpWebRequest)WebRequest.Create(TokenEndpoint); 

     webRequest.Method = "POST"; 
     webRequest.ContentType = "application/x-www-form-urlencoded"; 

     try 
     { 

      using (Stream s = webRequest.GetRequestStream()) 
      { 
       using (StreamWriter sw = new StreamWriter(s)) 
        sw.Write(postData.ToString()); 
      } 

      using (WebResponse webResponse = webRequest.GetResponse()) 
      { 
       using (var reader = new StreamReader(webResponse.GetResponseStream())) 
       { 
        response = reader.ReadToEnd(); 
       } 
      } 

      var json = JObject.Parse(response); 
      accessToken = (string)json["access_token"]; 
     } 
     catch (Exception ex) 
     { 
      Ccl.Log.Logging.Error("Error requesting OAuth access token from Google", ex); 
      return null; 
     } 

     return accessToken; 
    } 

    public override AuthenticationResult VerifyAuthentication(HttpContextBase context, Uri returnPageUrl) 
    { 
     string code = context.Request.QueryString["code"]; 
     if (string.IsNullOrEmpty(code)) 
     { 
      return AuthenticationResult.Failed; 
     } 

     string accessToken = this.QueryAccessToken(returnPageUrl, code); 
     if (accessToken == null) 
     { 
      return AuthenticationResult.Failed; 
     } 

     IDictionary<string, string> userData = this.GetUserData(accessToken); 
     if (userData == null) 
     { 
      return AuthenticationResult.Failed; 
     } 

     string id = userData["id"]; 
     string name; 

     // Some oAuth providers do not return value for the 'username' attribute. 
     // In that case, try the 'name' attribute. If it's still unavailable, fall back to 'id' 
     if (!userData.TryGetValue("username", out name) && !userData.TryGetValue("name", out name)) 
     { 
      name = id; 
     } 

     // add the access token to the user data dictionary just in case page developers want to use it 
     userData["accesstoken"] = accessToken; 

     return new AuthenticationResult(
      isSuccessful: true, provider: this.ProviderName, providerUserId: id, userName: name, extraData: userData); 
    } 
}