【问题标题】:GoogleOAuth2AuthenticationOptions setting access_type as offlineGoogleOAuth2AuthenticationOptions 将 access_type 设置为离线
【发布时间】:2014-04-24 13:57:07
【问题描述】:

我正在尝试在 MVC5 项目中使用 Microsoft.Owin.Security.Google 获取 Google 帐户的刷新令牌。要从谷歌服务器获取响应中的 RefreshToken,我需要设置access_type = offline。但我在 GoogleOAuth2AuthenticationOptions 对象中找不到任何合适的属性。

用于允许身份验证的代码

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

【问题讨论】:

    标签: c# oauth-2.0 asp.net-mvc-5 owin


    【解决方案1】:

    Microsoft.Owin.Security 库的 3.0.0 版将向 GoogleOAuth2AuthenticationProvider 添加此选项(请参阅已修复的 issue #227)。根据Katana Project roadmap,它将在 2014 年夏末推出。如果您在正式发布之前需要此功能,您可以通过预发布 NuGet 渠道获得最新版本。

    然后您可以像这样配置它(在 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);
            }
        });
    

    您可以在 ExternalLoginCallback 中获取刷新令牌(如果您保留默认代码组织,则为 AccountController.cs):

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

    【讨论】:

    • 致那些偶然发现这一点的人。您需要撤销该应用并再次进入同意屏幕以获取此刷新令牌。
    【解决方案2】:

    实际上,一种方法可以做到这一点!我用“login_hint”查询字符串元素做了类似的事情。

    当您声明提供程序时,您可以注册一个 OnApplyRedirect 处理程序并在那里更改 URL:

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

    【讨论】:

    • 不过,再想一想,如果您需要离线访问,您可能应该使用服务帐户..
    • 这对我有用。与使用服务帐户相比,您应该在哪些情况下执行此操作?我需要获取访问和刷新令牌,以便我可以每天离线访问用户的谷歌分析帐户以处理他们的数据,并且我正在使用 OAuth 让他们授予我权限。谢谢!
    【解决方案3】:

    在当前版本的 Microsoft.Owin.Security.Google 程序集中没有办法做到这一点。 但是因为这个库是开源的,你可以通过修改它来获取刷新令牌。

    正如我所说,google oauth2.0 需要将属性access_type 设置为offline。您可以在GoogleOAuth2AuthenticationHandler 方法ApplyResponseChallengeAsync() 中添加一条静态行(每次都设置此属性 - 不是最好的解决方案,但一次修复它的工作速度)作为添加查询字符串AddQueryString(queryStrings, properties, "access_type", "offline")

    【讨论】:

      猜你喜欢
      • 2020-01-28
      • 2015-03-09
      • 2016-10-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-08-12
      • 2020-05-24
      相关资源
      最近更新 更多