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);
}
}