Utiliser AuthSub avec la bibliothèque cliente .NET

Jeff Fisher, équipe Google Data APIs
Août 2007

Introduction: pourquoi AuthSub est-il important ?

L'avantage des API Google Data ("GData") est de permettre aux développeurs de créer des applications qui interagissent avec les services Google. Plus précisément, elles vous permettent d'accéder à des données utilisateur privées pour les utiliser dans votre application. Les API vous permettent d'écrire des applications pour synchroniser, importer, exporter et gérer ces données. Bien que les API vous accordent ces puissantes capacités, vous devez vous souvenir de les utiliser de manière responsable. Les données utilisateur étant des informations privées, vous souhaitez naturellement y accéder de manière sécurisée. La possibilité de s'authentifier auprès des serveurs de Google de manière sécurisée est un élément essentiel de cette approche.

Imaginons que vous ayez une nouvelle application Web intéressante et que vous souhaitiez l'associer aux données stockées dans les services Web Google. Vous souhaitez maintenant vous authentifier afin d'accéder à ces données privées. Pourquoi ne pas simplement utiliser un système simple, tel que ClientLogin ? Eh bien, ça fera l'affaire, mais vous traiterez encore plus de données privées: les identifiants de l'utilisateur. ClientLogin nécessite que votre application demande le nom d'utilisateur et le mot de passe Google de l'utilisateur. Cela ne pose pas de problème pour une application de bureau qui s'exécute sur l'ordinateur personnel de l'utilisateur, mais c'est moins bien pour une application Web. Outre la gestion de ces identifiants sur votre propre serveur, certains de vos utilisateurs les plus prudents pourraient craindre que vous ne stockiez leurs informations. Les utilisateurs s'inquiètent également du fait de ne vouloir autoriser un programme à accéder qu'à un seul service particulier (comme les événements de leur agenda Google), mais pas à un autre service (comme leurs documents Google). AuthSub résout ces deux problèmes en permettant à un utilisateur de s'authentifier via les serveurs de Google et permet à votre programme de demander uniquement l'accès dont il a besoin.

Maintenant que vous en savez suffisamment sur la théorie sur AuthSub, il est temps de passer au codage. Pour cet article, j'ai choisi de faire simple et de tout faire sur une seule page ASP, mais vous devriez pouvoir intégrer facilement les techniques présentées ici à votre propre application.

Gérer l'authentification

De quoi avez-vous besoin pour utiliser AuthSub dans votre application Web ? Tout d'abord, il existe des importations standards à partir de la bibliothèque cliente GData:

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

La première chose à faire est d'envoyer l'utilisateur vers une URL spécialement conçue à cet effet. Cela permet aux serveurs Google de gérer l'authentification, puis de rediriger l'utilisateur vers votre site Web. Heureusement, vous n'avez pas à générer cette URL manuellement, car il existe des méthodes pour le faire. Voyons un exemple :

authSubUrl = AuthSubUtil.getRequestUrl(target, scope, secure, session);
  • target : chaîne contenant l'URL de votre application Web. Il s'agit de la page vers laquelle l'utilisateur sera redirigé après l'authentification.
  • scope : cette chaîne est déterminée par l'API que vous utilisez. Il correspond à l'un des flux d'une API GData. Par exemple, le flux contenant toutes les informations de l'agenda d'un utilisateur est "http://www.google.com/calendar/feeds/default/private/full".
  • secure (booléen) : il s'agit d'une valeur booléenne qui indique au serveur que vous vous êtes enregistré auprès de Google. Elle va signer vos requêtes de manière cryptographique. Cet argument est généralement défini sur "false" par défaut, en particulier dans un environnement de test.
  • session : il s'agit d'une autre valeur booléenne indiquant que vous préférez un "jeton de session" plutôt qu'un "jeton à utilisation unique". Le rôle de cet argument sera plus clair dans un instant.

Lorsque l'utilisateur clique sur l'URL générée, il est redirigé vers une page "Comptes Google" qui lui permet de se connecter à son compte Google. Ils sont ensuite redirigés vers la page Web que vous avez spécifiée dans la variable "target", mais avec un paramètre de requête "token" qui contient un jeton à usage unique. Normalement, ce jeton ne peut être utilisé qu'une seule fois. Autrement dit, vous pouvez l'utiliser pour effectuer une action sur un flux donné. Toutefois, si vous avez spécifié true comme paramètre "session", il peut être échangé contre un "jeton de session" qui peut être réutilisé jusqu'à la fin de la session. Pour ce faire, procédez comme suit:

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

Ici, vous allez extraire le jeton du paramètre de requête et l'échanger contre un "jeton de session". Ensuite, pour qu'il puisse être enregistré en vue d'une utilisation ultérieure, vous pouvez choisir de le stocker dans le tableau automatique Session de .NET. Vous pouvez également choisir de stocker le jeton dans une base de données. L'étape suivante consiste à utiliser ce jeton pour effectuer une requête authentifiée:

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

Ici, vous allez configurer un objet CalendarService pour interagir avec l'API Google Calendar à l'aide de l'authentification AuthSub. Notez que "cl" utilisé dans le constructeur pour GAuthSubRequestFactory est le nom de service pour Agenda. Vous pouvez consulter les questions fréquentes sur les API Google Data pour obtenir d'autres noms de service.

AuthSub (sécurisé)

Si vous choisissez d'enregistrer votre application Web, vous pouvez activer un niveau de sécurité supplémentaire tout en utilisant AuthSub. Cela vous permet de signer numériquement toutes les requêtes effectuées par votre code, afin que quelqu'un ne puisse pas utiliser les jetons AuthSub qui vous sont délivrés, à moins de disposer de votre clé privée. La première étape consiste à vérifier que vous générez le bon lien AuthSub lorsque vous appelez AuthSubUtil.getRequestUrl en définissant l'argument "secure" sur true. Vous devez apporter deux autres modifications au code:

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

...

authFactory.PrivateKey = rsaKey;

Tout d'abord, notez que vous remplacez maintenant la variable "rsaKey" par la méthode exchangeForSessionToken au lieu de null. Cette même variable permet également de définir une propriété de GAuthSubRequestFactory lors de la configuration de la connexion au service. La variable "rsaKey" est un RSACryptoServiceProvider correspondant au composant de clé privée du certificat x509 que vous avez enregistré auprès de Google.

La génération d'une clé privée RSA et d'un certificat autosigné peut s'avérer un peu déroutante, car le framework .NET ne comprend pas les clés ni les certificats stockés au format PEM. Les commandes suivantes montrent comment générer une clé privée et un certificat public à l'aide de la suite d'outils 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"

La première étape génère une clé privée et un certificat X509 public, au format PEM appelé respectivement "test_key.pem" et "test_cert.pem". Notez que l'enregistrement du certificat auprès de "www.example.com" est basé à Mountain View, en Californie (États-Unis). Remplacez ici les valeurs appropriées pour votre entreprise. Le fichier "test_cert.pem" contient les informations que vous devez fournir sur la page d'inscription à AuthSub.

La deuxième étape génère un fichier PFX à partir de votre clé privée et de votre certificat. Ce fichier peut être importé dans la bibliothèque cliente .NET pour signer numériquement les requêtes adressées aux API GData. Le code suivant montre comment importer la clé privée du fichier PFX dans une application Web:

protected AsymmetricAlgorithm getRsaKey()
{

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

  return privateKey;
}

La fonction getRsaKey() définie par cet extrait de code peut être utilisée à la place de la variable "rsaKey" ci-dessus pour s'authentifier auprès des API. Naturellement, le chemin d'accès au fichier doit être remplacé par l'emplacement approprié du fichier PFX que vous avez généré.

Fiche de code complète

La façon la plus simple de montrer comment utiliser les méthodes présentées dans la section précédente est d'utiliser un exemple en direct. L'exemple de code suivant est une page ASP simple qui authentifie l'utilisateur à l'aide d'AuthSub, puis affiche les événements de son agenda Google.

<%@ 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>

Conclusion

AuthSub permet à votre application Web d'accéder aux données stockées dans le compte Google d'un utilisateur de manière sécurisée et contrôlée. La bibliothèque cliente .NET vous permet d'intégrer facilement votre site Web ASP aux services Google. Cet article est conçu pour vous aider à démarrer. Toutefois, nous vous encourageons à consulter d'autres ressources: