6

我正在使用 LiveID 和 Google 提供商将 OpenID 集成到我现有的应用程序中。在我的登录页面上,除了原始登录字段之外,我还添加了“使用 Google 登录”和“使用 Microsoft 登录”按钮。

我可以成功读取上述两个提供程序的 AuthenticationResult 数据,但我通过以下方式完成此操作...

对于新的登录按钮,我制作了一个返回 URL 以在用户返回时区分它们:

Protected Sub btn_google_Click(sender As Object, e As EventArgs) Handles btn_google.Click
    Dim client As New GoogleOpenIdClient
    Dim u As New System.Uri("http://www.mytest.com/login.aspx?action=signin&provider=google")
    client.RequestAuthentication(New HttpContextWrapper(HttpContext.Current), u)
End Sub

Protected Sub btn_live_Click(sender As Object, e As EventArgs) Handles btn_live.Click
    Dim client As New MicrosoftClient("xyz", "12345")
    Dim u As New System.Uri("http://www.mytest.com/login.aspx?action=signin&provider=microsoft")
    client.RequestAuthentication(New HttpContextWrapper(HttpContext.Current), u)
End Sub

因此,当用户被重定向回 l​​ogin.aspx 时,我会进行以下检查来处理登录功能:

If Not Page.IsPostBack Then
    If Request.QueryString("action") IsNot Nothing AndAlso Request.QueryString("action").Trim = "signin" Then
        If Request.QueryString("provider") IsNot Nothing AndAlso Request.QueryString("provider").Trim <> String.Empty Then
            Select Case Request.QueryString("provider").Trim
                Case "microsoft"
                    Dim client As New MicrosoftClient("xyz", "12345")
                    Dim u As New System.Uri("http://www.mytest.com/loginlive.aspx?action=signin&provider=microsoft")
                    Dim result As DotNetOpenAuth.AspNet.AuthenticationResult = client.VerifyAuthentication(New HttpContextWrapper(HttpContext.Current), u)
                    ' remainder of logic removed
                    ' ...
                Case "google"
                    Dim client As New GoogleOpenIdClient
                    Dim result As DotNetOpenAuth.AspNet.AuthenticationResult = client.VerifyAuthentication(New HttpContextWrapper(HttpContext.Current))
                    ' remainder of logic removed
                    ' ...
            End Select
        End
    End
End If

我的主要问题是,这是处理 AuthenticationResults 的好方法吗?或者,是否有更好/更安全/更聪明的方法来完成同样的任务?

4

1 回答 1

1

更好的方法是将抽象工厂模式与命令模式结合使用。这可以减少硬编码并且使代码松散耦合,因此您可以在将来为每个身份验证提供程序扩展功能。找到下面每个部分的代码片段

“BaseAuthentication Provider”的抽象类

public abstract class BaseAuthenticationProvider
{
    //abstract Methods that need to be invoked from the concrete class, this need to be decided based on the functionality you need to achieve. This function would be invoked using the command pattern.
    // AuthorizeUser() : this method would be invoked to authorize the user from the provider

   //AuthenticateUser() : this method would be invoked once the user is redirected from the provider site.

    //abstract Properties that will hold the base information for the authentication provider, this need to be decided based on the functionality you need to achieve
    //CustomerSecret
    //CustomerConsumerKey
}

使用以下代码片段为 Google、Yahoo、Microsoft 等实现具体类。

public class GoogleAuthentication : BaseAuthenticationProvider
{
     public GoogleAuthentication()
     {
          //initialization
     }

     public void AuthorizeUser()
     {
          //code
     }

     public string CustomerSecret()
     {
          //code
     }

     public string CustomerConsumerKey()
     {
          //code
     }
}

工厂类创建具体对象,防止创建该工厂类的实例,实现私有构造函数。

public class AuthenticationProviderFactory
{
     private AuthenticationProviderFactory()
     {
     }

     public static BaseAuthenticationProvider GetInstance(string Domain)
     {
          switch (Domain)
          {
               case "google":
                    return new GoogleAuthentication();
               case "yahoo":
                    return new YahooAuthentication();
           }
      }
 }

Login.aspx :为每个身份验证提供程序提供按钮,为每个按钮设置“CommandName”的值并将所有按钮链接到同一个事件处理程序

例如 btn_google.CommandName = "google"

Protected Sub AuthenticationProvider_Click(sender As Object, e As EventArgs) Handles btn_google.Click, btn_yahoo.Click
    AuthenticationProviderFactory.GetInstance(((Button)sender).CommandName).AuthorizeUser();
End Sub

各自的 AuthorizeUser 方法将调用各自的提供者站点进行身份验证。当提供者将用户重定向到返回 URL 时,在 Page_Load 事件上应用相同的模式并从抽象类调用 Autheticate 方法。

于 2013-06-03T15:19:53.310 回答