我正在尝试使用来自 Microsoft.Owin.Security.Google 的 GoogleAuthenticationExtensions
封装在MVC5程序中。这是我的 StartUp.cs:
var googlePlusOptions = new GoogleOAuth2AuthenticationOptions {};
googlePlusOptions.ClientId = "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX.apps.googleusercontent.com";
googlePlusOptions.AuthorizationEndpoint = "https://accounts.google.com/o/oauth2/auth";
googlePlusOptions.TokenEndpoint = "https://oauth2.googleapis.com/token";
googlePlusOptions.ClientSecret = "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX";
googlePlusOptions.CallbackPath = new PathString("/GoogleLoginCallback");
app.UseGoogleAuthentication(googlePlusOptions);
以及 LoginController 中的 SignInMethod 方法:
[HttpGet]
[AllowAnonymous]
public void SignInGoogle(string ReturnUrl = "/", string type = "")
{
if (!Request.IsAuthenticated)
{
if (type == "Google")
{
var owinContext = HttpContext.GetOwinContext();
owinContext.Authentication.Challenge(new AuthenticationProperties { RedirectUri = "Login/GoogleLoginCallback" }, "Google");
Response.StatusCode = 401;
Response.End();
}
}
}
和回调 URL 在同一 Controller 中:
[AllowAnonymous]
public ActionResult GoogleLoginCallback()
{
var claimsPrincipal = HttpContext.User.Identity as ClaimsIdentity;
var loginInfo = GoogleLoginViewModel.GetLoginInfo(claimsPrincipal);
if (loginInfo == null)
{
return RedirectToAction("Index");
}
var user = db.UserAccounts.FirstOrDefault(x => x.Email == loginInfo.emailaddress);
if (user == null)
{
user = new UserAccount
{
Email = loginInfo.emailaddress,
GivenName = loginInfo.givenname,
Identifier = loginInfo.nameidentifier,
Name = loginInfo.name,
SurName = loginInfo.surname,
IsActive = true
};
db.UserAccounts.Add(user);
db.SaveChanges();
}
var ident = new ClaimsIdentity(
new[] {
// adding following 2 claim just for supporting default antiforgery provider
new Claim(ClaimTypes.NameIdentifier, user.Email),
new Claim("http://schemas.microsoft.com/accesscontrolservice/2010/07/claims/identityprovider", "ASP.NET Identity", "http://www.w3.org/2001/XMLSchema#string"),
new Claim(ClaimTypes.Name, user.Name),
new Claim(ClaimTypes.Email, user.Email),
// optionally you could add roles if any
new Claim(ClaimTypes.Role, "User")
},
CookieAuthenticationDefaults.AuthenticationType);
HttpContext.GetOwinContext().Authentication.SignIn(
new AuthenticationProperties { IsPersistent = false }, ident);
return Redirect("~/");
}
现在程序进入 Google 的登录屏幕,但是当它返回回调 URL 时
loginInfo 为空。这是回调 URL 的响应:
到目前为止我所做的事情没有任何结果: 1-激活Google+ APi 2-将nuget更新到最新版本(4.2 atm) 3-将电子邮件添加到 TestUser 或将 google console 内的项目更改为生产 4-在谷歌控制台中添加并填写同意部分 5-设置js回调为空
有一点奇怪的是,如果我修改 ClientId,谷歌的登录屏幕将阻止我,但如果我更改 SecretId,什么也不会发生,但我仍然看到上面的错误。 我今天从 OAuth 控制台面板获得了它们(ClientId、SecretId)。
最佳答案
对于此类问题,如果不重新创建完整的环境设置,就很难准确指出问题所在。因此,我只能尝试解释正在发生的事情,但为了获得更精确的解决方案,您必须深入研究它。
基本上,我不确定您对 OpenIDConnect 和 OAuth2.0 流程了解多少,但我可以描述您的场景中发生的情况。
- 您的应用程序正在将用户重定向到 Google 登录页面
- 用户正在登录
- 成功登录后,Google 将使用这些查询参数将用户浏览器重定向回您的应用程序(屏幕截图中的第三行)
- 现在,您的应用程序应该获取这些参数,并通过反向 channel (服务器到服务器请求)将其发送到 google,以将其与 google 交换
access_token
。这是一个棘手的部分 - 可能您认为您正在立即执行GoogleLoginCallback
方法 - 但您没有。真正发生的事情是 GoogleAuthentication 中间件正在承担这一责任。它确定该请求是 OpenIDConnect 流程的一部分,并将尝试为您获取 token 并在您的上下文中设置身份。 - 不幸的是,出现了问题,因为您使用
?error=access_denied
参数进行了另一个重定向。这正是通过 Katana 项目的GoogleOAuth2AuthenticationHandler
实现来完成的:https://github.com/aspnet/AspNetKatana/blob/beb224c88712b08ce45f1d14bb8cf0cd9d4a8503/src/Microsoft.Owin.Security.Google/GoogleOAuth2AuthenticationHandler.cs#L259这是执行此操作的代码。我认为您应该使用此存储库来识别流程以及可能出现的问题(看起来您的context.Identity
由于某种原因为null
)。 - 现在,在该重定向上,您终于执行了 Controller 方法
GoogleLoginCallback
但我猜是因为上一步失败了 - 我们在该请求中没有正确的身份状态。
您尚未共享更多 Startup.cs
,但您应该使用 .UseCookieAuthentication()
,如 Katana 示例 https://github.com/aspnet/AspNetKatana/blob/beb224c88712b08ce45f1d14bb8cf0cd9d4a8503/samples/Katana.Sandbox.WebServer/Startup.cs#L83 中所示
我认为您需要更改的肯定是您需要更改或删除用于识别 OpenID 流程步骤的设置 CallbackPath
属性 https://github.com/aspnet/AspNetKatana/blob/beb224c88712b08ce45f1d14bb8cf0cd9d4a8503/src/Microsoft.Owin.Security.Google/GoogleOAuth2AuthenticationHandler.cs#L224 。此回调仅用于交换访问 token ,默认值为 /signin-google
https://github.com/aspnet/AspNetKatana/blob/dbe159e43e2eee44f315f26268943e8ab5a4f60d/src/Microsoft.Owin.Security.Google/GoogleOAuth2AuthenticationOptions.cs#L28因此,每次您尝试访问 Controller 方法时,GoogleAuthenticationHandler 都会启动。
很抱歉,如果这仍然没有帮助。但我认为你应该有足够的资源来慢慢找到你的解决方案。如果您仍然无法识别问题,我建议您将 Katana github 中的类复制到您的项目中,重命名,然后整个流程应该是“可调试的”。
并回答你的最后一个问题:
- ClientId 在流程的初始步骤中使用,因此会提前失败
- ClientSecret 用于 token 交换步骤 https://github.com/aspnet/AspNetKatana/blob/beb224c88712b08ce45f1d14bb8cf0cd9d4a8503/src/Microsoft.Owin.Security.Google/GoogleOAuth2AuthenticationHandler.cs#L71因此用户将登录 Google,但您的应用程序将无法在反向 channel 中从 google 检索 token ,因为 Secret 无效 - 这就是行为相似的原因
关于asp.net-mvc - GoogleOAuth2 总是返回拒绝访问回调 url,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/72027164/