我试图在MVC5项目中使用Microsoft.Owin.Security.Google获取Google帐户的刷新令牌。要从google服务器获取resposne中的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);
答案 0 :(得分:4)
3.0.版的Microsoft.Owin.Security库将把这个选项添加到GoogleOAuth2AuthenticationProvider中(参见fixed issue #227)。根据{{3}},它将于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();
答案 1 :(得分:3)
在当前版本的Microsoft.Owin.Security.Google程序集中无法执行此操作。 但由于这个事实,该库是开源的,您可以通过修改它来获取刷新令牌。
正如我所说,google oauth2.0需要将属性access_type
设置为offline
。您可以在GoogleOAuth2AuthenticationHandler
方法ApplyResponseChallengeAsync()
中添加一个静态行(为了每次都设置此属性 - 不是最佳解决方案,但快速一次修复它),因为添加了查询字符串{{1 }}
答案 2 :(得分:1)
实际上,是这样做的一种方式!我已经用&#34; login_hint&#34;做了类似的事情。查询元素。
当您声明提供程序时,您可以注册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
}
};