【问题标题】:ASP.NET and Google Oauth 2 stopped workingASP.NET 和 Google Oauth 2 停止工作
【发布时间】:2018-09-14 00:23:04
【问题描述】:

我们的谷歌第三方登录突然出现问题。我们可以通过 Facebook 和 LinkedIn 进行良好的身份验证,但 Google 失败并出现 IIS 404 错误。

系统使用标准的asp.net技术登录:

  • 社交登录按钮是在表单中类型提交,操作为 /Account/ExternalLogin
  • ExternalLogin 返回重定向浏览器以转到 Google 并请求连接授权
  • 如果正常,Google 返回到提供的 ReturnUrl
  • Microsoft Owin 中间件拦截此返回到 /domain/signin-google,对用户进行身份验证并调用 ExternalLoginCallback

我们的系统在返回 /domain/signin-google 时失败,并出现 404 错误。 LinkedIn 和 Facebook 运行良好,具有讽刺意味的是,该系统在我们使用 google 登录的开发服务器上运行良好。

Nuget 是最新的 - 我们在 v4.0 Owin 库上运行。我们上周升级了这可能是一个问题的指针,但我们已经恢复到 3.1 并且问题仍然存在。

几个月来网关或 IIS 设置没有任何变化。对域进行了 URL 重写,以摆脱服务器地址的 www 部分,但同样有一年左右没有触及。

我们的 Startup.Auth 文件如下所示:

Partial Public Class Startup
    Public Sub ConfigureAuth(app As IAppBuilder)
        app.CreatePerOwinContext(AddressOf ApplicationDbContext.Create)
        app.CreatePerOwinContext(Of ApplicationUserManager)(AddressOf ApplicationUserManager.Create)
        app.CreatePerOwinContext(Of ApplicationSignInManager)(AddressOf ApplicationSignInManager.Create)
        app.UseCookieAuthentication(New CookieAuthenticationOptions() With {
            .AuthenticationType = DefaultAuthenticationTypes.ApplicationCookie,
            .Provider = New CookieAuthenticationProvider() With {
                .OnValidateIdentity = SecurityStampValidator.OnValidateIdentity(Of ApplicationUserManager, ApplicationUser)(
                    validateInterval:=TimeSpan.FromMinutes(30),
                    regenerateIdentity:=Function(manager, user) user.GenerateUserIdentityAsync(manager))},
            .LoginPath = New PathString("/Account/Login")})
        app.UseExternalSignInCookie(DefaultAuthenticationTypes.ExternalCookie)
        app.UseTwoFactorSignInCookie(DefaultAuthenticationTypes.TwoFactorCookie, TimeSpan.FromMinutes(5))
        app.UseTwoFactorRememberBrowserCookie(DefaultAuthenticationTypes.TwoFactorRememberBrowserCookie)

        Dim facebookOptions = New FacebookAuthenticationOptions With {
            .AppId = ConfigurationManager.AppSettings("FacebookClientID"),
            .AppSecret = ConfigurationManager.AppSettings("FacebookClientSecret"),
            .Provider = New FacebookAuthenticationProvider With {
                .OnAuthenticated = Function(context)
                                       context.Identity.AddClaim(New Claim("Provider", "Facebook"))
                                       context.Identity.AddClaim(New Claim("provider:name", context.Identity.FindFirstValue(ClaimTypes.Name)))
                                       context.Identity.AddClaim(New Claim("provider:accesstoken", context.AccessToken, ClaimValueTypes.String, "Facebook"))
                                       context.Identity.AddClaim(New Claim("provider:picture", String.Format("//graph.facebook.com/{0}/picture?type=square", context.User.Value(Of String)("id"))))
                                       Dim email = context.Identity.FindFirstValue(ClaimTypes.Email)
                                       If email IsNot Nothing Then
                                           context.Identity.AddClaim(New Claim("provider:email", email))
                                       Else
                                           Dim fb = New Facebook.FacebookClient(context.AccessToken)
                                           Dim myInfo = fb.Get("/me?fields=email")
                                           email = myInfo("email")
                                           If email IsNot Nothing Then
                                               context.Identity.AddClaim(New Claim("provider:email", email))
                                           Else
                                               Throw New ArgumentNullException("myInfo.Email")
                                           End If
                                       End If

                                       Return Task.FromResult(0)
                                   End Function}}
        facebookOptions.Scope.Add("email")
        app.UseFacebookAuthentication(facebookOptions)

        app.UseGoogleAuthentication(New GoogleOAuth2AuthenticationOptions() With {
           .ClientId = ConfigurationManager.AppSettings("GoogleClientID"),
           .ClientSecret = ConfigurationManager.AppSettings("GoogleClientSecret"),
           .Provider = New GoogleOAuth2AuthenticationProvider With {.OnAuthenticated = Function(context)
                                                                                           context.Identity.AddClaim(New Claim("Provider", "Google"))
                                                                                           context.Identity.AddClaim(New Claim("provider:name", context.Identity.FindFirstValue(ClaimTypes.Name)))
                                                                                           context.Identity.AddClaim(New Claim("provider:email", context.Identity.FindFirstValue(ClaimTypes.Email)))
                                                                                           context.Identity.AddClaim(New Claim("provider:accesstoken", context.AccessToken, ClaimValueTypes.String, "Google"))
                                                                                           context.Identity.AddClaim(New Claim("provider:picture", context.User.SelectToken("image")?.Value(Of String)("url")))

                                                                                           Return Task.FromResult(0)
                                                                                       End Function}})

        app.UseLinkedInAuthentication(New LinkedInAuthenticationOptions With {
            .ClientId = ConfigurationManager.AppSettings("LinkedInClientID"),
            .ClientSecret = ConfigurationManager.AppSettings("LinkedInClientSecret"),
            .Provider = New LinkedInAuthenticationProvider With {.OnAuthenticated = Function(context)
                                                                                        context.Identity.AddClaim(New Claim("Provider", "LinkedIn"))
                                                                                        context.Identity.AddClaim(New Claim("provider:name", context.Name))
                                                                                        context.Identity.AddClaim(New Claim("provider:email", context.Email))
                                                                                        context.Identity.AddClaim(New Claim("provider:accesstoken", context.AccessToken, ClaimValueTypes.String, "LinkedIn"))
                                                                                        context.Identity.AddClaim(New Claim("provider:picture", context.User.SelectToken("pictureUrl").ToString))

                                                                                        Return Task.FromResult(0)
                                                                                    End Function}})

        app.MapSignalR
        GlobalHost.DependencyResolver.Register(GetType(IUserIdProvider), Function() New MySignalRIdProvider())
    End Sub
End Class

我们没有想法 - 任何想法都非常感谢!

【问题讨论】:

    标签: asp.net


    【解决方案1】:

    刚刚找到答案 - 我们在网站上有 1 条 url 重写规则,大约一年没有更新,禁用时允许我们使用 Google 进行身份验证。

    我们的开发环境之所以有效,是因为它有一个稍微简单一点的规则版本(同样已经存在 9 个月),我们已经投入使用。

    如果有人需要示例,这里是 url rewrite xml:

    <rules>
      <rule name="Remove WWW" enabled="false" patternSyntax="Wildcard" stopProcessing="true">
        <match url="*" />
          <conditions logicalGrouping="MatchAny">
                <add input="{CACHE_URL}" pattern="*://www.*" />
          </conditions>
          <action type="Redirect" url="{C:1}//{R:1}" appendQueryString="true" redirectType="Permanent" />
      </rule>
        <rule name="Enforce https" enabled="true" patternSyntax="Wildcard" stopProcessing="true">
            <match url="*" />
            <conditions logicalGrouping="MatchAny">
                <add input="{HTTPS}" pattern="off" />
            </conditions>
            <action type="Redirect" url="https://investorsedge.net:8443/{R:1}" />
        </rule>
    <rule name="Remove WWW and Ensure HTTPS" enabled="false" stopProcessing="true">
                        <match url="(.*)" />
                        <conditions logicalGrouping="MatchAny">
                <add input="{HTTP_HOST}" pattern="^(www\.)" />
                <add input="{HTTPS}" pattern="^OFF$" />
                        </conditions>
                        <action type="Redirect" url="https://investorsedge.net/{R:0}:8443" appendQueryString="false" redirectType="Permanent" />
                    </rule>
    <rule name="Remove www rule 2" enabled="true" stopProcessing="true">
      <match url="(.*)" ignoreCase="true" />
      <conditions logicalGrouping="MatchAll">
                <add input="{HTTP_HOST}" pattern="^www\.(.+)$" />
      </conditions>
      <action type="Redirect" url="https://{C:1}/{R:0}" appendQueryString="true" redirectType="Permanent" />
    </rule>
    </rules>
    

    【讨论】:

      猜你喜欢
      • 2015-09-12
      • 1970-01-01
      • 2017-08-21
      • 1970-01-01
      • 2014-05-29
      • 1970-01-01
      • 2011-09-21
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多