JSON Web Tokens: budowa, co należy do ładunku i różnica między dekodowaniem a weryfikacją

Przejdź do interaktywnego przykładu ↓
Spis treści
Odczyt JWT pokazuje zapisane oświadczenia. Zaufanie tym informacjom wymaga odrębnej walidacji. Rozróżnienie ma znaczenie: wiarygodnie wyglądający JSON można utworzyć bez klucza podpisu wystawcy.
Poniższe wyjaśnienie dotyczy popularnej zwartej reprezentacji JWS tokenu JWT. Trzy części oddzielone kropkami zawierają chroniony nagłówek, ładunek oraz podpis lub kod uwierzytelniania wiadomości (MAC). Pierwsze dwie części są JSON-em zakodowanym w Base64url, a nie zaszyfrowanym. Zwarty zaszyfrowany JWT używa JWE i ma pięć części. JWT oznacza format; nie każdy JWT jest tokenem dostępu.

Co potwierdzają trzy części
Nagłówek wskazuje algorytm kryptograficzny przez alg i może zawierać identyfikator klucza kid. Ładunek przechowuje oświadczenia, czyli informacje np. o wystawcy, podmiocie, odbiorcy lub kontekście uprawnień. Trzecia część chroni zakodowany nagłówek i ładunek przed niewykrytą zmianą oraz potwierdza utworzenie przez posiadacza odpowiedniego klucza podpisu lub MAC.
W algorytmie asymetrycznym klucz prywatny podpisuje, a odpowiadający klucz publiczny weryfikuje. Przy HS256 wspólny sekret służy do tworzenia i sprawdzania MAC. Każdy posiadacz tego sekretu może również tworzyć poprawne kody MAC; weryfikacja nie wskazuje jednoznacznie jednego konkretnego posiadacza. Poprawny wynik dla dowolnego klucza nie wystarcza: aplikacja musi ufać temu kluczowi dla oczekiwanego wystawcy i celu.
Dekodowanie, walidacja i autoryzacja
- Dekodowanie: odczyt oczekiwanej reprezentacji i traktowanie pól jako niezaufanych danych wejściowych.
- Weryfikacja kryptograficzna: dopuszczenie wyłącznie skonfigurowanych algorytmów i odpowiednich zaufanych kluczy oraz rzeczywiste sprawdzenie podpisu lub MAC.
- Walidacja kontekstu: sprawdzenie wystawcy, odbiorcy, typu tokenu, wymaganych pól i reguł czasowych danego profilu.
- Autoryzacja: ustalenie, czy zweryfikowany podmiot i uprawnienia pozwalają wykonać tę operację na tym zasobie.
Dekoder potrafi wyświetlić sfałszowany token. Z kolei poprawnie podpisany token może dotyczyć innego odbiorcy, być przeterminowany albo nie dawać dostępu do wskazanego konta. Wywołanie biblioteki pomaga tylko wtedy, gdy konfiguracja i pozostałe kontrole aplikacji realizują zamierzone reguły.
Aplikacja definiuje listę dozwolonych algorytmów; alg musi do niej pasować i odpowiadać dopuszczonemu typowi klucza. Niepodpisany token z alg: none jest niedopuszczalny tam, gdzie wymagany jest podpis. Pomylenie RS256 z HS256 to znany błąd podatnych lub źle skonfigurowanych weryfikatorów, a nie nieuniknione zachowanie każdej biblioteki. Publiczny klucz RSA nie może stać się sekretem HMAC.
kid jest niezaufaną wskazówką wyboru. Może wskazywać klucz w zaufanym zestawie oczekiwanego wystawcy, także w bezpiecznie pobranym JWKS. Nie może uprawniać do użycia dowolnych kluczy, adresów URL lub ścieżek plików podanych w tokenie. Token ID nie staje się tokenem dostępu do API tylko dlatego, że oba korzystają z JWT.
Oświadczenia odpowiednie do zadania
Hasła, klucze prywatne i zbędne dane osobowe nie należą do czytelnego ładunku. Nawet krótki identyfikator może być wrażliwy. Prawdziwe tokeny wymagają ochrony podczas zapisu, przesyłania, diagnostyki i obsługi zgłoszeń; materiały demonstracyjne powinny zawierać dane syntetyczne.
Role, zakresy uprawnień czy identyfikatory dzierżawców nie są bezwzględnie zabronione. RFC 9068 wprost przewiduje role i podobne oświadczenia autoryzacyjne. Znaczenie mają potrzeby odbierającej usługi, ryzyko ujawnienia oraz wymagany czas reakcji na zmiany. Rola w wydanym tokenie może się zdezaktualizować. Zapytania do serwera, krótkie okresy ważności lub inne kontrole mogą być potrzebne; odpytywanie serwera nie zachodzi automatycznie w każdej architekturze JWT.
sub wskazuje podmiot, iss wystawcę, a aud zamierzonego odbiorcę lub odbiorców. RFC 7519 nie wymaga wszystkich zarejestrowanych oświadczeń w każdym JWT. Konkretny profil protokołu może wprowadzać obowiązkowe pola; profil tokenów dostępu OAuth z RFC 9068 nakłada dodatkowe wymagania. Sama obecność nie wystarcza: wystawca i odbiorca muszą odpowiadać oczekiwanym wartościom.
Termin ważności i reguły serwera
exp i nbf używają wartości NumericDate w sekundach od epoki Uniksa, a nie milisekund JavaScript. Bez tolerancji zegara akceptacja wymaga now < exp oraz, przy obecnym nbf, now >= nbf. Dokładnie w chwili wygaśnięcia token jest już nieważny. Serwer musi również wymagać pól obowiązkowych w danym profilu; brak exp nie może po cichu omijać wymaganej kontroli ważności.
Brak exp nie oznacza zawsze nieograniczonej ważności. Reguły serwera, odwołanie dostępu, stan konta i zaufanie do klucza mogą niezależnie zablokować akceptację. Usunięcie kopii z przeglądarki nie odwołuje pozostałych kopii. Możliwe rozwiązania łączą krótko ważne tokeny dostępu z odwoływalnymi tokenami odświeżającymi, listami blokad lub introspekcją. Sam identyfikator jti nie wdraża odwoływania ani ochrony przed ponownym użyciem.
Pytania i odpowiedzi
Co zmienia rotacja klucza podpisu?
Planowana rotacja udostępnia nowy klucz weryfikacyjny, zanim będą od niego zależeć nowe podpisy. Stare klucze pozostają dostępne przez kontrolowany okres uwzględniający nadal akceptowane tokeny. Termin ważności, odbiorca i pozostałe reguły nadal obowiązują. Usunięcie starego klucza z opublikowanego JWKS nie usuwa natychmiast wszystkich kopii z pamięci podręcznych. Reguły odświeżania, cache i propagacja zmian określają moment rzeczywistego odrzucenia.
Przejęty klucz wymaga reakcji zatrzymującej dalsze użycie i wycofującej zaufanie u wszystkich dotkniętych weryfikatorów. Usunięcie jednego opublikowanego wpisu nie dowodzi natychmiastowego globalnego unieważnienia. Obsługa tokenów odświeżających zależy od rzeczywistego formatu i ścieżki walidacji; takie tokeny nie muszą być JWT.
Czy szyfrowanie czyni kopię tokenu nieszkodliwą?
Nie. JWE może ukryć oświadczenia przed stronami bez klucza deszyfrującego, lecz poświadczenie typu bearer nadal można ponownie wykorzystać bez odczytywania treści. Tokeny powiązane z nadawcą, np. przez DPoP, wymagają dodatkowych dowodów posiadania. Szyfrowanie nie potwierdza też automatycznie tożsamości zamierzonego wystawcy przy każdym trybie zarządzania kluczami. Znaczenie ma pełny profil podpisu, szyfrowania i walidacji.
Jak obsługiwać rozbieżności zegarów?
Spóźniający się weryfikator może akceptować po zamierzonym wygaśnięciu, a spieszący się odrzucać wcześniej. Niewielka skonfigurowana tolerancja uwzględnia zmierzone różnice czasu, ale przesuwa granicę akceptacji exp i może pozwalać na wcześniejszą akceptację przy nbf. Nie gwarantuje przedłużenia każdego tokenu dokładnie o ten okres: pozostałe kontrole mogą odrzucić wcześniej. Synchronizacja czasu, monitorowanie i świadomie dobrana tolerancja powinny działać łącznie.
Jakie testy negatywne są przydatne?
Zestaw testów powinien odrzucać zmieniony ładunek, zły klucz, niedozwolony algorytm, nieoczekiwanego wystawcę lub odbiorcę, token wygasły albo jeszcze nieważny, brak obowiązkowego pola i nieodpowiedni typ tokenu. Poprawny token również nie może zapewniać dostępu do niedozwolonego zasobu. Udane dekodowanie Base64 nie zastępuje takich testów.
Zrozum przez eksperyment
Jedna minuta: znajdziesz błąd?
Dekodujesz JWT i widzisz role: admin. Co wiesz na pewno?
Dekodowanie ujawnia ładunek. Zaufanie wymaga weryfikacji kryptograficznej i oczekiwanych deklaracji, np. wystawcy, odbiorcy i ważności. Aplikacja decyduje o uprawnieniach.
Jeden problem, konkretna droga do rozwiązania
Co jest w tym tokenie?
- Zrozum: Poznaj JWT
- Wypróbuj: Zbadaj token demonstracyjny
- Obejrzyj token demonstracyjny i poznaj jego pola. Czytelne dane nie potwierdzają poprawnego podpisu ani uprawnień.