Google 使用 YahooAuthenticationOptions 添加 Yahoo 时出现 Oauth 奇怪问题
Google Oauth strange issue when adding Yahoo with YahooAuthenticationOptions
我添加了 facebook 和 google,它们工作正常(我使用最新的 Owin.Security.Providers 3.0.1)。
但是一旦我添加 yahoo google returns 登录后出现空白页面
(我注意到只有当我先使用 yahoo 登录然后使用 google - 在我的本地主机上测试时才会发生这种情况)
感觉 yahoo 提供者做了一些事情来搞砸 google 提供者...
如果我将 yahoo 代码移到末尾,yahoo 会做同样的事情并且我在登录后得到一个空白页面(并且 google 在这种情况下工作正常)
我还看到了 class 名称 YahooAuthenticationOptions 和 GoogleOAuth2AuthenticationOptions - 这让我想知道为什么雅虎 class 没有命名为 YahooOAuth2AuthenticationOptions...
有没有我可以尝试的更好的雅虎提供商,或者有什么想法可以尝试吗?
这是我正在使用的代码:
#region Yahoo
var yahooAuthOptions = new YahooAuthenticationOptions(); // Same issue if using: Owin.Security.Providers.Yahoo.YahooAuthenticationOptions();
yahooAuthOptions.ConsumerKey = externalProviderManager.YahooAuthConsumerKey;
yahooAuthOptions.ConsumerSecret = externalProviderManager.YahooAuthConsumerSecret;
yahooAuthOptions.CallbackPath = new PathString("/signin-external"); // Note: by default yahoo is looking for a route named "signin-yahoo"
yahooAuthOptions.Provider = new YahooAuthenticationProvider()
{
OnAuthenticated = (context) =>
{
foreach (var claim in context.User)
{
var claimType = string.Format("urn:yahoo:{0}", claim.Key);
var claimValue = claim.Value.ToString();
if (!context.Identity.HasClaim(claimType, claimValue))
context.Identity.AddClaim(new System.Security.Claims.Claim(claimType, claimValue, "XmlSchemaString", "Yahoo"));
}
return Task.FromResult(0);
}
};
app.UseYahooAuthentication(yahooAuthOptions);
#endregion Yahoo
#region Google
var googleAuthOptions = new GoogleOAuth2AuthenticationOptions();
googleAuthOptions.ClientId = externalProviderManager.GoogleAuthClientId;
googleAuthOptions.ClientSecret = externalProviderManager.GoogleAuthClientSecret;
googleAuthOptions.CallbackPath = new PathString("/signin-external");
// googleAuthOptions.Scope.Add("https://www.googleapis.com/auth/plus.me"); // Know who you are on Google
googleAuthOptions.Scope.Add("https://www.googleapis.com/auth/plus.login"); // Know your basic profile info and list of people in your circles.
googleAuthOptions.Scope.Add("https://www.googleapis.com/auth/userinfo.email"); // View your email address
googleAuthOptions.Scope.Add("https://www.googleapis.com/auth/userinfo.profile"); // View your basic profile info
googleAuthOptions.Provider = new GoogleOAuth2AuthenticationProvider
{
OnAuthenticated = (context) =>
{
context.Identity.AddClaim(new System.Security.Claims.Claim("GoogleAccessToken", context.AccessToken));
var expiryDuration = context.ExpiresIn ?? new TimeSpan();
context.Identity.AddClaim(new Claim("urn:google:expires_in", DateTime.UtcNow.Add(expiryDuration).ToString(CultureInfo.InvariantCulture)));
if (context.Email != null) context.Identity.AddClaim(new Claim("urn:google:email", context.Email));
if (context.Id != null) context.Identity.AddClaim(new Claim("urn:google:id", context.Id));
if (context.GivenName != null) context.Identity.AddClaim(new Claim("urn:google:given_name", context.GivenName));
if (context.FamilyName != null) context.Identity.AddClaim(new Claim("urn:google:family_name", context.FamilyName));
if (context.Name != null) context.Identity.AddClaim(new Claim("urn:google:name", context.Name));
if (context.Profile != null) context.Identity.AddClaim(new Claim("urn:google:profile", context.Profile));
// Note: for the birthday value (yyyy/mm/dd) - make sure Google Plus profile allows sharing birthday with public
// Add all other available claims
foreach (var claim in context.User)
{
var claimType = string.Format("urn:google:{0}", claim.Key);
var claimValue = claim.Value.ToString();
if (!context.Identity.HasClaim(claimType, claimValue))
context.Identity.AddClaim(new System.Security.Claims.Claim(claimType, claimValue, "XmlSchemaString", "Google"));
}
return Task.FromResult(0);
}
};
app.UseGoogleAuthentication(googleAuthOptions);
#endregion Google
#region Facebook
var facebookAuthOptions = new FacebookAuthenticationOptions();
facebookAuthOptions.AppId = externalProviderManager.FacebookAuthAppId;
facebookAuthOptions.AppSecret = externalProviderManager.FacebookAuthAppSecret;
facebookAuthOptions.SendAppSecretProof = true;
// public_profile (Default) includes: id,name,first_name,last_name,age_range,link,gender,locale,timezone,updated_time,verified
facebookAuthOptions.Scope.Add("public_profile");
facebookAuthOptions.Scope.Add("email");
facebookAuthOptions.Scope.Add("user_birthday");
facebookAuthOptions.Scope.Add("user_location"); // current city through the location field on the User object
facebookAuthOptions.Provider = new FacebookAuthenticationProvider()
{
OnAuthenticated = (context) =>
{
//
// http://blogs.msdn.com/b/webdev/archive/2013/10/16/get-more-information-from-social-providers-used-in-the-vs-2013-project-templates.aspx
// Get the access token from FB and store it in the database and use FacebookC# SDK to get more information about the user
context.Identity.AddClaim(new System.Security.Claims.Claim("FacebookAccessToken", context.AccessToken));
var expiryDuration = context.ExpiresIn ?? new TimeSpan();
context.Identity.AddClaim(new Claim("urn:facebook:expires_in", DateTime.UtcNow.Add(expiryDuration).ToString(CultureInfo.InvariantCulture)));
// Add all other available claims
foreach (var claim in context.User)
{
var claimType = string.Format("urn:facebook:{0}", claim.Key);
var claimValue = claim.Value.ToString();
if (!context.Identity.HasClaim(claimType, claimValue))
context.Identity.AddClaim(new System.Security.Claims.Claim(claimType, claimValue, "XmlSchemaString", "Facebook"));
}
return Task.FromResult(0);
}
};
app.UseFacebookAuthentication(facebookAuthOptions);
#endregion Facebook
更新:在RouteConfig.cs
#region External Sign-in API redirects
routes.MapRoute(
name: "External Sign-in API redirect for Facebook",
url: "signin-facebook",
defaults: new { controller = "Account", action = "SignUpConnectRedirect", returnUrl = UrlParameter.Optional }
);
routes.MapRoute(
name: "External Sign-in API redirect for Google",
url: "signin-google",
defaults: new { controller = "Account", action = "SignUpConnectRedirect", returnUrl = UrlParameter.Optional }
);
routes.MapRoute(
name: "External Sign-in API redirect for LinkedIn",
url: "signin-linkedin",
defaults: new { controller = "Account", action = "SignUpConnectRedirect", returnUrl = UrlParameter.Optional }
);
routes.MapRoute(
name: "External Sign-in API redirect for Microsoft Live",
url: "signin-microsoft",
defaults: new { controller = "Account", action = "SignUpConnectRedirect", returnUrl = UrlParameter.Optional }
);
routes.MapRoute(
name: "External Sign-in API redirect for Twitter",
url: "signin-twitter",
defaults: new { controller = "Account", action = "SignUpConnectRedirect", returnUrl = UrlParameter.Optional }
);
routes.MapRoute(
name: "External Sign-in API redirect for Yahoo",
url: "signin-yahoo",
defaults: new { controller = "Account", action = "SignUpConnectRedirect", returnUrl = UrlParameter.Optional }
);
#endregion External Sign-in API redirects
这是一个很难解决的问题...
我试图为我的所有外部提供者使用捕获所有回调 URI,
一旦我在 RouteConfig.cs 中分别为每个提供者创建了一个条目,一切都很好
当然还有 - 更新提供商应用程序界面上的所有回调 URI...
我添加了 facebook 和 google,它们工作正常(我使用最新的 Owin.Security.Providers 3.0.1)。
但是一旦我添加 yahoo google returns 登录后出现空白页面 (我注意到只有当我先使用 yahoo 登录然后使用 google - 在我的本地主机上测试时才会发生这种情况)
感觉 yahoo 提供者做了一些事情来搞砸 google 提供者...
如果我将 yahoo 代码移到末尾,yahoo 会做同样的事情并且我在登录后得到一个空白页面(并且 google 在这种情况下工作正常)
我还看到了 class 名称 YahooAuthenticationOptions 和 GoogleOAuth2AuthenticationOptions - 这让我想知道为什么雅虎 class 没有命名为 YahooOAuth2AuthenticationOptions...
有没有我可以尝试的更好的雅虎提供商,或者有什么想法可以尝试吗?
这是我正在使用的代码:
#region Yahoo
var yahooAuthOptions = new YahooAuthenticationOptions(); // Same issue if using: Owin.Security.Providers.Yahoo.YahooAuthenticationOptions();
yahooAuthOptions.ConsumerKey = externalProviderManager.YahooAuthConsumerKey;
yahooAuthOptions.ConsumerSecret = externalProviderManager.YahooAuthConsumerSecret;
yahooAuthOptions.CallbackPath = new PathString("/signin-external"); // Note: by default yahoo is looking for a route named "signin-yahoo"
yahooAuthOptions.Provider = new YahooAuthenticationProvider()
{
OnAuthenticated = (context) =>
{
foreach (var claim in context.User)
{
var claimType = string.Format("urn:yahoo:{0}", claim.Key);
var claimValue = claim.Value.ToString();
if (!context.Identity.HasClaim(claimType, claimValue))
context.Identity.AddClaim(new System.Security.Claims.Claim(claimType, claimValue, "XmlSchemaString", "Yahoo"));
}
return Task.FromResult(0);
}
};
app.UseYahooAuthentication(yahooAuthOptions);
#endregion Yahoo
#region Google
var googleAuthOptions = new GoogleOAuth2AuthenticationOptions();
googleAuthOptions.ClientId = externalProviderManager.GoogleAuthClientId;
googleAuthOptions.ClientSecret = externalProviderManager.GoogleAuthClientSecret;
googleAuthOptions.CallbackPath = new PathString("/signin-external");
// googleAuthOptions.Scope.Add("https://www.googleapis.com/auth/plus.me"); // Know who you are on Google
googleAuthOptions.Scope.Add("https://www.googleapis.com/auth/plus.login"); // Know your basic profile info and list of people in your circles.
googleAuthOptions.Scope.Add("https://www.googleapis.com/auth/userinfo.email"); // View your email address
googleAuthOptions.Scope.Add("https://www.googleapis.com/auth/userinfo.profile"); // View your basic profile info
googleAuthOptions.Provider = new GoogleOAuth2AuthenticationProvider
{
OnAuthenticated = (context) =>
{
context.Identity.AddClaim(new System.Security.Claims.Claim("GoogleAccessToken", context.AccessToken));
var expiryDuration = context.ExpiresIn ?? new TimeSpan();
context.Identity.AddClaim(new Claim("urn:google:expires_in", DateTime.UtcNow.Add(expiryDuration).ToString(CultureInfo.InvariantCulture)));
if (context.Email != null) context.Identity.AddClaim(new Claim("urn:google:email", context.Email));
if (context.Id != null) context.Identity.AddClaim(new Claim("urn:google:id", context.Id));
if (context.GivenName != null) context.Identity.AddClaim(new Claim("urn:google:given_name", context.GivenName));
if (context.FamilyName != null) context.Identity.AddClaim(new Claim("urn:google:family_name", context.FamilyName));
if (context.Name != null) context.Identity.AddClaim(new Claim("urn:google:name", context.Name));
if (context.Profile != null) context.Identity.AddClaim(new Claim("urn:google:profile", context.Profile));
// Note: for the birthday value (yyyy/mm/dd) - make sure Google Plus profile allows sharing birthday with public
// Add all other available claims
foreach (var claim in context.User)
{
var claimType = string.Format("urn:google:{0}", claim.Key);
var claimValue = claim.Value.ToString();
if (!context.Identity.HasClaim(claimType, claimValue))
context.Identity.AddClaim(new System.Security.Claims.Claim(claimType, claimValue, "XmlSchemaString", "Google"));
}
return Task.FromResult(0);
}
};
app.UseGoogleAuthentication(googleAuthOptions);
#endregion Google
#region Facebook
var facebookAuthOptions = new FacebookAuthenticationOptions();
facebookAuthOptions.AppId = externalProviderManager.FacebookAuthAppId;
facebookAuthOptions.AppSecret = externalProviderManager.FacebookAuthAppSecret;
facebookAuthOptions.SendAppSecretProof = true;
// public_profile (Default) includes: id,name,first_name,last_name,age_range,link,gender,locale,timezone,updated_time,verified
facebookAuthOptions.Scope.Add("public_profile");
facebookAuthOptions.Scope.Add("email");
facebookAuthOptions.Scope.Add("user_birthday");
facebookAuthOptions.Scope.Add("user_location"); // current city through the location field on the User object
facebookAuthOptions.Provider = new FacebookAuthenticationProvider()
{
OnAuthenticated = (context) =>
{
//
// http://blogs.msdn.com/b/webdev/archive/2013/10/16/get-more-information-from-social-providers-used-in-the-vs-2013-project-templates.aspx
// Get the access token from FB and store it in the database and use FacebookC# SDK to get more information about the user
context.Identity.AddClaim(new System.Security.Claims.Claim("FacebookAccessToken", context.AccessToken));
var expiryDuration = context.ExpiresIn ?? new TimeSpan();
context.Identity.AddClaim(new Claim("urn:facebook:expires_in", DateTime.UtcNow.Add(expiryDuration).ToString(CultureInfo.InvariantCulture)));
// Add all other available claims
foreach (var claim in context.User)
{
var claimType = string.Format("urn:facebook:{0}", claim.Key);
var claimValue = claim.Value.ToString();
if (!context.Identity.HasClaim(claimType, claimValue))
context.Identity.AddClaim(new System.Security.Claims.Claim(claimType, claimValue, "XmlSchemaString", "Facebook"));
}
return Task.FromResult(0);
}
};
app.UseFacebookAuthentication(facebookAuthOptions);
#endregion Facebook
更新:在RouteConfig.cs
#region External Sign-in API redirects
routes.MapRoute(
name: "External Sign-in API redirect for Facebook",
url: "signin-facebook",
defaults: new { controller = "Account", action = "SignUpConnectRedirect", returnUrl = UrlParameter.Optional }
);
routes.MapRoute(
name: "External Sign-in API redirect for Google",
url: "signin-google",
defaults: new { controller = "Account", action = "SignUpConnectRedirect", returnUrl = UrlParameter.Optional }
);
routes.MapRoute(
name: "External Sign-in API redirect for LinkedIn",
url: "signin-linkedin",
defaults: new { controller = "Account", action = "SignUpConnectRedirect", returnUrl = UrlParameter.Optional }
);
routes.MapRoute(
name: "External Sign-in API redirect for Microsoft Live",
url: "signin-microsoft",
defaults: new { controller = "Account", action = "SignUpConnectRedirect", returnUrl = UrlParameter.Optional }
);
routes.MapRoute(
name: "External Sign-in API redirect for Twitter",
url: "signin-twitter",
defaults: new { controller = "Account", action = "SignUpConnectRedirect", returnUrl = UrlParameter.Optional }
);
routes.MapRoute(
name: "External Sign-in API redirect for Yahoo",
url: "signin-yahoo",
defaults: new { controller = "Account", action = "SignUpConnectRedirect", returnUrl = UrlParameter.Optional }
);
#endregion External Sign-in API redirects
这是一个很难解决的问题...
我试图为我的所有外部提供者使用捕获所有回调 URI,
一旦我在 RouteConfig.cs 中分别为每个提供者创建了一个条目,一切都很好
当然还有 - 更新提供商应用程序界面上的所有回调 URI...