使用 Azure ADFS 和 OWIN 进行单点登录

SSO with Azure ADFS and OWIN

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

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

我想要这种行为,因为该站点的大多数用户不会成为公司网络的一部分,并且无法进行身份验证。所以,默认情况下,他们应该只看到我们的主页。但是,有时公司成员可能在家工作,因此不会在我们的网络上进行自动身份验证。在这种情况下,他们将使用 link 将他们发送到 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

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

谢谢

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


  • 您可以尝试绕过登录页面提示,看一下here,其中向您解释了如何:

bypass the sign-in page prompts by adding your company’s existing federated domain name to the end of the Windows Azure Management Portal URL


When users sign in using Azure AD, this feature validates users' passwords directly against your on-premises Active Directory.


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

没有 solid/correct 方法来检查匿名用户是否在您的网络中(或者我不知道)。可能的方法是检查您网络内的用户的 IP 地址(范围) publicly 在 Internet 上。您可以向网络管理员核实这一点。他们可能会告诉您 public IP 地址(范围)。

一旦您知道 public 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
    }

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