Utilizzo di AuthSub con la libreria client .NET

Jeff Fisher, team delle API di dati di Google
agosto 2007

Introduzione: perché AuthSub è importante?

L'aspetto fantastico delle API di dati di Google ("GData" in breve) è il modo in cui consentono agli sviluppatori di creare applicazioni che interagiscono con i servizi Google. Più nello specifico, consentono di accedere a dati utente privati da utilizzare nella tua applicazione. Le API consentono di scrivere applicazioni per sincronizzare, importare, esportare e gestire quei dati. Anche se le API ti offrono queste potenti funzionalità, devi ricordarti di usarle responsabilmente. Poiché i dati utente sono informazioni private, è consigliabile accedervi in modo sicuro. Una parte fondamentale di questo processo è l'autenticazione in modo sicuro sui server di Google.

Supponiamo che tu abbia una nuova applicazione web fantastica che vuoi associare ai dati archiviati nei servizi web di Google. Ora vuoi eseguire l'autenticazione per accedere a questi dati privati. Perché non utilizzare semplicemente qualcosa di semplice, come ClientLogin? Questo è il trucco, ma devi gestire ancora più dati privati: le credenziali di accesso dell'utente. ClientLogin richiede all'applicazione di richiedere il nome utente e la password Google dell'utente. Non è un problema per un'applicazione desktop in esecuzione sul computer personale dell'utente, ma non è l'ideale per le applicazioni basate sul Web. Oltre alla responsabilità di gestire queste credenziali sul tuo server, forse alcuni dei tuoi utenti più prudenti potrebbero temere che tu possa memorizzare le loro informazioni. Un'altra preoccupazione comune degli utenti è se vogliono concedere a un programma l'accesso solo a un particolare servizio (come gli eventi sul loro calendario Google), ma non ad altri (come i documenti Google). AuthSub risolve entrambi i problemi consentendo a un utente di autenticarsi tramite i server di Google e consente al tuo programma di richiedere solo l'accesso di cui ha bisogno.

Ora che hai letto abbastanza sulla teoria alla base di AuthSub, è il momento di passare a un po' di programmazione. Per questo articolo ho scelto di semplificare la procedura e di fare tutto all'interno di un'unica pagina ASP, ma dovresti essere in grado di integrare facilmente le tecniche illustrate qui nella tua applicazione.

Gestione dell'autenticazione

Cosa serve per poter utilizzare AuthSub nella tua applicazione web? Innanzitutto, ecco alcune importazioni standard dalla libreria client di GData:

<%@ Import Namespace="Google.GData.Client" %>
<%@ Import Namespace="Google.GData.Extensions" %>
<%@ Import Namespace="System.Net" %>

La prima cosa da fare è indirizzare l'utente a un URL creato appositamente. Questo è ciò che consente ai server di Google di gestire l'autenticazione e quindi reindirizzare l'utente al tuo sito web. Fortunatamente non è necessario generare manualmente questo URL, poiché esistono alcuni metodi per farlo. Ad esempio:

authSubUrl = AuthSubUtil.getRequestUrl(target, scope, secure, session);
  • target è una stringa contenente l'URL della tua applicazione web. Questa è la pagina a cui l'utente viene reindirizzato dopo l'autenticazione.
  • scope Questa stringa è determinata dall'API che stai utilizzando. Corrisponde a uno dei feed in un'API GData. Ad esempio, il feed contenente tutte le informazioni del calendario per un utente è "http://www.google.com/calendar/feeds/default/private/full".
  • secure È un valore booleano che indica al server che hai registrato a Google e firmerà crittograficamente le tue richieste. Questo argomento è in genere falso per impostazione predefinita, soprattutto quando si lavora in un ambiente di test.
  • session è un altro booleano che indica che preferisci un "token di sessione" anziché un "token di utilizzo una tantum". Il ruolo di questo argomento sarà più chiaro tra un momento.

Dopo aver fatto clic sull'URL generato, l'utente verrà indirizzato a una pagina Account Google che gli consentirà di accedere al suo Account Google. Verrà quindi reindirizzato alla pagina web specificata nella variabile "target", ma con il parametro di ricerca "token" che contiene un token monouso. Normalmente, questo token può essere utilizzato una sola volta. Vale a dire che può essere utilizzato per eseguire un'azione su un determinato feed. Tuttavia, se hai specificato il parametro "session" come true, può essere scambiato con un "token di sessione" che può essere riutilizzato fino a quando l'utente termina la sessione. Puoi procedere nel seguente modo:

String token = Request.QueryString["token"];
Session["token"] = AuthSubUtil.exchangeForSessionToken(token, null).ToString();

Qui puoi estrarre il token dal parametro di ricerca e scambiarlo con un "token di sessione". Quindi, in modo che possa essere salvato per un uso successivo, puoi scegliere di memorizzarlo nell'array Session automatico di .NET. Naturalmente, puoi anche scegliere di archiviare il token all'interno di un database. Il passaggio successivo consiste nell'utilizzare questo token per effettuare una richiesta autenticata:

GAuthSubRequestFactory authFactory = new GAuthSubRequestFactory("cl", "My-Cool-Application");
authFactory.Token = (String) Session["token"];
CalendarService service = new CalendarService(authFactory.ApplicationName);
service.RequestFactory = authFactory;

In questo strumento configuri un oggetto CalendarService per interagire con l'API Google Calendar utilizzando AuthSub per l'autenticazione. Nota: "cl" utilizzato nel costruttore per GAuthSubRequestFactory è il nome del servizio per Calendar. Puoi consultare le domande frequenti sulle API Google Data per altri nomi di servizi.

AuthSub sicuro (registrato)

Se scegli di registrare la tua applicazione web, puoi attivare un ulteriore livello di sicurezza mentre utilizzi AuthSub. In questo modo puoi firmare digitalmente tutte le richieste effettuate dal codice, in modo che qualcuno non possa usare i token AuthSub che ti vengono inviati, a meno che non abbiano la chiave privata. Il primo passaggio consiste nell'assicurarti di generare il link AuthSub corretto durante la chiamata a AuthSubUtil.getRequestUrl impostando l'argomento "secure" su true. Devi apportare altre due modifiche al codice:

String token = Request.QueryString["token"];
Session["token"] = AuthSubUtil.exchangeForSessionToken(token, rsaKey).ToString();

...

authFactory.PrivateKey = rsaKey;

Innanzitutto, noterai invece di null passando la variabile "rsaKey" al metodo exchangeForSessionToken. La stessa variabile viene utilizzata anche per impostare una proprietà di GAuthSubRequestFactory durante la configurazione della connessione al servizio. La variabile "rsaKey" è una RSACryptoServiceProvider corrispondente al componente della chiave privata del certificato x509 che hai registrato con Google.

La generazione di una chiave privata RSA e di un certificato autofirmato può generare un po' di confusione, soprattutto perché il framework .NET non comprende le chiavi o i certificati archiviati in formato PEM. I comandi seguenti mostrano come generare una chiave privata e un certificato pubblico utilizzando la suite di strumenti OpenSSL:

openssl req -x509 -nodes -days 365 -newkey rsa:1024 -sha1 -subj \
  '/C=US/ST=CA/L=Mountain View/CN=www.example.com' -keyout \
  test_key.pem -out test_cert.pem

openssl pkcs12 -export -in test_cert.pem -inkey test_key.pem \
  -out test_cert.pfx -name "Testing Certificate"

Il primo passaggio genera una chiave privata e un certificato X509 pubblico entrambi in formato PEM chiamati rispettivamente "test_key.pem" e "test_cert.pem". Tieni presente che il certificato è impostato per essere registrato su "www.example.com" con base a Mountain View, CA, USA. Sostituisci qui i valori appropriati per la tua azienda. Il file "test_cert.pem" contiene le informazioni che è necessario inviare nella pagina di registrazione di AuthSub.

Il secondo passaggio genera un file PFX dalla chiave privata e dal certificato. Questo file può essere importato nella libreria client .NET per firmare digitalmente le richieste effettuate alle API GData. Il codice seguente mostra come importare la chiave privata dal file PFX in un'applicazione web:

protected AsymmetricAlgorithm getRsaKey()
{

  X509Certificate2 cert = new X509Certificate2("C:/MyAspSite/test_cert.pfx","");
  RSACryptoServiceProvider privateKey = cert.PrivateKey as RSACryptoServiceProvider;

  return privateKey;
}

La funzione getRsaKey() definita da questo snippet può essere utilizzata al posto della variabile "rsaKey" mostrata sopra quando usata per l'autenticazione con le API. Ovviamente, il percorso del file deve essere sostituito con la posizione appropriata del file PFX generato.

Completa il codice

Il modo più semplice per mostrare come utilizzare i metodi illustrati nella sezione precedente è un esempio pubblicato. Il seguente codice di esempio è una pagina ASP semplice che utilizza AuthSub per autenticare l'utente e quindi stampa gli eventi di Google Calendar.

<%@ Page Language="C#" AutoEventWireup="true"  CodeFile="Default.aspx.cs" Inherits="_Default" %>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<%@ Import Namespace="Google.GData.Client" %>
<%@ Import Namespace="Google.GData.Extensions" %>
<%@ Import Namespace="Google.GData.Calendar" %>
<%@ Import Namespace="System.Net" %>

<script runat="server">
    void PrintCalendar() {

        GAuthSubRequestFactory authFactory = new GAuthSubRequestFactory("cl", "TesterApp");
        authFactory.Token = (String) Session["token"];
        CalendarService service = new CalendarService(authFactory.ApplicationName);
        service.RequestFactory = authFactory;

        EventQuery query = new EventQuery();

        query.Uri = new Uri("http://www.google.com/calendar/feeds/default/private/full");

        try
        {
            EventFeed calFeed = service.Query(query);
            foreach (Google.GData.Calendar.EventEntry entry in calFeed.Entries)
            {
                Response.Write("Event: " + entry.Title.Text + "<br/>");
            }
        }
        catch (GDataRequestException gdre)
        {
            HttpWebResponse response = (HttpWebResponse)gdre.Response;
            
            //bad auth token, clear session and refresh the page
            if (response.StatusCode == HttpStatusCode.Unauthorized)
            {
                Session.Clear();
                Response.Redirect(Request.Url.AbsolutePath, true);
            }
            else
            {
                Response.Write("Error processing request: " + gdre.ToString());
            }
        }
    }

</script>


<html xmlns="http://www.w3.org/1999/xhtml" >
<head runat="server">
    <title>Test Site</title>
</head>
<body>

    <form id="form1" runat="server">
    <h1>AuthSub Sample Page</h1>
    <div>
    <%
        GotoAuthSubLink.Visible = false;
        
        if (Session["token"] != null)
        {
            PrintCalendar();
        }
        else if (Request.QueryString["token"] != null)
        {
            String token = Request.QueryString["token"];
            Session["token"] = AuthSubUtil.exchangeForSessionToken(token, null).ToString();
            Response.Redirect(Request.Url.AbsolutePath, true);
        }
        else //no auth data, print link
        {
            GotoAuthSubLink.Text = "Login to your Google Account";
            GotoAuthSubLink.Visible = true;
            GotoAuthSubLink.NavigateUrl = AuthSubUtil.getRequestUrl(Request.Url.ToString(),
                "http://www.google.com/calendar/feeds/",false,true);
        }
        
     %>
    <asp:HyperLink ID="GotoAuthSubLink" runat="server"/>

    </div>
    </form>
</body>
</html>

Conclusione

AuthSub consente alla tua applicazione web di accedere ai dati archiviati nell'Account Google di un utente in modo sicuro e controllato. L'utilizzo della libreria client .NET consente di integrare facilmente il tuo sito web basato su ASP con i servizi Google. Questo articolo ha lo scopo di aiutarti a iniziare, ma ti consigliamo di consultare le seguenti risorse aggiuntive: