2013-04-23 21 views
6

Ich integriere OpenID zu meiner bestehenden Anwendung mit LiveID und Google-Providern. Auf meiner Anmeldeseite habe ich zusätzlich zu den ursprünglichen Anmeldefeldern die Schaltflächen "Mit Google anmelden" und "Mit Microsoft anmelden" hinzugefügt.Processing AuthenticationResult von verschiedenen Anbietern auf der gleichen Seite

Ich kann erfolgreich die AuthenticationResult Daten für beide Anbieter oben gelesen, aber dies in der folgenden Art und Weise bin erreichen ...

Für die neuen Login-Buttons ich eine Rückkehr URL gestaltete sie auf die Rückkehr des Benutzers zu unterscheiden:

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 

Also, wenn der Benutzer zurück umgeleitet wird login.aspx, dann habe ich die folgenden Prüfungen durch die Login-Funktionalität zu verarbeiten:

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 

Meine Hauptfrage hier ist, ist dies eine gute Möglichkeit, AuthenticationResults zu verarbeiten? Oder gibt es einen besseren/sichereren/schlaueren Weg, dasselbe zu erreichen?

Antwort

1

Besserer Weg wäre, abstrakte Fabrikmuster in Kombination mit Befehlsmuster zu verwenden. Das kann die harte Codierung reduzieren und auch den Code lose gekoppelt haben, so dass Sie die Funktionalität zukünftig für jeden Authentifizierungsanbieter erweitern können. Finden Sie den Ausschnitt aus jedem Abschnitt des Codes unter

Abstrakte Klasse für "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 
} 

Verwenden Sie den folgenden Code-Schnipsel konkrete Klasse für die Gooogle, Yahoo, Microsoft usw. zu implementieren

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

    public void AuthorizeUser() 
    { 
      //code 
    } 

    public string CustomerSecret() 
    { 
      //code 
    } 

    public string CustomerConsumerKey() 
    { 
      //code 
    } 
} 

Factory-Klasse das konkrete Objekt zu schaffen, von der Erstellung in verhindern Stand dieser Factory-Klasse implementieren einen privaten Konstruktor.

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: haben Schaltflächen für jede der Authentifizierungsanbieter, für jeden der Taste, um den Wert für „Command“ gesetzt, und verknüpfen alle Tasten auf der gleichen Ereignisbehandlungsroutine

für z.B. 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 

Jeweilige AuthorizeUser Verfahren die jeweilige Anbieterstelle zur Authentifizierung nennen. Wenn der Anbieter den Benutzer an die Rückgabe-URL umleitet, wenden Sie das gleiche Muster für das Page_Load-Ereignis an und rufen Sie die Authenticate-Methode von der abstrakten Klasse auf.

+0

Danke für diesen Eingang. Ich schätze Ihre Punkte, habe aber einige Vorbehalte, nämlich ... Ich hatte gehofft, einen Benutzer automatisch in mein System einloggen zu können, wenn diese bereits über einen Link wie www.mydomain.com/autologin über Google eingeloggt waren. aspx? provider = Google', um Zeit zu sparen und zusätzliche Schaltflächen auf der normalen Anmeldeseite zu drücken. Da String-Werte wie ConsumerKey nur einmal verwendet werden, würde das Verschieben in eine Klasse bei jeder Aktualisierung neu kompiliert werden müssen. Ist das eine gute Praxis? Entschuldigung, meine Programmierkenntnisse sind nur durchschnittlich, daher habe ich vielleicht einige wichtige Punkte bei Ihrem Ansatz übersehen. – EvilDr

+1

1. direkte Anmeldung: Sie können dies immer noch durch das Muster erreichen, das ich oben gesagt habe. Verwenden Sie die gleichen Methoden wie in der Anmeldeschaltfläche.Verwenden Sie das selbe beim Laden der Seite des Autologin.aspx 2. Verschieben von Consumerkey in den Code: Der Consumer Key kann in der Konfigurations- oder Ressourcendatei gespeichert werden und Sie können diese direkt in Ihren Code einbinden. Ich hoffe, dies beantwortet Ihre Anfrage. –

+0

Okay, großartig. Das bisschen, um das ich mich bemühe, ist * warum * Ihr Code ist besser als mein Ansatz. Wieder meine Schuld, nur ein paar Tipps wären großartig! – EvilDr