You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

如何在ASP.NET MVC 5中处理Google OAuth2授权错误回调?

解决Google认证授权错误无法回调到ASP.NET MVC5应用的问题

我之前也遇到过一模一样的情况——当把Google OAuth应用设置为仅限公司内部账号使用时,非公司账号登录会被Google直接拦截,跳不到我们自己的错误页。这其实是Google的默认机制,但我们可以通过两种方式解决:

方法1:在Google Cloud Console配置自定义错误跳转(优先推荐)

Google其实提供了配置自定义授权错误页面的选项,步骤很简单:

  • 登录Google Cloud Console,找到你的OAuth 2.0客户端ID对应的项目
  • 进入OAuth同意屏幕页面,拉到页面底部的错误处理区块
  • 授权错误URL中填入你的应用错误页面地址,比如 https://your-app-url/Account/AccessDenied
  • 保存配置,等个几分钟让设置生效

这样当用户用非公司账号尝试登录时,Google就会直接跳转到你指定的这个页面,而不是它自带的错误页。

方法2:在应用内添加二次校验(兜底保障)

就算配置了上面的跳转,也建议在应用内部再加一层校验,防止出现绕过的情况。你可以修改Startup.Auth.cs里的Google认证Provider,添加邮箱域名校验和跳转逻辑:

_options.Provider = new GoogleOAuth2AuthenticationProvider() {
    OnAuthenticated = async context => {
        // 你原有的处理代码保持不变
        string claimType;
        bool bAddClaim = false;
        foreach (var claim in context.User) {
            claimType = string.Empty;
            bAddClaim = false;
            switch (claim.Key) {
                case "picture":
                    claimType = "Picture";
                    bAddClaim = true;
                    break;
            }
            if (bAddClaim) {
                string claimValue = claim.Value.ToString();
                if (!context.Identity.HasClaim(claimType, claimValue))
                    context.Identity.AddClaim(new System.Security.Claims.Claim(claimType, claimValue, "XmlSchemaString", "Google"));
            }
        }

        // 新增:校验用户邮箱是否属于公司域名
        var emailClaim = context.Identity.FindFirst(System.Security.Claims.ClaimTypes.Email);
        if (emailClaim == null || !emailClaim.Value.EndsWith("@your-company-domain.com")) {
            // 用Owin上下文标记该用户无权限
            context.OwinContext.Set("GoogleAuth:AccessDenied", true);
        }
    },
    OnReturnEndpoint = async context => {
        // 检查是否被标记为无权限
        if (context.OwinContext.Get<bool?>("GoogleAuth:AccessDenied") == true) {
            // 重定向到自定义错误页
            context.Response.Redirect("/Account/AccessDenied");
            context.RequestCompleted(); // 终止后续流程
        }
    }
};

然后在你的AccountController里添加对应的错误页动作:

public ActionResult AccessDenied()
{
    ViewBag.ErrorMessage = "抱歉,你没有权限访问此应用,请使用公司邮箱账户登录。";
    return View();
}

额外提示

  • 两种方法结合使用效果最好:方法1解决Google端的跳转问题,方法2在应用内做兜底校验
  • 配置Google的授权错误URL时,要确保该地址属于你已授权的重定向URI所在域名,否则可能会被Google拦截
  • 本地测试时,记得把http://localhost:xxxx/Account/AccessDenied也添加到相关配置中

内容的提问来源于stack exchange,提问作者smvdbrink

火山引擎 最新活动