Informacje o tym przewodniku
Interfejs Chrome Verified Access API umożliwia korzystanie z usług sieciowych, takich jak sieci VPN czy intranet aby zweryfikować autentyczność swoich klientów i kryptograficznie być zgodne z zasadami firmy. Większość dużych firm ma obowiązek zezwala na dostęp do sieci WPA2 EAP-TLS tylko urządzeniom zarządzanym przez firmę, dostępu wyższego poziomu w sieciach VPN i stronach intranetowych TLS wspólnych. Wiele istniejących oparte są na kontroli heurystycznych na tym samym kliencie, przejętych. Stanowi to wyzwanie, w którym sygnały są wykorzystywane potwierdzają autentyczność urządzenia, sfałszowane. Niniejszy przewodnik zawiera wspierane sprzętowo gwarancje kryptograficzne oparte na tożsamość urządzenia oraz czy jego stan był niezmodyfikowany i zgodny z zasadami; podczas uruchamiania; zweryfikowanego dostępu.
Główni odbiorcy | Administratorzy firmowych domen IT |
Komponenty techniczne | ChromeOS, interfejs Google Verified Access API |
Wymagania wstępne zweryfikowanego dostępu
Przed wdrożeniem procesu weryfikacji dostępu przeprowadź tę konfigurację.
Włącz API
Skonfiguruj projekt w konsoli interfejsów API Google i włącz interfejs API:
- Utwórz lub użyj istniejącego projektu w Konsola interfejsów API Google.
- Przejdź do Włączone interfejsy API usługi.
- Włącz Chrome Verified Access API.
- Utwórz klucz interfejsu API dla swojej aplikacji, postępując zgodnie z dokumentacją interfejsu Google Cloud API.
Tworzenie konta usługi
Aby usługa sieciowa mogła uzyskać dostęp do interfejsu Chrome Verified Access API w celu reakcja na wyzwanie, utworzyć konto usługi oraz klucz konta usługi (nie musisz tworzyć nowego projektu Cloud, możesz użyć tego samego).
Po utworzeniu klucza konta usługi powinno być już ono gotowe. plik z kluczem prywatnym został pobrany. To jedyna kopia klucza prywatnego, więc upewnij się, przechowywać go w bezpiecznym miejscu.
Rejestrowanie zarządzanego Chromebooka
Musisz mieć odpowiednio zarządzanego Chromebooka z przeglądarką Chrome. do weryfikacji dostępu.
- Urządzenie Chromebook musi być zarejestrowane w usłudze zarządzania w firmie lub instytucji edukacyjnej.
- Użytkownik urządzenia musi być zarejestrowanym użytkownikiem w tej samej domenie.
- Na urządzeniu musi być zainstalowane rozszerzenie do Chrome umożliwiające Zweryfikowany dostęp.
- Zasady są skonfigurowane tak, aby włączyć zweryfikowany dostęp; dodać Chrome do listy dozwolonych. i przyznać dostęp do interfejsu API kontu usługi reprezentującemu usługi sieciowej (zobacz dokumentacji pomocy konsoli administracyjnej Google).
Zweryfikuj użytkownika i urządzenie
Deweloperzy mogą używać zweryfikowanego dostępu do weryfikacji użytkowników lub urządzeń albo używać obu tych metod dla większego bezpieczeństwa:
Weryfikacja urządzenia – w przypadku pomyślnej weryfikacji urządzenie generuje zagwarantowanie, że urządzenie z Chrome zostanie zarejestrowane w zarządzanej domenie, jest zgodne z zasadami dotyczącymi urządzenia w trybie zweryfikowanym rozruchem określonym przez domenę. . Jeśli usługa sieciowa ma uprawnienia do wyświetlania urządzenia (zobacz dokumentację pomocy konsoli administracyjnej Google), otrzyma też identyfikatora urządzenia, którego można używać do kontroli, śledzenia i wywoływania interfejsu Directory API.
Weryfikacja użytkownika – jeśli weryfikacja przebiegnie pomyślnie, weryfikacja użytkownika będzie gwarantować. zalogowany użytkownik Chrome jest użytkownikiem zarządzanym i korzysta z zarejestrowanego urządzenia; jest zgodna z zasadami dotyczącymi użytkownika w trybie weryfikacji podczas uruchamiania określonymi przez domenę . Jeśli usługa sieciowa ma uprawnienia do odbierania danych użytkownika, uzyskałoby również żądanie podpisania certyfikatu przez użytkownika (CSR w formacie signed-public-key-and-challenge, SPKAC, (znanego też jako format generatora kluczy).
Jak potwierdzić tożsamość użytkownika i urządzenia
Podejmij wyzwanie – rozszerzenie do Chrome na urządzeniu kontaktuje się ze Zweryfikowanym. Uzyskaj dostęp do interfejsu API, aby uzyskać test. Wyzwanie jest niejednoznaczne (obiekt blob podpisany przez Google), trwający 1 minutę, co oznacza, weryfikacja typu test-odpowiedź (krok 3) nie powiedzie się, jeśli zostanie użyte nieaktualne zadanie.
W najprostszym przypadku użycia użytkownik inicjuje proces, klikając przycisk, które generuje rozszerzenie (to samo dotyczy rozszerzenia udostępnionego przez Google, robi).
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 } };
Kod pomocniczy do kodowania wyzwania – jeśli korzystasz z interfejsu API w wersji 1, tag musi być zakodowany.
// 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); } };
Wygeneruj odpowiedź na wyzwanie – rozszerzenie do Chrome używa tego testu zabezpieczającego. otrzymane w kroku 1 w celu wywołania interfejsu enterprise.platformKeys Chrome API. Ten generuje podpisaną i zaszyfrowaną odpowiedź testową, którą rozszerzenie uwzględniony w żądaniu dostępu wysyłanym do usługi sieciowej.
Nie ma próby zdefiniowania protokołu, w którym rozszerzenie i przez usługi sieciowe do komunikacji. Oba te elementy są zaimplementowane przez zewnętrznych programistów i nie określają, jak porozumiewają się ze sobą. An przykładem może być wysłanie odpowiedzi (zakodowanej w adresie URL) jako ciągu zapytania za pomocą żądania HTTP POST lub specjalnego nagłówka HTTP.
Oto przykładowy kod do wygenerowania odpowiedzi na zadanie:
Generowanie odpowiedzi na wyzwanie
// 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); }
Funkcja wywołania zwrotnego testu
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 }; }
Kod pomocniczy konwersji 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; }
Zweryfikuj odpowiedź w ramach wyzwania – po otrzymaniu odpowiedzi zabezpieczającej od (może być rozszerzeniem istniejącego protokołu uwierzytelniania), usługa sieciowa powinna wywoływać interfejs Verified Access API w celu zweryfikowania urządzenia tożsamości i stan zasad (zobacz przykładowy kod poniżej). Aby zwalczać podszywanie się, Zaleca się, aby usługa sieciowa zidentyfikowała klienta, z którym się komunikuje, oraz podaj w żądaniu oczekiwaną tożsamość klienta:
- Na potrzeby weryfikacji urządzenia należy podać oczekiwaną domenę urządzenia , W wielu przypadkach jest to prawdopodobnie wartość zakodowana na stałe, ponieważ chroni zasoby konkretnej domeny. Jeśli te informacje nie są znane można ją wywnioskować na podstawie tożsamości użytkownika.
- Na potrzeby weryfikacji użytkownika oczekiwany adres e-mail użytkownika to dostępna. Oczekujemy, że usługa sieciowa będzie znała swoich użytkowników (zwykle wymagałoby od użytkowników zalogowania się).
Po wywołaniu interfejsu API Google wykonuje on kilka testów, na przykład:
- Sprawdź, czy odpowiedź w ramach wyzwania pochodzi z ChromeOS i nie zmodyfikowane w trakcie przesyłania
- Sprawdź, czy urządzenie lub użytkownik są zarządzane przez firmę.
- Sprawdź, czy tożsamość urządzenia/użytkownika jest zgodna z oczekiwaniami tożsamości (jeśli podano drugą).
- Sprawdź, czy zadanie, na które odpowiadasz, to nowe (nie starsze niż minutę).
- Sprawdzić, czy urządzenie lub użytkownik spełnia wymagania określone w z administratorem domeny.
- Sprawdź, czy element wywołujący (usługa sieciowa) ma uprawnienia do nawiązania połączenia interfejs API.
- Jeśli rozmówca otrzyma pozwolenie na uzyskanie dodatkowego urządzenia lub dane użytkownika, dołącz identyfikator urządzenia lub podpis użytkownika za pomocą certyfikatu (CSR) w odpowiedzi.
W tym przykładzie wykorzystuje się bibliotekę 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(); }
Przyznaj dostęp – ten krok dotyczy też usługi sieciowej. To jest sugerowane (niezalecane) wdrożenie. Możliwe działania to:
- Utworzenie pliku cookie sesji
- Wystawianie certyfikatu użytkownika lub urządzenia. W przypadku konta użytkownika oraz przy założeniu, że usłudze sieciowej przyznano dostęp do dodatkowych danych użytkownika (zgodnie z zasadami konsoli administracyjnej Google), wysyłanego przez użytkownika żądania podpisania certyfikatu, które można następnie wykorzystać do uzyskania rzeczywistego certyfikat wystawiony przez urząd certyfikacji. W przypadku integracji z MicrosoftR CA, usługa sieciowa może działać jako pośrednikiem za pomocą interfejsu ICertRequest.
Używanie certyfikatów klienta ze zweryfikowanym dostępem
W dużej organizacji może być dostępnych wiele usług sieciowych (serwery VPN, punkty dostępu Wi-Fi, zapory sieciowe i wiele witryn intranetowych), które skorzystać ze zweryfikowanego dostępu. Stworzenie logiki kroków 2–4 (opisanej powyżej) w każdej z tych usług sieciowych mogą nie być praktyczny. Często wiele z tych usług sieciowych już ma możliwość wymagać certyfikatów klienta w ramach uwierzytelniania (na przykład EAP-TLS lub wzajemne strony intranetowe TLS). Jeśli więc certyfikat Enterprise Certificate Urząd, który wystawia te certyfikaty klienta, może wdrożyć kroki 2–4 oraz warunek wystawiania certyfikatu klienta na pytanie-odpowiedź to posiadanie takiego certyfikatu może stanowić dowód Klient jest autentyczny i przestrzega zasad obowiązujących w firmie. Potem każdą sieć Wi-Fi punkt dostępu, serwer VPN itp. może sprawdzić ten certyfikat klienta zamiast wykonywać kroki 2–4.
Innymi słowy, tutaj urząd certyfikacji (który wystawia certyfikat klienta dla przedsiębiorstwa, urządzeń) przyjmuje rolę usługi sieciowej na rys. 1. Musi wywołać przy użyciu interfejsu Verified Access API oraz (tylko po weryfikacji odpowiedzi na żądanie) prześlij certyfikat klientowi. Udostępnienie certyfikatu Klient jest odpowiednikiem kroku 4 – Udziel dostępu z ilustracji 1.
Opisuje proces bezpiecznego przenoszenia certyfikatów klienta na Chromebooki. w tym artykule. Jeśli zgodnie z opisem w tym akapicie, a następnie wybierz Rozszerzenie zweryfikowanego dostępu. i rozszerzenia do wprowadzania certyfikatów klienta można połączyć w jedno. Więcej informacji o tym, jak napisać rozszerzenie wprowadzające do certyfikatu klienta.