【问题标题】:SSO with Azure ADFS and OWINSSO 与 Azure ADFS 和 OWIN
【发布时间】:2018-01-09 17:53:17
【问题描述】:

感谢您提供帮助。我有一个站点可以通过 Active Directory 联合服务进行身份验证以进行单点登录。目前,我的网站的工作方式是,默认情况下,当用户访问我的网站时,我的代码会尝试登录 SSO(为此我使用 OWIN 库)。如果用户不在我们的网络上,则无法进行身份验证,他们将被重定向到我的公司登录页面,他们可以在其中提供公司凭据。

不过,我想改变这种行为。相反,当用户点击我的页面时,如果他们进行了身份验证,它应该会继续正常进行,并且他们应该被重定向到我的网站。但是,如果他们没有进行身份验证,我不希望他们重定向到我们的登录页面。相反,我希望他们被重定向回我的网站,我的代码将确定他们在网站上可以做什么和不能做什么。然后我想提供一个链接,以便他们决定转到登录页面。

我想要这种行为,因为该网站的大多数用户不会成为公司网络的一部分,也无法进行身份验证。所以,默认情况下,他们应该只看到我们的主页。但是,有时公司成员可能在家工作,因此不会在我们的网络上进行自动身份验证。在这种情况下,他们将使用将他们发送到 Azure 登录页面的链接。

这是我目前正在使用的代码(网站是 ASP.net,表单网页(不是 MVC)):

Startup.Auth.vb:

Partial Public Class Startup
    Dim appSettings = ConfigurationManager.AppSettings

    Private realm As String
    Private aadInstance As String
    Private tenant As String
    Private metadata As String
    Private authority As String

    Public Sub ConfigureAuth(app As IAppBuilder)
        Try
            Dim appSettings = ConfigurationManager.AppSettings
            If (appSettings("releaseVersion") = "DEBUG") Then
                realm = ConfigurationManager.AppSettings("test_ida:RPIdentifier")
                aadInstance = ConfigurationManager.AppSettings("test_ida:AADInstance")
                tenant = ConfigurationManager.AppSettings("test_ida:Tenant")
            ElseIf (appSettings("releaseVersion") = "PROD") Then
                realm = ConfigurationManager.AppSettings("ida:RPIdentifier")
                aadInstance = ConfigurationManager.AppSettings("ida:AADInstance")
                tenant = ConfigurationManager.AppSettings("ida:Tenant")
            End If

            metadata = String.Format("{0}/FederationMetadata/2007-06/FederationMetadata.xml", aadInstance)
            authority = String.Format(CultureInfo.InvariantCulture, aadInstance, tenant)

            app.SetDefaultSignInAsAuthenticationType(CookieAuthenticationDefaults.AuthenticationType)
            app.UseCookieAuthentication(New CookieAuthenticationOptions())
            Dim authOption As WsFederationAuthenticationOptions = New WsFederationAuthenticationOptions()

            Dim fn = Function(context)
                         context.HandleResponse()
                         context.Response.Redirect("Home/Error?message=" + context.Exception.Message)
                         Return Task.FromResult(0)
                     End Function

            Dim auth_not As WsFederationAuthenticationNotifications = New WsFederationAuthenticationNotifications() With {
                    .AuthenticationFailed = fn
                 }

            Dim auth_opt As WsFederationAuthenticationOptions = New WsFederationAuthenticationOptions() With {
                 .Wtrealm = realm,
                 .MetadataAddress = metadata,
                 .Notifications = auth_not
               }
            If (Not auth_opt.Wtrealm Is Nothing) Then
                app.UseWsFederationAuthentication(auth_opt)
            Else

            End If

        Catch ex As Exception
            Throw ex
        End Try

    End Sub


End Class

然后,在我的 Default.aspx.vb 页面加载事件中,我这样做:

  If (Not Request.IsAuthenticated) Then
        Try
            Dim newAuth As AuthenticationProperties = New AuthenticationProperties()
            newAuth.RedirectUri = "/"
            HttpContext.Current.GetOwinContext().Authentication.Challenge(newAuth, WsFederationAuthenticationDefaults.AuthenticationType)

        Catch ex As Exception
            Throw ex
        End Try

    End If

问题是,我不知道如何尝试对用户进行身份验证,确定他们是否已通过身份验证,并相应地重定向它们。任何帮助将不胜感激。

谢谢

【问题讨论】:

  • 有人有这方面的经验吗?
  • 虽然这听起来很棘手(如何确定用户是否可以进行身份验证?如果他们可以但不想呢?)您可以重新考虑您的设计。与其自动决定,不如让用户决定。正式 - 有一个不需要任何身份验证的起始页面(控制器上没有 Authorize 属性),并且所有其他需要身份验证的页面都重定向到您站点中的另一个登录页面。在那里,用户可以自行选择几个选项(链接):使用 Azure 登录、使用用户名/密码登录、使用其他提供商登录等。
  • 我想到了这个主意。首先,它是一个单页应用程序,尽管这仍然可以完成。其次,客户想要特定的行为。我们的大多数用户将在我们的网络上并自动登录。但是,对于那些不在我们网络上的人,他们很可能无法进行身份验证(公众),因此将他们重定向到登录页面将是一个问题。边缘情况是可以进行身份​​验证但不在现场和我们网络之外的用户。
  • 这不可能吗?我觉得这不应该那么复杂。但是,我不知道谁来确定某人是否是 SSO 的。如果有办法捕捉失败的登录尝试,并在点击公司登录页面之前重定向,我认为这会奏效吗?我只是不知道如何使用 OWIN 来做到这一点
  • 这里的诀窍是您已经集成了由浏览器自动处理的身份验证(基于 ntlm/kerberos)。一个想法是有一个单独的页面尝试自动登录并在加载时执行window.postMessage 以指示成功的身份验证。然后你有一个不需要任何身份验证的主页,但是你把这个附加页面放在一个 1x1 的 iframe 中(这样用户就看不到它了)。并且主页会监听message 事件以从 iframe 中捕获成功的身份验证。每当您捕获它时,您都可以强制/启动身份验证,因为您可以保证它会成功。

标签: asp.net vb.net azure single-sign-on owin-middleware


【解决方案1】:

没有可靠/正确的方法来检查匿名用户是否在您的网络中(或者我不知道有一个)。可能的方法是检查您网络内的用户在 Internet 上公开的 IP 地址(范围)。您可以向网络管理员咨询。他们可能会告诉您公共 IP 地址(范围)。

一旦您知道公共 IP 地址(范围),您就可以检查传入的请求,以比较请求是否来自 RedirectToIdentityProvider 函数内的 IP 地址(范围)的已知范围。

Dim redirectToIdentityProvider = Function(context)
    Dim isCompanyNetworkUser = companyIPAddress == context.Request.RemoteIpAddress
    ' Or relevant check for range
    ' Dim isCompanyNetworkUser = (companyIPAddressRangeStart < context.Request.RemoteIpAddress AndAlso companyIPAddressRangeEnd > context.Request.RemoteIpAddress

    If Not isCompanyNetworkUser Then
        context.State = NotificationResultState.Skipped
        context.HandleResponse()
    End If

End Function

Dim auth_not As WsFederationAuthenticationNotifications = New WsFederationAuthenticationNotifications() With {
                    .AuthenticationFailed = fn
                    .RedirectToIdentityProvider = redirectToIdentityProvider
    }

您可能需要稍微调整一下,因为我没有尝试过,但可能会为您指明正确的方向。

【讨论】:

  • 感谢您为此提供的所有帮助,cloudikka!我希望你得到这个赏金!我确实与我们的 Azure 管理员交谈过,并确认真正做到这一点的唯一方法是在标头中测试客户端的源 IP,并将其与我们的 IP 范围相匹配。我会试试看!
  • 这与赏金无关。我正要帮忙。您需要一些帮助,请与我联系!我在极地圈待了两周,但我反应灵敏:)
【解决方案2】:

很抱歉没有提供完整的代码示例,但在我看来:


  • 您可以尝试绕过登录页面提示,查看here,它会告诉您如何:

通过将贵公司现有的联合域名添加到 Windows Azure 管理门户 URL 的末尾来绕过登录页面提示


当用户使用 Azure AD 登录时,此功能会直接根据您的本地 Active Directory 验证用户的密码。


我终于发现this question可能与你的问题有关。

【讨论】:

  • @A STEFANI 感谢您的回复,但您提供的链接实际上并不适用于我遇到的问题。我的应用程序确实将用户无缝地登录到 Azure,但前提是他们与 Azure 在同一网络上。我需要检测是否是这种情况,因此如果它们不在网络上,我可以停止自动登录。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-12-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多