2013-04-23 26 views
6

Sto integrando OpenID alla mia applicazione esistente con LiveID e provider di Google. Nella mia pagina di accesso, oltre ai campi di accesso originali, ho aggiunto i pulsanti "Accedi con Google" e "Accedi con Microsoft".Elaborazione di AuthenticationResult di provider diversi nella stessa pagina

posso leggere correttamente i dati AuthenticationResult per entrambi i fornitori di cui sopra, ma sto realizzare questo nel modo seguente ...

Per i nuovi pulsanti d'accesso ho predisposto un URL di ritorno per differenziarli sul ritorno dell'utente:

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 

Così, quando l'utente viene reindirizzato a Login.aspx, ho poi avuto i seguenti controlli per elaborare la funzionalità di 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 

La mia domanda principale è, questo è un buon modo per elaborare AuthenticationResults? O c'è un modo migliore/più sicuro/più intelligente per realizzare lo stesso?

risposta

1

Il modo migliore sarebbe utilizzare il pattern Abstract Factory in combinazione con Command Pattern. Questo può ridurre la codifica hard e avere il codice liberamente accoppiato, quindi è possibile estendere la funzionalità in futuro per ciascuno dei provider di autenticazione. Trovare il frammento di ogni sezione del codice qui sotto

classe astratta per "Provider 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 
} 

Utilizzare il seguente frammento di codice per implementare classe concreta per il Gooogle, Yahoo, Microsoft, ecc

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

    public void AuthorizeUser() 
    { 
      //code 
    } 

    public string CustomerSecret() 
    { 
      //code 
    } 

    public string CustomerConsumerKey() 
    { 
      //code 
    } 
} 

classe di fabbrica per creare l'oggetto concreto, per evitare di creare in posizione di questa classe di fabbrica implementare un costruttore privato.

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: dispone di pulsanti per ciascuno dei provider di autenticazione, impostare il valore per "CommandName" per ciascuno del pulsante e collegare tutti i pulsanti per lo stesso gestore di eventi

per esempio 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 

metodo AuthorizeUser rispettivi avrebbe chiamato il rispettivo sito del provider per l'autenticazione. Quando il provider reindirizza l'utente all'URL di ritorno, applica lo stesso pattern all'evento Page_Load e chiama il metodo Autheticate dalla classe astratta.

+0

Grazie per quell'input. Apprezzo i tuoi punti, ma ho qualche riserva, in particolare ... speravo di poter accedere automaticamente a un utente al mio sistema se erano già registrati tramite Google con un link come questo "www.mydomain.com/autologin". aspx? provider = Google' per risparmiare tempo colpendo pulsanti extra nella normale pagina di accesso. Inoltre, poiché i valori di stringa come ConsumerKey vengono utilizzati solo una volta, spostarli in una classe richiederebbe una ricompilazione ogni volta che vengono aggiornati. È una buona pratica? Spiacente, le mie capacità di codifica sono solo nella media, quindi potrei aver perso alcuni punti chiave del tuo approccio. – EvilDr

+1

1. accesso diretto: è ancora possibile ottenere ciò con il modello che ho detto sopra. Utilizzando le stesse metodologie utilizzate nel pulsante di accesso. Utilizzare lo stesso sul caricamento della pagina dell'autologin.aspx 2. Spostamento di Consumerkey nel codice: la chiave del consumatore può essere conservata nel file config o di risorsa e puoi indirizzarla direttamente nel tuo codice. Spero che questo risponda alla tua richiesta. –

+0

Ok, bene. Il bit che sto faticando a vedere è * perché * il tuo codice è migliore del mio approccio. Di nuovo incolpare la mia esperienza, solo alcuni suggerimenti sarebbero fantastici! – EvilDr

Problemi correlati