0

I am facing the same issue as mentioned in AuthenticationResult.IsSuccessful started returning false for google

I am using MVC 4 Web Api application and migrating it to MVC 5 would be a big change. Is somebody else facing the same issue ?

Are there any samples on how to use DotnetOpenAuth.OAuth2 so that I can skip migrating to DotnetOpenAuth.GoogleOAuth2 in a MVC 5 app.

4

1 Answer 1

1

In case someone still need to use Google OpenID Connect in MVC 4 here is a code:

In AuthConfig.cs write:

OAuthWebSecurity.RegisterClient(new GoogleCustomClient("YoutGoogleAPIKey", "GoogleSecret"), "Google", null);

and the GoogleCustomClient class (based on a LinkedIn oAuth example I found):

using DotNetOpenAuth.AspNet;
using DotNetOpenAuth.AspNet.Clients;
using DotNetOpenAuth.OAuth;
using System;
using System.Collections.Generic;
using System.IO;
using System.Net;
using System.Text;
using System.Text.RegularExpressions;
using System.Web;
using System.Web.Script.Serialization;


namespace MyProject.CustomProviders
{
public class GoogleCustomClient : OAuth2Client
{
    #region Constants and Fields
    private const string AuthorizationEndpoint = "https://accounts.google.com/o/oauth2/auth";
    private const string TokenEndpoint = "https://accounts.google.com/o/oauth2/token";
    private readonly string _clientId;
    private readonly string _clientSecret;
    private string absoluteReturnUrl = string.Empty;
    #endregion

    public GoogleCustomClient(string clientId, string clientSecret) : base("Google")
    {
        this._clientId = clientId;
        this._clientSecret = clientSecret;
    }

    protected override Uri GetServiceLoginUrl(Uri returnUrl)
    {
        StringBuilder serviceUrl = new StringBuilder();
        serviceUrl.AppendFormat("{0}?", AuthorizationEndpoint);
        serviceUrl.Append("response_type=code");
        serviceUrl.AppendFormat("&client_id={0}", this._clientId);
        serviceUrl.Append("&scope=email");
        absoluteReturnUrl = Regex.Match(returnUrl.ToString(), "https://(\\d|\\w|\\/|:|\\.){1,}").Value;
        serviceUrl.AppendFormat("&redirect_uri={0}", Uri.EscapeDataString(absoluteReturnUrl));
        serviceUrl.AppendFormat("&state={0}", Regex.Match(returnUrl.AbsoluteUri, "(?<=__sid__=).*?($|&)", RegexOptions.IgnoreCase).Value);
        return new Uri(serviceUrl.ToString());
    }

    protected override IDictionary<string, string> GetUserData(string accessToken)
    {
        var request = WebRequest.Create("https://www.googleapis.com/oauth2/v1/userinfo?access_token=" + Uri.EscapeDataString(accessToken));

        string responseText = string.Empty;
        using (var response = request.GetResponse())
        {
            using (var responseStream = response.GetResponseStream())
            {
                using (var reader = new StreamReader(responseStream, Encoding.UTF8))
                {
                    responseText = reader.ReadToEnd();
                }
            }
        }
        Dictionary<string, string> userData = new Dictionary<string, string>();
        JavaScriptSerializer deserializer = new JavaScriptSerializer();
        Dictionary<string, string> responseData = deserializer.Deserialize<Dictionary<string, string>>(responseText);
        userData.Add("id", responseData["id"]);
        userData.Add("firstname", responseData["given_name"]);
        userData.Add("lastname", responseData["family_name"]);
        userData.Add("emailAddress", responseData["email"]);
        userData.Add("picture", responseData["picture"]);
        userData.Add("accesstoken", "");
        userData.Add("allData", responseText);
        return userData;
    }

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

        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 (StreamReader reader = new StreamReader(webResponse.GetResponseStream()))
                {
                    response = reader.ReadToEnd();
                }
            }

            JavaScriptSerializer deserializer = new JavaScriptSerializer();
            var userData = deserializer.Deserialize<Dictionary<string, string>>(response);
            accessToken = (string)userData["access_token"];
        }
        catch (Exception)
        {
            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 email = userData["emailAddress"];
        string id = userData["id"];

        userData["accesstoken"] = accessToken;

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

And for some reason OAuthWebSecurity.VerifyAuthentication in the function "ExternalLoginCallback" is not going to the right class so here is a workaround:

AuthenticationResult result = ((GoogleCustomClient)OAuthWebSecurity.GetOAuthClientData("google").AuthenticationClient).VerifyAuthentication(this.HttpContext, uri);
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.