2013-04-23 40 views
6

我正在使用LiveID和Google提供程序將OpenID集成到我現有的應用程序中。在我的登錄頁面上,除了我已添加的「登錄Google」和「使用Microsoft登錄」按鈕的原始登錄字段外。在同一頁面中處理來自不同供應商的AuthenticationResult

我可以成功讀取上面都提供商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 

因此,當用戶被重定向回到login.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的好方法嗎?或者,是否有更好/更安全/更聰明的方法來完成相同的目標?

回答

1

更好的方法是將抽象工廠模式與命令模式結合使用。這可以減少硬編碼並使代碼鬆散耦合,因此您可以爲每個身份驗證提供程序擴展功能。請看下面

抽象類的代碼的每個部分的片段爲「BaseAuthentication提供商」

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 
} 

使用下面的代碼片段來實現具體類的Gooogle企業,雅虎,微軟等

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事件中應用相同的模式,並從抽象類中調用Aututhate方法。

+0

感謝您的輸入。我很欣賞你的觀點,但有一些保留意見,即......我希望能夠自動登錄到我的系統,如果他們已經通過谷歌登錄這樣的鏈接,如www.mydomain.com/autologin。 aspx?provider = Google',以節省正常登錄頁面上額外按鈕的時間。此外,因爲像ConsumerKey這樣的字符串值只能使用一次,所以將它們移動到類中時,每次更新時都需要重新編譯。這是不錯的做法嗎?對不起,我的編程技能只有平均水平,所以我可能錯過了一些關鍵點。 – EvilDr 2013-06-04 07:53:32

+1

1.直接登錄:您仍然可以通過上述模式實現此目的。使用登錄按鈕中使用的相同方法。在自動登錄的頁面加載中使用相同的方法。aspx 2.將Consumerkey移動到代碼中:消費者密鑰可以保存在配置文件或資源文件中,您可以直接將它們引用到您的代碼中。 我希望這會回答您的查詢。 – 2013-06-04 09:52:55

+0

好吧。我努力看到的一點是*爲什麼*你的代碼比我的方法更好。再次指責我的經驗,只是一些指針會很棒! – EvilDr 2013-06-06 10:31:33