Guide du développeur de l'accès validé à Chrome

À propos de ce guide

L'API Chrome Verified Access permet d'utiliser des services réseau comme les VPN, pour vérifier de manière cryptographique que les clients sont authentiques sont conformes à la politique de l'entreprise. La plupart des grandes entreprises doivent autoriser uniquement les appareils gérés par l'entreprise sur leurs réseaux WPA2 EAP-TLS, un accès de niveau supérieur dans les VPN et des pages intranet TLS mutuelle. Un grand nombre s'appuient sur des vérifications heuristiques sur le même client ou compromis. Il y a donc le défi que les signaux sur lesquels on s'appuie pour qui attestent de l'état légitime de l'appareil falsifiée. Ce guide fournit des garanties cryptographiques intégrées au matériel l'identité de l'appareil, et que son état n'a pas été modifié et que son état est conforme aux règles au démarrage, appelée "Accès validé".

Audience principale Administrateurs de domaines informatiques en entreprise
Composants techniques ChromeOS, API Google Verified Access

Conditions préalables à l'accès validé

Effectuez la configuration suivante avant de mettre en œuvre le processus de validation de l'accès.

Activer l'API

Configurez un projet de console Google APIs et activez l'API:

  1. Créez ou utilisez un projet existant dans le Console Google APIs
  2. Accédez au API activées et des services Google.
  3. Activez l'API Verified Access pour Chrome.
  4. Créez une clé API pour votre application en suivant la documentation de l'API Google Cloud.

Créer un compte de service

Pour que le service réseau accède à l'API Chrome Verified Access afin de vérifier votre les défis et réponses, Créer un compte de service et une clé de compte de service (vous n'avez pas besoin de créer un projet Cloud, vous pouvez utiliser le même projet).

Une fois la clé de compte de service créée, vous devez disposer d'un compte de service fichier de clé privée téléchargé. Il s'agit de la seule copie de la clé privée, assurez-vous de le conserver en toute sécurité.

Enregistrer un Chromebook géré

Vous devez configurer un Chromebook correctement géré avec votre navigateur Chrome. pour l'accès validé.

  1. L'appareil Chromebook doit être enregistré pour la gestion de l'entreprise ou de l'enseignement.
  2. L'appareil doit être un utilisateur enregistré appartenant au même domaine.
  3. L'extension Chrome pour l'accès validé doit être installée sur l'appareil.
  4. Les règles sont configurées pour activer l'accès validé, ajouter Chrome à la liste d'autorisation et accordez l'accès à l'API au compte de service représentant service réseau (consultez la documentation de la console d'administration Google).

Valider l'utilisateur et l'appareil

Les développeurs peuvent utiliser l'accès validé pour la validation des utilisateurs ou des appareils, ou les deux. pour plus de sécurité:

  • Validation de l'appareil : en cas de réussite, la validation de l'appareil fournit un garantir que l'appareil Chrome est inscrit dans un domaine géré et qu'il La règle est conforme aux règles relatives aux appareils en mode de démarrage validé, comme spécifié par le domaine administrateur. Si le service réseau est autorisé à voir l'appareil (voir la documentation d'aide de la console d'administration Google), il reçoit également ID d'appareil permettant d'auditer, de suivre ou d'appeler l'API Directory.

  • Validation de l'utilisateur : en cas de réussite, la validation de l'utilisateur offre une garantie. qu'un utilisateur Chrome connecté est un utilisateur géré, qu'il utilise un appareil enregistré ; est conforme aux règles relatives aux utilisateurs du mode de démarrage validé, comme spécifié par le domaine administrateur. Si le service réseau est autorisé à recevoir des données utilisateur supplémentaires, il obtiendra également une demande de signature de certificat émise par l'utilisateur (CSR sous la forme d'une clé publique signée et d'un défi, ou SPKAC, (également appelé format keygen).

Valider un utilisateur et un appareil

  1. Obtenir un test d'authentification : l'extension Chrome installée sur l'appareil contacte l'utilisateur validé Accédez à l'API pour obtenir un test. Le défi est que les données sont opaques (un blob signé par Google) qui est valable pendant une minute, c'est-à-dire que La validation de la question d'authentification (étape 3) échoue si une question d'authentification obsolète est utilisée.

    Dans le cas d'utilisation le plus simple, l'utilisateur lance ce flux en cliquant sur un bouton qui génère l'extension (il s'agit également de l'exemple d'extension fourni par Google). le cas échéant).

    var apiKey = 'YOUR_API_KEY_HERE';
    var challengeUrlString =
      'https://verifiedaccess.googleapis.com/v2/challenge:generate?key=' + apiKey;
    
    // Request challenge from URL
    var xmlhttp = new XMLHttpRequest();
    xmlhttp.open('POST', challengeUrlString, true);
    xmlhttp.send();
    xmlhttp.onreadystatechange = function() {
      if (xmlhttp.readyState == 4) {
        var challenge = xmlhttp.responseText;
        console.log('challenge: ' + challenge);
        // v2 of the API returns an encoded challenge so no further challenge processing is needed
      }
    };
    

    Code d'aide pour encoder le défi : si vous utilisez la version 1 de l'API, la classe votre question d'authentification doit être encodée.

    // This can be replaced by using a third-party library such as
    // [https://github.com/dcodeIO/ProtoBuf.js/wiki](https://github.com/dcodeIO/ProtoBuf.js/wiki)
    /**
     * encodeChallenge convert JSON challenge into base64 encoded byte array
     * @param {string} challenge JSON encoded challenge protobuf
     * @return {string} base64 encoded challenge protobuf
     */
    var encodeChallenge = function(challenge) {
      var jsonChallenge = JSON.parse(challenge);
      var challengeData = jsonChallenge.challenge.data;
      var challengeSignature = jsonChallenge.challenge.signature;
    
      var protobufBinary = protoEncodeChallenge(
          window.atob(challengeData), window.atob(challengeSignature));
    
      return window.btoa(protobufBinary);
    };
    
    /**
     * protoEncodeChallenge produce binary encoding of the challenge protobuf
     * @param {string} dataBinary binary data field
     * @param {string} signatureBinary binary signature field
     * @return {string} binary encoded challenge protobuf
     */
    var protoEncodeChallenge = function(dataBinary, signatureBinary) {
      var protoEncoded = '';
    
      // See https://developers.google.com/protocol-buffers/docs/encoding
      // for encoding details.
    
      // 0x0A (00001 010, field number 1, wire type 2 [length-delimited])
      protoEncoded += '\u000A';
    
      // encode length of the data
      protoEncoded += varintEncode(dataBinary.length);
      // add data
      protoEncoded += dataBinary;
    
      // 0x12 (00010 010, field number 2, wire type 2 [length-delimited])
      protoEncoded += '\u0012';
      // encode length of the signature
      protoEncoded += varintEncode(signatureBinary.length);
      // add signature
      protoEncoded += signatureBinary;
    
      return protoEncoded;
    };
    
    /**
     * varintEncode produce binary encoding of the integer number
     * @param {number} number integer number
     * @return {string} binary varint-encoded number
     */
    var varintEncode = function(number) {
      // This only works correctly for numbers 0 through 16383 (0x3FFF)
      if (number <= 127) {
        return String.fromCharCode(number);
      } else {
        return String.fromCharCode(128 + (number & 0x7f), number >>> 7);
      }
    };
    
  2. Générer une question d'authentification : l'extension Chrome utilise la question d'authentification qu'elle reçu à l'étape 1 pour appeler l'API Chrome enterprise.platformKeys. Ce génère une réponse d'authentification signée et chiffrée, que l'extension inclut dans la demande d’accès qu’il envoie au service réseau.

    Au cours de cette étape, il n'y a pas de tentative de définir un protocole que l'extension et de service réseau pour communiquer. Ces deux entités sont implémentées par des développeurs externes et leur façon de communiquer entre eux n'est pas obligatoire. Une Par exemple, vous pouvez envoyer une réponse d'authentification (encodée au format URL) sous forme de chaîne de requête , en utilisant HTTP POST ou en utilisant un en-tête HTTP spécial.

    Voici un exemple de code permettant de générer une réponse à la question d'authentification:

    Générer une question d'authentification

      // Generate challenge response
      var encodedChallenge; // obtained by generate challenge API call
      try {
        if (isDeviceVerification) { // isDeviceVerification set by external logic
          chrome.enterprise.platformKeys.challengeKey(
              {
                scope: 'MACHINE',
                challenge: decodestr2ab(encodedChallenge),
              },
              ChallengeCallback);
        } else {
          chrome.enterprise.platformKeys.challengeKey(
              {
                scope: 'USER',
                challenge: decodestr2ab(encodedChallenge),
                registerKey: { 'RSA' }, // can also specify 'ECDSA'
              },
              ChallengeCallback);
        }
      } catch (error) {
        console.log('ERROR: ' + error);
      }
    

    Fonction de rappel du défi

      var ChallengeCallback = function(response) {
        if (chrome.runtime.lastError) {
          console.log(chrome.runtime.lastError.message);
        } else {
          var responseAsString = ab2base64str(response);
          console.log('resp: ' + responseAsString);
        ... // send on to network service
       };
      }
    

    Code d'aide pour la conversion de ArrayBuffer

      /**
       * ab2base64str convert an ArrayBuffer to base64 string
       * @param {ArrayBuffer} buf ArrayBuffer instance
       * @return {string} base64 encoded string representation
       * of the ArrayBuffer
       */
      var ab2base64str = function(buf) {
        var binary = '';
        var bytes = new Uint8Array(buf);
        var len = bytes.byteLength;
        for (var i = 0; i < len; i++) {
          binary += String.fromCharCode(bytes[i]);
        }
        return window.btoa(binary);
      }
    
      /**
       * decodestr2ab convert a base64 encoded string to ArrayBuffer
       * @param {string} str string instance
       * @return {ArrayBuffer} ArrayBuffer representation of the string
       */
      var decodestr2ab = function(str) {
        var binary_string =  window.atob(str);
        var len = binary_string.length;
        var bytes = new Uint8Array(len);
        for (var i = 0; i < len; i++)        {
            bytes[i] = binary_string.charCodeAt(i);
        }
        return bytes.buffer;
      }
    
  3. Vérifier la réponse à la question d'authentification : après avoir reçu la réponse d'un (peut-être comme extension d'un protocole d'authentification existant), le service réseau doit appeler l'API Verified Access pour valider l'appareil stratégie d'identité et de stratégie (voir l'exemple de code ci-dessous). Pour lutter contre le spoofing, recommandent au service réseau d'identifier le client avec lequel il communique et inclure l'identité attendue du client dans sa requête:

    • Pour la validation de l'appareil, le domaine attendu de l'appareil doit être indiqué. pour en savoir plus. Dans de nombreux cas, il s'agit probablement d'une valeur codée en dur, car le réseau protège les ressources d'un domaine particulier. Si cette information n'est pas connue à l'avance, il peut être déduit de l'identité de l'utilisateur.
    • Pour la validation de l'utilisateur, l'adresse e-mail de l'utilisateur attendu doit être fournies. Nous nous attendons à ce que le service réseau connaisse ses utilisateurs (normalement, obligeront les utilisateurs à se connecter).

    Lorsque l'API Google est appelée, elle effectue un certain nombre de vérifications, par exemple:

    • Vérifiez que la réponse à la question d'authentification est produite par ChromeOS et n'est pas modifié en transit
    • Vérifiez que l'appareil ou l'utilisateur sont gérés par une entreprise.
    • Vérifiez que l'identité de l'appareil/de l'utilisateur correspond à celle attendue (si cette dernière est fournie).
    • Vérifiez que la question d'authentification récentes (datant d'une minute maximum)
    • Vérifiez que l'appareil ou l'utilisateur respecte les règles spécifiées dans l'administrateur du domaine.
    • Vérifier que l'appelant (service réseau) est autorisé à appeler l'API.
    • Si l'appelant est autorisé à obtenir un appareil ou les données utilisateur, y compris l'ID de l'appareil ou la signature du certificat de l'utilisateur ; dans la réponse.

    Cet exemple utilise la bibliothèque gRPC

    import com.google.auth.oauth2.GoogleCredentials;
    import com.google.auth.oauth2.ServiceAccountCredentials;
    import com.google.chrome.verifiedaccess.v2.VerifiedAccessGrpc;
    import com.google.chrome.verifiedaccess.v2.VerifyChallengeResponseRequest;
    import com.google.chrome.verifiedaccess.v2.VerifyChallengeResponseResult;
    import com.google.protobuf.ByteString;
    
    import io.grpc.ClientInterceptor;
    import io.grpc.ClientInterceptors;
    import io.grpc.ManagedChannel;
    import io.grpc.auth.ClientAuthInterceptor;
    import io.grpc.netty.GrpcSslContexts;
    import io.grpc.netty.NettyChannelBuilder;
    
    import java.io.File;
    import java.io.FileInputStream;
    import java.util.Arrays;
    import java.util.concurrent.Executors;
    
    // https://cloud.google.com/storage/docs/authentication#generating-a-private-key
    private final String clientSecretFile = "PATH_TO_GENERATED_JSON_SECRET_FILE";
    
    private ManagedChannel channel;
    private VerifiedAccessGrpc.VerifiedAccessBlockingStub client;
    
    void setup() {
    
       channel = NettyChannelBuilder.forAddress("verifiedaccess.googleapis.com", 443)
          .sslContext(GrpcSslContexts.forClient().ciphers(null).build())
          .build();
    
       List<ClientInterceptor> interceptors = Lists.newArrayList();
       // Attach a credential for my service account and scope it for the API.
       GoogleCredentials credentials =
           ServiceAccountCredentials.class.cast(
               GoogleCredentials.fromStream(
                   new FileInputStream(new File(clientSecretFile))));
      credentials = credentials.createScoped(
          Arrays.<String>asList("https://www.googleapis.com/auth/verifiedaccess"));
      interceptors.add(
           new ClientAuthInterceptor(credentials, Executors.newSingleThreadExecutor()));
    
      // Create a stub bound to the channel with the interceptors applied
      client = VerifiedAccessGrpc.newBlockingStub(
          ClientInterceptors.intercept(channel, interceptors));
    }
    
    /**
     * Invokes the synchronous RPC call that verifies the device response.
     * Returns the result protobuf as a string.
     *
     * @param signedData base64 encoded signedData blob (this is a response from device)
     * @param expectedIdentity expected identity (domain name or user email)
     * @return the verification result protobuf as string
     */
    public String verifyChallengeResponse(String signedData, String expectedIdentity)
      throws IOException, io.grpc.StatusRuntimeException {
      VerifyChallengeResponseResult result =
        client.verifyChallengeResponse(newVerificationRequest(signedData,
            expectedIdentity)); // will throw StatusRuntimeException on error.
    
      return result.toString();
    }
    
    private VerifyChallengeResponseRequest newVerificationRequest(
      String signedData, String expectedIdentity) throws IOException {
      return VerifyChallengeResponseRequest.newBuilder()
        .setChallengeResponse(
            ByteString.copyFrom(BaseEncoding.base64().decode(signedData)))
        .setExpectedIdentity(expectedIdentity == null ? "" : expectedIdentity)
        .build();
    }
    
  4. Accorder l'accès : cette étape est également spécifique à un service réseau. Il s'agit d'un implémentation suggérée (non prescrite). Voici des exemples d'actions possibles:

    • Création d'un cookie de session
    • Émission d'un certificat pour l'utilisateur ou l'appareil En cas de succès vérification, et en supposant que le service réseau s’est vu accorder l’accès à d'autres données utilisateur (via les règles de la console d'administration Google), reçoit une requête de signature de certificat signée par l'utilisateur, qui peut ensuite être utilisée pour obtenir de l'autorité de certification. Lors de l'intégration avec MicrosoftR, le service réseau peut agir en tant que un intermédiaire et utiliser l'interface ICertRequest.

Utiliser des certificats client avec accès validé

<ph type="x-smartling-placeholder">
</ph> <ph type="x-smartling-placeholder">
</ph> Utiliser des certificats client avec accès validé

Dans une grande organisation, il peut y avoir plusieurs services réseau (serveurs VPN, points d'accès Wi-Fi, pare-feu et plusieurs sites intranet) qui bénéficierait de cette fonctionnalité. Cependant, créer la logique des étapes 2 à 4 (dans la section ci-dessus) de chacun de ces services réseau peuvent ne pas pratiques. Souvent, nombre de ces services réseau ont déjà la capacité de exigent des certificats clients dans leurs authentifications (par exemple, pages intranet EAP-TLS ou TLS mutuel). Donc, si le certificat d'entreprise L'autorité qui émet ces certificats clients peut mettre en œuvre les étapes 2 à 4 et conditionner l'émission du certificat client sur le défi-réponse vérification, alors la possession du certificat peut être la preuve que le client est authentique et respecte la politique de l'entreprise. Chaque connexion Wi-Fi le point d'accès, le serveur VPN, etc., pourraient vérifier au lieu de suivre les étapes 2 à 4.

En d'autres termes, ici l'autorité de certification (qui émet le certificat client à l'entreprise appareils) joue le rôle du service réseau de la figure 1. Il doit appeler l'API Verified Access et, uniquement lors de la validation de la question d'authentification réussissez, fournissez le certificat au client. Fournir le certificat à le client est l'équivalent de l'Étape 4 (Accorder l'accès) de la figure 1.

Le processus permettant d'obtenir des certificats client sur des Chromebooks de manière sécurisée est décrit consultez cet article. Si le décrit dans ce paragraphe, le système Verified Access Extension et l'extension d'intégration des certificats client peuvent être combinées en une seule. En savoir plus pour savoir comment écrire une extension d'intégration des certificats client.