DotNetOpenAuth 4.3 and Google - OpenID 2.0 + OAuth 1.0 deprecated
Asked Answered
M

2

11

If you want to cut to the chase, the question is: what is the best/official way to use DotNetOpenAuth with Google in asp.net mvc 5?

About a year ago, I used OAuth (DotNetOpenAuth oAuth and OpenID) pretty much as it came out of the box for asp.net MVC 4 (as it is in the sample project). Since then I used it successfully for google, facebook, yahoo and microsoft. However, recently I have been having intermittent problems with users signing into google. I have tried upgrading to MVC 5 and DotNetOpenAuth 4.3, but I get the same.

When I looked at the google docs I found this:

Important: Google has deprecated its support for OAuth 1.0. If you are using OpenID 2.0 + OAuth 1.0, we recommend that you switch to Google+ Sign-In. Google+ Sign-In provides the OAuth 2.0 authentication mechanism with rich social features and access to additional Google desktop and mobile features. It supports all Google users and transparent migration. For details, see the Migration of Google authentication.

I could very well be mistaken, by I thought that out-of-the-box asp.net mvc 4 DotNetOpenAuth uses OpenID 2.0 (I use minimumRequiredOpenIdVersion="V20") + OAuth 1.0. I can see in the DotNetOpenAuth source that there is an OAuth 2.0 library under 'product', but I am not sure how to use this. Also, I am a bit nervous about Auth 2.0 as what I have read is not very complementary and it seems that it is easier to shoot oneself in the foot (might be unfounded, but it seems to be a recurring theme).

For Google+ I found these instructions which seem pretty straightforward, but that is almost a year ago, so I am wondering if this is still the best way to go. I also found this git repository implementing Google oauth2. Still, I would like to know whether this is still relevant as it is all from some time ago.

So, the question is - what is the best/official way to use DotNetOpenAuth with Google in asp.net mvc5? Hopefully I haven't missed anything obvious, in which case just a pointer to some links will be fine.

Update I found this question and this question which are related. I guess that I will go with the google auth2 from git unless I am told otherwise.

Resolution

I did the following: -

  • Followed the steps in the link provided by the accepted answer. It is this link.

It's important to keep using SSL after login and not drop back to HTTP, your login cookie is just as secret as your username and password…redirecting back to HTTP after you’re logged in won’t make the current request or future requests much faster.

  • Got the latest DotNetOpenAuth.GoogleOAuth2 on Nuget.

  • I looked at the recommendation from this msdn blog (by the same author) about how to best to secure the site. Basically, the recommendation is to add the following which will force all pages to HTTPS:

    filters.Add( new System.Web.Mvc.RequireHttpsAttribute() );

Ultimately what this means is that the whole site is HTTPS. Since making those changes, the site has been running fine.

Marpet answered 29/1, 2014 at 0:53 Comment(3)
Hi. Is it possible to use OAuth 2 for Google Authentication from MVC 4? Or should I first upgrade my project to MVC 5? Did you follow any guidelines to do such an upgrade? Thanks!Aegis
@Aegis - I upgraded to MVC 5 to do this, while remaining on Visual Studio 2012. I can't recall the exact steps, but I am pretty sure I followed the instructions in these sites: asp.net/mvc/overview/releases/… #19103331 blogs.msdn.com/b/webdev/archive/2013/11/18/….Marpet
Thanks @acarlon, I'm on VS2013. I have migrated the app, but with no success. I get an HTTP 500 error when trying to debug. I'm trying to find out what it's missing or not correctly configured.Aegis
A
5

Here is the recommended way to use Google authentication as well as a few other social integrations:

http://www.asp.net/mvc/tutorials/mvc-5/create-an-aspnet-mvc-5-app-with-facebook-and-google-oauth2-and-openid-sign-on

In order to use oauth2 (assuming your using MVC)

  1. Enable the Google OpenID provider Open the App_Start\Startup.Auth.cs file and remove the comment characters in //app.UseGoogleAuthentication(); to enable Google authentication.

  2. Under Use another service to log in, click Google. The user is then redirected to the google site where you will enter your credentials.

If you don't have this file or folder "app_start", then you probably created a 'blank' project, instead of an "internet" project when you first created the solution. It's much easier (if planning on using external logins) to select 'internet application' when you first begin. Not sure what editor your using, but Visual Studio 2012/2013 make this ridiculously easy!

If your going to use OpenID which is now the recommended way, here is a great starting point: https://developers.google.com/accounts/docs/OpenID#settingup

Lastly, if you have access to NUGET through your editor like (Visual studio) , you'll find these tasks, like adding oAuth-1/2 or openId have been made very easy..

Here is a last link that would get you off in the right direction if the above doesn't really fit your build... With a few more details, I would be more than happy to help guide you to the best solution. One thing I can say is that oauth2 IS still very relevant and used in many applications today, and you wouldn't be wrong implementing this while starting a new project today - it would be the right way to go (or at least one of the right ways to go)... Hope some of this helps and isn't just going down a path you have already been down.

Hope all is well.

Alissaalistair answered 29/1, 2014 at 6:15 Comment(2)
Ah, thank you. I somehow missed that link. That should be easier than what I originally had planned.Marpet
No problem! These things used to be so much more trivial. .NET has really come a long way even just in the last 2 years or so, where things like this are all good to go out of the box. This way we can all focus on "All the solutions and business logic for a user AFTER they can get through the door ;) Glad I could help!Alissaalistair
H
9

This is how you use DotnetOpenAuth with Google/OAuth2.

First, reference the DotnetOpenAuth.Ultimate package from Nuget.

Then create a provider class and the profile model class

public class GoogleClient : WebServerClient
{
    private static readonly AuthorizationServerDescription GoogleDescription = 
        new AuthorizationServerDescription
    {
        TokenEndpoint = new Uri( "https://accounts.google.com/o/oauth2/token" ),
        AuthorizationEndpoint = new Uri( "https://accounts.google.com/o/oauth2/auth" ),
        ProtocolVersion = ProtocolVersion.V20
    };

    public const string ProfileEndpoint = "https://www.googleapis.com/oauth2/v1/userinfo";

    public const string ProfileScope = "https://www.googleapis.com/auth/userinfo.profile";
    public const string EmailScope = "https://www.googleapis.com/auth/userinfo.email";

    public GoogleClient()
        : base( GoogleDescription )
    {
    }
}

public class GoogleProfileAPI
{
    public string email { get; set; }

    private static DataContractJsonSerializer jsonSerializer = 
        new DataContractJsonSerializer( typeof( GoogleProfileAPI ) );

    public static GoogleProfileAPI Deserialize( Stream jsonStream )
    {
        try
        {
            if ( jsonStream == null )
            {
                throw new ArgumentNullException( "jsonStream" );
            }

            return (GoogleProfileAPI)jsonSerializer.ReadObject( jsonStream );
        }
        catch ( Exception ex )
        {
            return new GoogleProfileAPI();
        }
    }
}

Then, in your login page (login controller) have this code:

    private static readonly GoogleClient googleClient = new GoogleClient
    {
        ClientIdentifier = "client_id",
        ClientCredentialApplicator = ClientCredentialApplicator.PostParameter( "client_secret" )
    };

        // Page_Load of login page if WebForms
        // Login action of the Account controller if MVC 

        IAuthorizationState authorization = googleClient.ProcessUserAuthorization();
        if ( authorization == null )
        {
            // Kick off authorization request
            // Google will redirect back here
            Uri uri = new Uri( "http://your.application.address/login" );
            googleClient.RequestUserAuthorization( returnTo: uri, 
                scope: new[] { GoogleClient.ProfileScope, GoogleClient.EmailScope } );
        }
        else
        {
            // authorization. we have the token and 
            // we just go to profile APIs to get email (and possibly other data)
            var request =
                WebRequest.Create(
                    string.Format( "{0}?access_token={1}", 
                    GoogleClient.ProfileEndpoint, 
                    Uri.EscapeDataString( authorization.AccessToken ) ) );
            using ( var response = request.GetResponse() )
            {
                using ( var responseStream = response.GetResponseStream() )
                {
                    var profile = GoogleProfileAPI.Deserialize( responseStream );
                    if ( profile != null &&
                        !string.IsNullOrEmpty( profile.email ) )
                        FormsAuthentication.RedirectFromLoginPage( profile.email, false );
                }
            }
        }
Hadik answered 29/1, 2014 at 7:50 Comment(7)
Thanks, I will use this for reference. I think the link that battery1 provided has most of the info I need, so I will go with that as the answer.Marpet
@acarlon: No problem. Note however, that your question was specifically about DotnetOpenAuth and my answer addresses it precisely.Hadik
Agreed that is why I +1. Since the mvc5 approach looks simpler at this moment I will go with that.Marpet
Would this solution work for ASP.NET MVC 4? Or is it required to upgrade to MVC 5? Thanks!Aegis
I'm going to use this, as I've had to opt for DotNetOpenAuth due to a custom database solution. Thanks for the info.Cheder
I've been battling with this issue for hours, thanks for your response. Also have a custom databse, formsauth...not suitable for new OwinAssembly. Looking at the DotNetOpenAuth code there is no MVC sample. Yours worked just fine. p.s.: I did not use the Ultimate, but regular DotNetOpenAuth with the dependencies.Perplex
@Wiktor Zychla - Perhaps you have example for facebook / twitter ?Chlorous
A
5

Here is the recommended way to use Google authentication as well as a few other social integrations:

http://www.asp.net/mvc/tutorials/mvc-5/create-an-aspnet-mvc-5-app-with-facebook-and-google-oauth2-and-openid-sign-on

In order to use oauth2 (assuming your using MVC)

  1. Enable the Google OpenID provider Open the App_Start\Startup.Auth.cs file and remove the comment characters in //app.UseGoogleAuthentication(); to enable Google authentication.

  2. Under Use another service to log in, click Google. The user is then redirected to the google site where you will enter your credentials.

If you don't have this file or folder "app_start", then you probably created a 'blank' project, instead of an "internet" project when you first created the solution. It's much easier (if planning on using external logins) to select 'internet application' when you first begin. Not sure what editor your using, but Visual Studio 2012/2013 make this ridiculously easy!

If your going to use OpenID which is now the recommended way, here is a great starting point: https://developers.google.com/accounts/docs/OpenID#settingup

Lastly, if you have access to NUGET through your editor like (Visual studio) , you'll find these tasks, like adding oAuth-1/2 or openId have been made very easy..

Here is a last link that would get you off in the right direction if the above doesn't really fit your build... With a few more details, I would be more than happy to help guide you to the best solution. One thing I can say is that oauth2 IS still very relevant and used in many applications today, and you wouldn't be wrong implementing this while starting a new project today - it would be the right way to go (or at least one of the right ways to go)... Hope some of this helps and isn't just going down a path you have already been down.

Hope all is well.

Alissaalistair answered 29/1, 2014 at 6:15 Comment(2)
Ah, thank you. I somehow missed that link. That should be easier than what I originally had planned.Marpet
No problem! These things used to be so much more trivial. .NET has really come a long way even just in the last 2 years or so, where things like this are all good to go out of the box. This way we can all focus on "All the solutions and business logic for a user AFTER they can get through the door ;) Glad I could help!Alissaalistair

© 2022 - 2024 — McMap. All rights reserved.