2014-04-22 42 views
0

我試圖在我的網站中使用YahooJapan(Yconnect)作爲socail登錄,並且我決定使用DotNetOpenAuth.AspNet.But我無法獲取它工作(actrully,訪問授權端點的第一步),我總是會在VerifyAuthentication方法中得到一個空代碼。我想我的AuthorizationForAspNet方法可能有問題(也許這些步驟的順序是錯誤的)。 請幫助我,謝謝。如何使用DotNetOpenAuth.AspNet提供社交登錄,而我使用MVC3

下面是控制器:

public virtual ActionResult ExternalLogin(int providerNo, string returnAction = "Login") 
    { 
     if (provider == Provider.Yahoo) 
     { 
      state = OAuth2Provider.AuthorizationForAspNet(provider); 
     } 
    } 

下面是在類OAuth2Provider的AuthorizationForAspNet方法: (網址「https://開頭**** /用戶/ ExternalLogin ?providerNo = 4" 是我通過returnUri,我決定在YahooDeveloperConsole)**

public static OAuth2State AuthorizationForAspNet(Provider provider) 
    { 
     var YahooClient = new YahooClient(
     clientId: clients[provider].AppID, clientSecret: clients[provider].AppSecret); 

     OAuthWebSecurity.RegisterClient(YahooClient); 

     OAuthWebSecurity.RequestAuthentication("yahoo"); 

     AuthenticationResult result = YahooClient.VerifyAuthentication(new HttpContextWrapper(HttpContext.Current), new System.Uri("https://******/User/ExternalLogin?providerNo=4")); 
    } 

,以下是我定製YahooClient:

public class YahooClient : DotNetOpenAuth.AspNet.Clients.OAuth2Client 
{ 
    private static string Escape(string target) 
    { 
     return Uri.EscapeDataString(target); 
    } 

    private const string AuthorizationEndpoint = "https://auth.login.yahoo.co.jp/yconnect/v1/authorization"; 
    private const string TokenEndpoint = "https://auth.login.yahoo.co.jp/yconnect/v1/token"; 
    private const string UserDetailsEndPoint = "https://userinfo.yahooapis.jp/yconnect/v1/attribute"; 

    private readonly string _clientId; 

    private readonly string _clientSecret; 

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

     if (string.IsNullOrWhiteSpace(clientSecret)) 
      throw new ArgumentNullException("clientSecret"); 

     _clientId = clientId; 
     _clientSecret = clientSecret; 

    } 

    protected override Uri GetServiceLoginUrl(Uri returnUrl) 
    { 
     string sid = String.Empty; 
     if (returnUrl.ToString().Contains("__sid__")) 
     { 
      int index = returnUrl.ToString().IndexOf("__sid__") + 8; 
      int len = returnUrl.ToString().Length; 
      sid = returnUrl.ToString().Substring(index, len - index - 1); 
     } 

     string redirectUri = (returnUrl.ToString().Contains("&"))?(returnUrl.ToString().Substring(0, returnUrl.ToString().IndexOf("&"))):(returnUrl.ToString()); 

     var builder = new UriBuilder(AuthorizationEndpoint); 
     builder.Query = string.Join("&", 
      "response_type=code", 
      "client_id=" + Escape(_clientId), 
      "redirect_uri=" + Escape(redirectUri), 
      "scope=" + Escape("openid profile"), 
      "state=" + sid); 
     return builder.Uri; 
    } 

    protected override IDictionary<string, string> GetUserData(string accessToken) 
    { 
     // UserInfo API 
     var builder = new UriBuilder(UserDetailsEndPoint); 
     builder.Query = string.Join("&", "schema=openid"); 

     var request = WebRequest.Create(builder.Uri); 

     request.Headers.Add("Authorization", "Bearer " + Escape(accessToken)); 

     using (var response = (HttpWebResponse)request.GetResponse()) 
     { 
      if (response.StatusCode != HttpStatusCode.OK) return null; 

      var json = response.GetResponseBody(); 
      var userData = JObject.Parse(json); 
      if (userData == null) return null; 

      return new Dictionary<string, string>() 
       .AddIfNotEmpty("id", (string)userData["user_id"]) 
       .AddIfNotEmpty("username", (string)userData["name"]); 
     } 
    } 

    protected override string QueryAccessToken(Uri returnUrl, string authorizationCode) 
    { 
     var request = WebRequest.Create(TokenEndpoint); 
     request.ContentType = "application/x-www-form-urlencoded"; 
     request.Method = "POST"; 

     // Basic 
     var credentials = Convert.ToBase64String(Encoding.UTF8.GetBytes(_clientId + ":" + _clientSecret)); 
     request.Headers.Add("Authorization", "Basic " + credentials); 

     var postData = string.Join("&", 
      "grant_type=authorization_code", 
      "code=" + Escape(authorizationCode), 
      "redirect_uri=" + Escape(returnUrl.AbsoluteUri)); 

     request.ContentLength = postData.Length; 
     using (var stream = request.GetRequestStream()) 
     using (var writer = new StreamWriter(stream)) 
     { 
      writer.Write(postData); 
      writer.Flush(); 
     } 

     using (var response = (HttpWebResponse)request.GetResponse()) 
     { 
      if (response.StatusCode != HttpStatusCode.OK) return null; 

      var json = response.GetResponseBody(); 
      var tokenData = JObject.Parse(json); 
      if (tokenData == null) return null; 

      return (string)tokenData["access_token"]; 
     } 

    } 

    public override AuthenticationResult VerifyAuthentication(HttpContextBase context, Uri returnPageUrl) 
    { 
     string code = context.Request.QueryString["code"]; 
     string u = context.Request.Url.ToString(); 

     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["user_id"]; 
     string name = string.Empty; 

     return new AuthenticationResult(
      isSuccessful: true, provider: "yahoo", providerUserId: id, userName: name, extraData: userData); 
    } 

    public override void RequestAuthentication(HttpContextBase context, Uri returnUrl) 
    { 
     base.RequestAuthentication(context, returnUrl); 
    } 
} 

回答

0

這個工程。

 if (provider == Provider.Yahoo) 
     { 
      DotNetOpenAuth.AspNet.AuthenticationResult result; 
      var YahooClient = new YahooClient(clientId: clients[provider].AppID, clientSecret: clients[provider].AppSecret); 
      var context = HttpContext.Current; 

      //the second time 
      if (!String.IsNullOrEmpty(context.Request.QueryString.ToString()) && (context.Request.QueryString.ToString().Contains("code"))) 
      { 
       result = YahooClient.VerifyAuthentication(new HttpContextWrapper(context), new Uri(returnUrl)); 
       if (result.IsSuccessful) 
       { 
        //Success; 
       } 
      } 
      //the first time 
      else 
      { 
       OAuthWebSecurity.RegisterClient(YahooClient, "yahoo"); 
       OAuthWebSecurity.RequestAuthentication("yahoo"); 
      } 
     } 
相關問題