如何在使用 MVC3 时使用 DotNetOpenAuth.AspNet 提供社交登录



我正试图在我的网站中使用YahooJapan(Yconnect)作为socail登录,我决定使用DotNetOpenAuth.AspNet.但是我无法让它工作(实际上,访问授权端点的第一步),我在VerifyAuthentication方法中总是得到一个空代码。我想我的AuthorizationForAspNet方法可能有问题(可能步骤顺序错误)。请帮帮我,谢谢。

以下是控制器:

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

以下是类OAuth2Provider中的AuthorizationForAspNet方法:(url"https://***/User/ExternalLogin?providerNo=4"是我在YahooDeveloperConsole中决定的returnURI)**

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

这是有效的。

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

相关内容

  • 没有找到相关文章

最新更新