Používanie JWT s Spring Security OAuth

1. Prehľad

V tomto tutoriáli si ukážeme, ako získať implementáciu Spring Security OAuth2 na využitie webových tokenov JSON.

Ďalej pokračujeme v stavaní na vrchole článku Spring REST API + OAuth2 + Angular v tejto sérii OAuth.

2. Autorizačný server OAuth2

Zásobník Spring Security OAuth predtým ponúkol možnosť nastavenia autorizačného servera ako jarnej aplikácie. Potom sme ho museli nakonfigurovať na použitie JwtTokenStore aby sme mohli používať tokeny JWT.

Zásobník OAuth bol však jarom zastaraný a teraz budeme ako autorizačný server používať Keycloak.

Tentokrát teda nastavíme náš autorizačný server ako zabudovaný server Keycloak v aplikácii Spring Boot. Štandardne vydáva tokeny JWT, takže v tejto súvislosti nie je potrebná žiadna iná konfigurácia.

3. Zdrojový server

Poďme sa teraz pozrieť na to, ako nakonfigurovať náš zdrojový server na používanie JWT.

Urobíme to v aplikácia.yml spis:

server: port: 8081 servlet: kontextová cesta: / zdroj-server jar: zabezpečenie: oauth2: resourceserver: jwt: issuer-uri: // localhost: 8083 / auth / realms / baeldung jwk-set-uri: // localhost: 8083 / auth / realms / baeldung / protocol / openid-connect / certs

JWT obsahujú všetky informácie v rámci Tokenu. Zdrojový server teda musí overiť podpis tokenu, aby sa ubezpečil, že údaje neboli upravené. The jwk-set-uri nehnuteľnosť obsahuje verejný kľúč server môže na tento účel použiť.

The vydavateľ-uri Vlastnosť ukazuje na základný identifikátor URI autorizačného servera, ktorý možno tiež použiť na overenie iss nárok ako ďalšie bezpečnostné opatrenie.

Tiež, ak jwk-set-uri vlastnosť nie je nastavená, server zdrojov sa pokúsi použiť server vydavateľ-ui na určenie umiestnenia tohto kľúča z koncového bodu metadát autorizačného servera.

Dôležité je, že pridáte vydavateľ-uri majetok nariaďuje, že pred spustením aplikácie Resource Server by sme mali mať spustený autorizačný server.

Teraz sa pozrime, ako môžeme nakonfigurovať podporu JWT pomocou konfigurácie Java:

@Configuration verejná trieda SecurityConfig rozširuje WebSecurityConfigurerAdapter {@Override chránená neplatná konfigurácia (HttpSecurity http) vyvolá výnimku {http.cors (). A () .authorizeRequests () .antMatchers (HttpMethod.GET, "/ user / info", "/ api / foos / ** ") .hasAuthority (" SCOPE_read ") .antMatchers (HttpMethod.POST," / api / foos ") .hasAuthority (" SCOPE_write ") .anyRequest () .authenticated (). a () .oauth2ResourceServer ( ) .jwt (); }}

Tu prepíšeme predvolenú konfiguráciu zabezpečenia HTTP. Musíme to teda výslovne špecifikovať chceme, aby sa to chovalo ako zdrojový server a že budeme používať prístupové tokeny formátované JWT pomocou metód oauth2ResourceServer () a jwt ()resp.

Vyššie uvedená konfigurácia JWT je to, čo nám poskytuje predvolená inštancia Spring Boot. To je tiež možné prispôsobiť, ako sa čoskoro uvidíme.

4. Vlastné reklamácie v tokene

Poďme teraz nastaviť nejakú infraštruktúru, aby bolo možné pridať niekoľko vlastné deklarácie v prístupovom tokene vrátené autorizačným serverom. Štandardné nároky poskytované rámcom sú dobré a dobré, ale väčšinu času budeme potrebovať nejaké ďalšie informácie v tokene, aby sme ich mohli využiť na strane klienta.

Zoberme si príklad vlastného nároku, Organizácia, ktorý bude obsahovať názov organizácie daného používateľa.

4.1. Konfigurácia autorizačného servera

Za týmto účelom musíme do nášho definičného súboru ríše pridať niekoľko konfigurácií, baeldung-realm.json:

  • Pridajte atribút Organizácia nášmu používateľovi [chránené e-mailom]:
    "attributes": {"organization": "baeldung"},
  • Pridaj protocolMapper zavolal Organizácia do jwtClient konfigurácia:
    "protocolMappers": [{"id": "06e5fc8f-3553-4c75-aef4-5a4d7bb6c0d1", "name": "organization", "protocol": "openid-connect", "protocolMapper": "oidc-usermodel-attribute -mapper "," agreeRequired ": false," config ": {" userinfo.token.claim ":" true "," user.attribute ":" organizácia "," id.token.claim ":" true "," access.token.claim ":" true "," claim.name ":" organizácia "," jsonType.label ":" Reťazec "}}],

V prípade samostatného nastavenia služby Keycloak sa to dá urobiť aj pomocou administrátorskej konzoly.

Ďalej je dôležité si to uvedomiť vyššie uvedená konfigurácia JSON je špecifická pre Keycloak a pre iné servery OAuth sa môže líšiť.

S touto novou konfiguráciou, ktorá je v prevádzke, získame ďalší atribút organizácia = baeldung, v tokenu užitočného zaťaženia pre [chránené e-mailom]:

{jti: "989ce5b7-50b9-4cc6-bc71-8f04a639461e" exp: 1585242462 nbf: 0 iat: 1585242162 iss: "// localhost: 8083 / auth / realms / baeldung" sub: "a5461470-33eb-4b2d-82d4 -0d4 -0d4 -0d "typ:" Nositeľ "azp:" jwtClient "auth_time: 1585242162 session_state:" 384ca5cc-8342-429a-879c-c15329820006 "acr:" 1 "rozsah:" profil napísať na čítanie "organizácia:" baeldung "preferované_používateľské meno:" [chránený e-mailom ] "}

4.2. Použite prístupový token v uhlovom klientovi

Ďalej budeme chcieť využiť informácie o tokenoch v našej aplikácii Angular Client. Na to použijeme knižnicu angular2-jwt.

Využijeme Organizácia nárok v našom AppService, a pridať funkciu getOrganization:

getOrganization () {var token = Cookie.get ("access_token"); var užitočné zaťaženie = this.jwtHelper.decodeToken (token); this.organization = payload.organisation; vrátiť túto.organizáciu; }

Táto funkcia využíva JwtHelperService z angular2-jwt knižnica na dekódovanie prístupového tokenu a získanie nášho vlastného nároku. Všetko, čo musíme urobiť, je zobraziť to v našom AppComponent:

@Component ({selector: 'app-root', template: `Spring Security Oauth - Authorization Code 

{{Organizácia}}

`}) exportná trieda AppComponent implementuje OnInit {public organization =" "; konštruktor (súkromná služba: AppService) {} ngOnInit () {this.organization = this.service.getOrganization (); }}

5. Získajte prístup k mimoriadnym nárokom na zdrojovom serveri

Ako však môžeme k týmto informáciám získať prístup na strane servera so zdrojmi?

5.1. Prístup k nárokom na autentifikačný server

Je to naozaj jednoduché: musíme to urobiť extrahovať z org.springframework.security.oauth2.jwt.Jwt‘S AuthenticationPrincipal, ako by sme to urobili pre akýkoľvek iný atribút v UserInfoController:

@GetMapping ("/ user / info") public Map getUserInfo (@AuthenticationPrincipal Jwt principál) {Map map = new Hashtable (); map.put ("meno_uzivatela", principal.getClaimAsString ("preferovane_uzivatelske meno")); map.put ("organizácia", principal.getClaimAsString ("organizácia")); vrátiť Collections.unmodifiableMap (mapa); } 

5.2. Konfigurácia na pridanie / odstránenie / premenovanie nárokov

Čo teraz, ak chceme pridať ďalšie nároky na strane servera zdrojov? Alebo niektoré odstrániť alebo premenovať?

Povedzme, že chceme upraviť Organizácia nárok prichádzajúci z autentifikačného servera na získanie hodnoty veľkými písmenami. Okrem toho, ak nárok nie je k dispozícii používateľovi, musíme nastaviť jeho hodnotu ako neznámy.

Aby sme to dosiahli, najskôr budeme musieť pridať triedu, ktorá implementuje Prevádzač rozhranie a použitie MappedJwtClaimSetConverter previesť pohľadávky:

verejná trieda OrganizationSubClaimAdapter implementuje Converter {private final MappedJwtClaimSetConverter delegate = MappedJwtClaimSetConverter.withDefaults (Collections.emptyMap ()); public Map convert (Map claims) {Map convertedClaims = this.delegate.convert (claims); Reťazcová organizácia = převedenéClaims.get ("organizácia")! = Null? (String) convertedClaims.get ("organization"): "unknown"; convertClaims.put ("organization", organization.toUpperCase ()); návrat prevedenéClaims; }}

Po druhé, v našom SecurityConfig triedy, musíme pridať naše vlastné JwtDecoder inštancia prepísať tú, ktorú poskytuje Spring Boot a nastavili našu OrganizationSubClaimAdapter ako prevádzač jeho pohľadávok:

@Bean public JwtDecoder customDecoder (vlastnosti OAuth2ResourceServerProperties) {NimbusJwtDecoder jwtDecoder = NimbusJwtDecoder.withJwkSetUri (properties.getJwt (). GetJwkSetUri ()). Build (); jwtDecoder.setClaimSetConverter (nový OrganizationSubClaimAdapter ()); návrat jwtDecoder; } 

Teraz, keď sme narazili na našu / pouzivatel / info API pre používateľa [chránené e-mailom], dostaneme Organizácia ako NEZNÁMY.

Upozorňujeme, že prepísanie predvolenej hodnoty JwtDecoder bean nakonfigurovaný pomocou Spring Boot by ste mali robiť opatrne, aby ste sa uistili, že je stále zahrnutá všetka potrebná konfigurácia.

6. Načítanie kľúčov z úložiska kľúčov Java

V našej predchádzajúcej konfigurácii sme na overenie integrity nášho tokenu použili predvolený verejný kľúč autorizačného servera.

Na podpisovanie môžeme tiež použiť pár kľúčov a certifikát uložený v súbore Java Keystore.

6.1. Vytvorte súbor JKS Java KeyStore

Najprv vygenerujme kľúče - a konkrétnejšie a .jks súbor - pomocou nástroja príkazového riadku keytool:

keytool -genkeypair -alias mytest -keyalg RSA -keypass mypass -keystore mytest.jks -storepass mypass

Príkaz vygeneruje súbor s názvom mytest.jks ktorý obsahuje naše kľúče - verejný a súkromný kľúč.

Tiež sa uistite keypass a skladový pas sú rovnaké.

6.2. Exportovať verejný kľúč

Ďalej musíme exportovať náš verejný kľúč z vygenerovaného JKS, môžeme na to použiť nasledujúci príkaz:

keytool -list -rfc --keystore mytest.jks | openssl x509 -informačný pem -pubkey

Ukážka odpovede bude vyzerať takto:

----- BEGIN PUBLIC KEY ----- MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAgIK2Wt4x2EtDl41C7vfp OsMquZMyOyteO2RsVeMLF / hXIeYvicKr0SQzVkodHEBCMiGXQDz5prijTq3RHPy2 / 5WJBCYq7yHgTLvspMy6sivXN7NdYE7I5pXo / KHk4nz + Fa6P3L8 + L90E / 3qwf6j3 DKWnAgJFRY8AbSYXt1d5ELiIG1 / gEqzC0fZmNhhfrBtxwWXrlpUDT0Kfvf0QVmPR xxCLXT + tEe1seWGEqeOLL5vXRLqmzZcBe1RZ9kQQm43 + a9Qn5icSRnDfTAesQ3Cr lAWJKl2kcWU1HwJqw + dZRSZ1X4kEXNMyzPdPBbGmU6MHdhpywI7SKZT7mX4BDnUK eQIDAQAB ----- END PUBLIC KEY --- - ----- BEGIN OSVEDČENIE ----- MIIDCzCCAfOgAwIBAgIEGtZIUzANBgkqhkiG9w0BAQsFADA2MQswCQYDVQQGEwJ1 czELMAkGA1UECBMCY2ExCzAJBgNVBAcTAmxhMQ0wCwYDVQQDEwR0ZXN0MB4XDTE2 MDMxNTA4MTAzMFoXDTE2MDYxMzA4MTAzMFowNjELMAkGA1UEBhMCdXMxCzAJBgNV BAgTAmNhMQswCQYDVQQHEwJsYTENMAsGA1UEAxMEdGVzdDCCASIwDQYJKoZIhvcN AQEBBQADggEPADCCAQoCggEBAICCtlreMdhLQ5eNQu736TrDKrmTMjsrXjtkbFXj Cxf4VyHmL4nCq9EkM1ZKHRxAQjIhl0A8 + aa4o06t0Rz8tv + ViQQmKu8h4Ey77KTM urIr1zezXWBOyOaV6Pyh5OJ8 / hWuj9y / Pi / dBP96sH + o9wylpwICRUWPAG0mF7dX eRC4iBtf4BKswtH2ZjYYX6wbccFl65aVA09Cn739EFZj0ccQi10 / rRHtbHlhhKnj i y + b10S6ps2XAXtUWfZEEJuN / mvUJ + YnEkZw30wHrENwq5QFiSpdpHFlNR8CasPn WUUmdV + JBFzTMsz3TwWxplOjB3YacsCO0imU + 5l + AQ51CnkCAwEAAaMhMB8wHQYD VR0OBBYEFOGefUBGquEX9Ujak34PyRskHk + WMA0GCSqGSIb3DQEBCwUAA4IBAQB3 1eLfNeq45yO1cXNl0C1IQLknP2WXg89AHEbKkUOA1ZKTOizNYJIHW5MYJU / zScu0 yBobhTDe5hDTsATMa9sN5CPOaLJwzpWV / ZC6WyhAWTfljzZC6d2rL3QYrSIRxmsp / J1Vq9WkesQdShnEGy7GgRgJn4A8CKecHSzqyzXulQ7Zah6GoEUD + VJB + BheP4aN hiYY1OuXD + HsdKeQqS + 7eM5U7WW6dz2Q8mtFJ5qAxjY75T0pPrHwZMlJUhUZ + Q2V FfweJEaoNB9w9McPe1cAiE + oeejZ0jq0el3 / dJsx3rlVqZN + lMhRJJeVHFyeb3XF lLFCUGhA7hxn2xf3x1JW ----- END OSVEDČENIE -----

6.3. Konfigurácia Maven

Ďalej nechceme, aby bol súbor JKS zachytený procesom filtrovania maven - takže ho nezabudneme vylúčiť v pom.xml:

   src / main / resources true * .jks 

Ak používame Spring Boot, musíme sa ubezpečiť, že náš súbor JKS je pridaný do triedy aplikácií cez Spring Boot Maven Plugin - addResources:

   org.springframework.boot spring-boot-maven-plugin true 

6.4. Autorizačný server

Teraz nakonfigurujeme Keycloak tak, aby používal náš Keypair od mytest.jkspridaním do súboru JSON s definíciou sféry KeyProvider časť takto:

{"id": "59412b8d-aad8-4ab8-84ec-e546900fc124", "name": "java-keystore", "providerId": "java-keystore", "subComponents": {}, "config": {" keystorePassword ": [" mypass "]," keyAlias ​​": [" mytest "]," keyPassword ": [" mypass "]," active ": [" true "]," keystore ": [" src / main / resources /mytest.jks "]," priority ": [" 101 "]," enabled ": [" true "]," algoritmus ": [" RS256 "]}},

Tu sme nastavili prioritou do 101, väčší ako ktorýkoľvek iný Keypair pre náš autorizačný server, a nastavený aktívny do pravda. Toto sa deje preto, aby náš zdrojový server vybral tento konkrétny pár kľúčov z jwk-set-uri majetok, ktorý sme špecifikovali skôr.

Táto konfigurácia je opäť špecifická pre Keycloak a môže sa líšiť v prípade iných implementácií servera OAuth.

7. Záver

V tomto rýchlom článku sme sa zamerali na nastavenie nášho projektu Spring Security OAuth2 na používanie webových tokenov JSON.

Celú implementáciu tohto tutoriálu nájdete na viac ako na GitHub.


$config[zx-auto] not found$config[zx-overlay] not found