eCorke
eCorke

Reputation: 868

GoogleOAuth2AuthenticationOptions setting access_type as offline

I'm trying to obtain Refresh token for Google Account using Microsoft.Owin.Security.Google in MVC5 project. To obtain RefreshToken in resposne from google server, I need to set access_type = offline. But I can't find any suitable property in GoogleOAuth2AuthenticationOptions object for that.

Code using to allow authentication

        var gao = new GoogleOAuth2AuthenticationOptions
        {
            ClientId = ConfigurationManager.AppSettings.Get("GoogleClientId"),
            ClientSecret = ConfigurationManager.AppSettings.Get("GoogleClientSecret"),
            Provider = new GoogleOAuth2AuthenticationProvider
            {
                OnAuthenticated = async ctx =>
                {
                    var refreshToken = ctx.RefreshToken;
                    //ctx.Identity.AddClaim(new Claim("refresh_token", refreshToken));                    
                }
            }
        };

        gao.Scope.Add(TasksService.Scope.Tasks);
        gao.Scope.Add("openid");

        app.UseGoogleAuthentication(gao);

Upvotes: 8

Views: 4014

Answers (3)

stefann
stefann

Reputation: 1075

Release 3.0.0 of the Microsoft.Owin.Security library will be adding this option to the GoogleOAuth2AuthenticationProvider (see fixed issue #227). According to Katana Project roadmap it will be available late summer 2014. If you need this ability before the official release you can get the latest build through the pre-release NuGet channel.

You can then configure it like so (in Startup.Auth.cs):

app.UseGoogleAuthentication(new Microsoft.Owin.Security.Google.GoogleOAuth2AuthenticationOptions {
    ClientId = ...,
    ClientSecret = ...,
    AccessType = "offline",
    Provider = new Microsoft.Owin.Security.Google.GoogleOAuth2AuthenticationProvider {
        OnAuthenticated = context => {
            if (!String.IsNullOrEmpty(context.RefreshToken)) {
                context.Identity.AddClaim(new Claim("RefreshToken", context.RefreshToken));
            }
            return Task.FromResult<object>(null);
        }
    });

And you can obtain the refresh token in ExternalLoginCallback (AccountController.cs if you kept the default code organization):

string refreshToken = loginInfo.ExternalIdentity.Claims
    .Where(i => i.Type == "RefreshToken")
    .Select(i => i.Value)
    .SingleOrDefault();

Upvotes: 5

Chris Wood
Chris Wood

Reputation: 531

Actually, there is a way of doing this! I've done something similar with the "login_hint" querystring element.

When you declare the provider you can register an OnApplyRedirect handler and change the URL there:

this.Provider = new Microsoft.Owin.Security.Google.GoogleOAuth2AuthenticationProvider
        {
            OnApplyRedirect = async context =>
                {
                    string redirect = context.RedirectUri;

                    // Change the value of "redirect" here
                    // e.g. append access_type=offline

                    context.Response.Redirect(redirect);
                },
            OnAuthenticated = async context =>
            {
                // Do stuff
            }
        };

Upvotes: 1

eCorke
eCorke

Reputation: 868

There is NO way to do this in current version of Microsoft.Owin.Security.Google assembly. But because of the fact, that library is open source you can modify it in the way to get refresh token.

As I said, google oauth2.0 needs to have setted property access_type to offline. You can achieve this adding one static line (to has this property setted each time - not the best solution, but as fast one time fix it works) in GoogleOAuth2AuthenticationHandler method ApplyResponseChallengeAsync() as adding query string AddQueryString(queryStrings, properties, "access_type", "offline").

Upvotes: 3

Related Questions