2013-04-23 11 views
6

私は既存のアプリケーションとOpenIDをLiveIDとGoogleプロバイダで統合しています。私のログインページには、元のログインフィールドの他に、「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

より良い方法は、抽象ファクトリパターンをコマンドパターンと組み合わせて使用​​することです。これにより、ハードコーディングが削減され、コードが疎結合しているため、今後、各認証プロバイダの機能を拡張できます。などGooogle、ヤフー、マイクロソフトのための具体的なクラスを実装するために、「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 
} 

使用次のコードスニペット用

抽象クラス以下のコードの各セクションのスニペットを探します

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は=

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メソッドを呼び出します。

+0

ありがとうございます。私はあなたの意見を感謝しますが、いくつかの予約をしています。私はすでに、www.mydomain.com/autologinのようなリンクを使ってGoogle経由でログインしていれば、自動的にユーザのシステムにログインすることができます。 aspx?provider = Google'は通常のログインページに余分なボタンを押して時間を節約します。また、ConsumerKeyのような文字列値は一度しか使用されないので、それらをクラスに移動するには、それらが更新されるたびに再コンパイルする必要があります。それはいい練習ですか?申し訳ありませんが、私のコーディングスキルは平均的なものなので、あなたのアプローチでいくつかの重要な点を見逃しているかもしれません。 – EvilDr

+1

1.直接ログイン:上記のパターンでこれを達成することができます。ログインボタンで使用されているのと同じ方法を使用します。自動ログインのページの読み込みでも同じ方法を使用します。aspx 2.コンシューマキーをコードに移動する:コンシューマキーを設定ファイルまたはリソースファイルに保存し、それらをコードに直接参照することができます。 これがあなたの質問に答えることを願っています。 –

+0

大丈夫です。私が見るのが難しいのは、あなたのコードが私のアプローチよりも優れている理由です。もう一度私の経験を責め、ちょうどいくつかの指針は素晴らしいだろう! – EvilDr