2013-04-23 29 views
6

Integruję OpenID z moją istniejącą aplikacją z LiveID i dostawcami Google. Na mojej stronie logowania oprócz oryginalnych pól logowania dodałem przyciski "Zaloguj się za pomocą Google" i "Zaloguj się za pomocą Microsoft".Processing AuthenticationResults od różnych dostawców na tej samej stronie

powodzeniem mogę odczytać danych AuthenticationResult zarówno dla dostawców wyżej, ale ja to osiągnąć w następujący sposób ...

Dla nowych przycisków logowania I spreparowanego adresu URL powrotu do odróżnienia ich po powrocie użytkownika:

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 

Więc gdy użytkownik zostanie przekierowany z powrotem do Login.aspx, ja wtedy mają następujące kontrole, aby przetworzyć funkcjonalność login:

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 

Moje główne pytanie tutaj jest, czy jest to dobry sposób na przetwarzanie AuthenticationResults? Czy istnieje lepszy/bezpieczniejszy/bardziej sprytny sposób na osiągnięcie tego samego?

Odpowiedz

1

Lepszym sposobem byłoby użycie wzoru abstrakcyjnej fabryki w połączeniu ze wzorem polecenia. Może to zmniejszyć twarde kodowanie, a także luźno powiązać kod, dzięki czemu można rozszerzyć funkcjonalność w przyszłości dla każdego dostawcy uwierzytelniania. Znajdź fragment każdej sekcji kodu poniżej

klasy abstrakcyjnej dla „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 
} 

Zastosowanie następujący fragment kodu do realizacji konkretne klasy dla Gooogle, Yahoo, Microsoft itp

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

    public void AuthorizeUser() 
    { 
      //code 
    } 

    public string CustomerSecret() 
    { 
      //code 
    } 

    public string CustomerConsumerKey() 
    { 
      //code 
    } 
} 

klasa Fabryka stworzyć konkretny obiekt, aby zapobiec tworzeniu się stanowisko tej klasy fabrycznej implementuje prywatny 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: mieć przyciski dla każdego dostawcy uwierzytelniania, należy ustawić wartość dla „nazwa_polecenia” dla każdego przycisku i połączyć wszystkie przyciski do tej samej procedury obsługi zdarzenia

na przykład 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 

odpowiednich metoda AuthorizeUser nazwałbym odpowiednią witrynę dostawcy uwierzytelniania. Gdy dostawca przekierowuje użytkownika do zwrotnego adresu URL, zastosuj ten sam wzorzec w zdarzeniu Page_Load i wywołaj metodę Autheticate z klasy abstrakcyjnej.

+0

Dzięki za to wejście. Doceniam twoje punkty, ale mam pewne zastrzeżenia, a mianowicie ... Miałem nadzieję, że będę mógł zalogować się automatycznie do mojego systemu, jeśli byli już zalogowani przez Google za pomocą linku podobnego do 'www.mydomain.com/autologin. aspx? provider = Google', aby zaoszczędzić czas na trafianie dodatkowych przycisków na normalnej stronie logowania. Ponieważ wartości łańcuchowe, takie jak ConsumerKey, są używane tylko raz, przeniesienie ich do klasy wymagałoby przekompilowania za każdym razem, gdy były one aktualizowane. Czy to dobra praktyka? Niestety moje umiejętności kodowania są tylko średnie, więc mogłem pominąć pewne kluczowe punkty z twoim podejściem. – EvilDr

+1

1. Bezpośrednie logowanie: nadal możesz to osiągnąć według wzorca, który powiedziałem powyżej. Korzystanie z tych samych metod stosowanych w przycisku logowania. Użyj tego samego przy ładowaniu strony autologin.aspx 2. Przenoszenie Consumerkey do kodu: klucz konsumenta może być przechowywany w pliku konfiguracyjnym lub zasobowym i można je odesłać bezpośrednio do kodu. Mam nadzieję, że to odpowie na twoje pytanie. –

+0

Okay świetnie. Trochę, z czym walczę, to: * dlaczego * twój kod jest lepszy niż moje podejście. Ponownie obwiniam moje doświadczenie, tylko niektóre wskazówki byłyby świetne! – EvilDr