Kratki vodič za korištenje UAA za lijevanje u oblaku

1. Pregled

Korisnički račun i provjera autentičnosti Cloud Foundry (CF UAA) usluga je upravljanja identitetom i autorizacije. Točnije, radi se o OAuth 2.0 pružatelju koji omogućuje provjeru autentičnosti i izdavanje tokena klijentskim aplikacijama.

U ovom uputstvu pokriti ćemo osnove postavljanja poslužitelja CF UAA. Zatim ćemo pogledati kako ga koristiti za zaštitu aplikacija poslužitelja resursa.

No prije pojasnimo ulogu UAA-e u OAuth 2.0 autorizacijskom okviru.

2. UAO u ljevaonici oblaka i OAuth 2.0

Počnimo s razumijevanjem kako se UAA odnosi na specifikaciju OAuth 2.0.

Specifikacija OAuth 2.0 definira četiri sudionika koji se mogu međusobno povezati: vlasnik resursa, poslužitelj resursa, klijent i poslužitelj za autorizaciju.

Kao pružatelj OAuth 2.0, UAA igra ulogu autorizacijski poslužitelj. To znači njegov je primarni cilj izdavanje pristupnih tokena za klijent aplikacija i provjera valjanosti ovih tokena za resursni poslužiteljs.

Da bismo omogućili interakciju ovih sudionika, prvo moramo postaviti UAA poslužitelj, a zatim implementirati još dvije aplikacije: jednu kao klijenta, a drugu kao poslužitelja resursa.

Koristit ćemo autorizacijski_kod tijek odobrenja s klijentom. I koristit ćemo autorizaciju Bearer tokena s poslužiteljem resursa. Za sigurnije i učinkovitije rukovanje koristit ćemo potpisane JWT-ove kao svoje pristupne tokene.

3. Postavljanje UAA poslužitelja

Prvi, instalirat ćemo UAA i popuniti ga nekim demo podacima.

Jednom instalirani, registrirat ćemo klijentsku aplikaciju s imenom webappclient. Zatim ćemo stvoriti korisnika s imenom appuser s dvije uloge, resurs.čitati i resurs.pisati.

3.1. Montaža

UAA je web aplikacija Java koja se može pokrenuti u bilo kojem usklađenom spremniku servleta. U ovom uputstvu koristit ćemo Tomcat.

Idemo naprijed i preuzmi UAA rat i položi ga u naš Tomcat raspoređivanje:

wget -O $ CATALINA_HOME / webapps / uaa.war \ //search.maven.org/remotecontent?filepath=org/cloudfoundry/identity/cloudfoundry-identity-uaa/4.27.0/cloudfoundry-identity-uaa-4.27.0. rat

Prije nego što ga pokrenemo, morat ćemo konfigurirati njegov izvor podataka i par ključeva JWS.

3.2. Potrebna konfiguracija

Prema zadanim postavkama UAA čita konfiguraciju iz uaa.yml na svojoj stazi. Ali, budući da smo upravo preuzeli rat datoteku, bit će nam bolje da UAA kažemo prilagođeno mjesto u našem datotečnom sustavu.

To možemo učiniti do postavljanje UAA_CONFIG_PATH svojstvo:

izvoz UAA_CONFIG_PATH = ~ / .uaa

Alternativno, možemo postaviti CLOUD_FOUNDRY_CONFIG_PATH. Ili možemo odrediti udaljeno mjesto pomoću UAA_CONFIG_URL.

Zatim možemo kopirati potrebnu konfiguraciju UAA u našu konfiguracijsku stazu:

wget -qO- //raw.githubusercontent.com/cloudfoundry/uaa/4.27.0/uaa/src/main/resources/required_configuration.yml \> $ UAA_CONFIG_PATH / uaa.yml

Imajte na umu da brišemo posljednja tri retka jer ćemo ih začas zamijeniti.

3.3. Konfiguriranje izvora podataka

Pa, konfigurirajmo izvor podataka, gdje će UAA pohranjivati ​​podatke o klijentima.

U svrhu ovog vodiča koristit ćemo HSQLDB:

izvoz SPRING_PROFILES = "zadano, hsqldb"

Naravno, budući da je ovo aplikacija Spring Boot, to bismo mogli specificirati i u uaa.yml kao opruga.profili imovine.

3.4. Konfiguriranje JWS ključnog para

Budući da koristimo JWT, UAA mora imati privatni ključ za potpisivanje svakog JWT-a koji UAA izdaje.

OpenSSL čini ovo jednostavno:

openssl genrsa -out signkey.pem 2048 openssl rsa -in signkey.pem -pubout -out verifykey.pem

Autorizacijski poslužitelj će znak JWT s privatnim ključem, a hoće i naš klijent i poslužitelj resursa provjeriti taj potpis s javnim ključem.

Izvest ćemo ih u JWT_TOKEN_SIGNING_KEY i JWT_TOKEN_VERIFICATION_KEY:

izvoz JWT_TOKEN_SIGNING_KEY = $ (mačka signkey.pem) izvoz JWT_TOKEN_VERIFICATION_KEY = $ (mačka verifykey.pem) 

Opet bismo ih mogli specificirati u uaa.yml putem jwt.token.signing-key i jwt.token.provjera-ključ Svojstva.

3.5. Pokretanje UAA

Napokon, pokrenimo stvari:

$ CATALINA_HOME / bin / catalina.sh trčanje

U ovom trenutku trebali bismo imati na raspolaganju poslužitelj UAA poslužitelja // localhost: 8080 / uaa.

Ako odemo u // localhost: 8080 / uaa / info, tada ćemo vidjeti neke osnovne informacije o pokretanju

3.6. Instaliranje klijenta UAA naredbenog retka

Klijent naredbenog retka CF UAA glavni je alat za upravljanje UAA, ali da bismo je koristili, prvo moramo instalirati Ruby:

sudo apt install rubygems gem install cf-uaac

Tada možemo konfigurirati uaac ukazati na našu tekuću instancu UAA:

cilj uaac // localhost: 8080 / uaa

Imajte na umu da ako ne želimo koristiti klijent naredbenog retka, možemo, naravno, koristiti UAA-ov HTTP klijent.

3.7. Stanovništvo klijenata i korisnika koji koriste UAAC

Sad kad jesmo uaac instalirano, popunimo UAA nekim demo podacima. Trebat će nam najmanje: A klijent, a korisnik, i resurs.čitati i resurs.pisati skupine.

Dakle, za bilo kakvu administraciju trebat ćemo se provjeriti autentičnost. Odabrat ćemo zadanog administratora koji se isporučuje s UAA, koja ima dozvole za stvaranje drugih klijenata, korisnika i grupa:

uaac token client dobiva admin-s adminsecret

(Naravno, definitivno moramo promijeniti ovaj račun - putem datoteke oauth-clients.xml - prije slanja!)

U osnovi ovu naredbu možemo pročitati kao: „Daj mi znak, koristeći klijent vjerodajnice s client_id od admin i a stajna od tajna administratora“.

Ako sve bude u redu, vidjet ćemo poruku o uspjehu:

Uspješno dohvaćen token putem dodjele vjerodajnica klijenta.

Token je pohranjen u uaac'S država.

Sada, djelujući kao admin, možemo registrirati klijenta s imenom webappclient s klijent dodaj:

uaac klijent dodaj webappclient -s webappclientsecret \ --name WebAppClient \ --scope resource.read, resource.write, openid, profil, e-mail, adresa, telefon \ --authorized_grant_types auth_code, refresh_token, client_credentials, password \ --authorities uaa. resurs \ --redirect_uri // localhost: 8081 / login / oauth2 / code / uaa

Također, možemo registrirati korisnika s imenom appuser s korisnik dodaj:

uaac korisnik dodaj appuser -p appusersecret --emails [e-mail zaštićen]

Zatim ćemo dodati dvije grupe - resurs.čitati i resurs.pisati - koristeći sa dodaj u grupu:

uaac grupa dodati resurs.čitati uaac grupa dodati resurs.write

I na kraju, dodijelit ćemo ove grupe appuser s član dodaj:

član uaac dodati resursa.čitati appuser član uaac dodati resource.write appuser

Fuj! Dakle, ono što smo do sada učinili je:

  • Instaliran i konfiguriran UAA
  • Instalirano uaac
  • Dodan je demo klijent, korisnici i grupe

Dakle, imajmo na umu ove podatke i prijeđimo na sljedeći korak.

4. OAuth 2.0 klijent

U ovom odjeljku, koristit ćemo Spring Boot za stvaranje OAuth 2.0 klijentske aplikacije.

4.1. Postavljanje programa

Počnimo s pristupom Spring Initializr i generiranjem web aplikacije Spring Boot. Mi biramo samo mreža i OAuth2 klijent komponente:

 org.springframework.boot spring-boot-starter-web org.springframework.boot spring-boot-starter-oauth2-client 

U ovom smo primjeru koristili verziju 2.1.3 Spring Boot-a.

Sljedeći, moramo registrirati svog klijenta, webappklijent.

Jednostavno, aplikaciji ćemo trebati dati ID klijenta, klijent-tajno, i UAA izdavatelj-uri. Također ćemo odrediti opsege OAuth 2.0 koje ovaj klijent želi da mu korisnik odobri:

#registration spring.security.oauth2.client.registration.uaa.client-id = webappclient spring.security.oauth2.client.registration.uaa.client-secret = webappclientsecret spring.security.oauth2.client.registration.uaa.scope = resource.read, resource.write, openid, profile #provider spring.security.oauth2.client.provider.uaa.issuer-uri = // localhost: 8080 / uaa / oauth / token

Za više informacija o ovim svojstvima možemo pogledati Java dokumente za registraciju i grah dobavljača.

A budući da već koristimo port 8080 za UAA, pokrenimo ovo na 8081:

poslužitelj.port = 8081

4.2. Prijaviti se

Sad ako pristupimo /prijaviti se puta, trebali bismo imati popis svih registriranih klijenata. U našem slučaju imamo samo jednog registriranog klijenta:

Klik na vezu preusmjerit će nas na stranicu za prijavu UAA:

Evo, prijavimo se s appuser / appusersecret.

Slanje obrasca trebalo bi nas preusmjeriti na obrazac za odobrenje gdje korisnik može odobriti ili uskratiti pristup našem klijentu:

Korisnik tada može dodijeliti koje privilegije želi. U naše svrhe, sve ćemo odabrati osim resursa: piši.

Sve što korisnik provjeri bit će opsezi u rezultirajućem tokenu pristupa.

Da bismo to dokazali, možemo kopirati token prikazan na putu indeksa, // localhost: 8081i dekodirajte ga pomoću JWT ispravljača. Opsege koje smo provjerili trebali bismo vidjeti na stranici za odobrenje:

{"jti": "f228d8d7486942089ff7b892c796d3ac", "sub": "0e6101d8-d14b-49c5-8c33-fc12d8d1cc7d", "scope": ["resource.read", "openid", "profile"], "client_id", "client_id" webappclient "// više zahtjeva}

Kad naša klijentska aplikacija primi ovaj token, može provjeriti autentičnost korisnika i imat će pristup aplikaciji.

Sada, aplikacija koja ne prikazuje nikakve podatke nije baš korisna, pa će naš sljedeći korak biti uspostavljanje poslužitelja resursa - koji ima korisničke podatke - i na njega povežite klijenta.

Završeni poslužitelj resursa imat će dva zaštićena API-ja: jedan koji zahtijeva resurs.čitati opseg i još jedan koji zahtijeva resurs.pisati.

Ono što ćemo vidjeti je to klijent će, koristeći opsege koje smo mu odobrili, moći nazvati čitati API, ali ne pisati.

5. Poslužitelj resursa

Poslužitelj resursa hostira zaštićene resurse korisnika.

Ovjerava klijente putem Ovlaštenje zaglavlje i uz konzultacije s autorizacijskim poslužiteljem - u našem slučaju to je UAA.

5.1. Postavljanje aplikacije

Da bismo stvorili naš poslužitelj resursa, ponovno ćemo upotrijebiti Spring Initializr za generiranje web aplikacije Spring Boot. Ovaj put ćemo odabrati mreža i OAuth2 Resursni poslužitelj komponente:

 org.springframework.boot spring-boot-starter-oauth2-resource-server org.springframework.boot spring-boot-starter-web 

Kao i kod klijentske aplikacije, koristimo verziju 2.1.3 Spring Boot-a.

Sljedeći je korak naznačiti mjesto tekućeg CF UAA u primjena.svojstva datoteka:

spring.security.oauth2.resourceserver.jwt.issuer-uri = // localhost: 8080 / uaa / oauth / token

Naravno, odaberimo i novu luku ovdje. 8082 će dobro raditi:

poslužitelj.port = 8082

I to je to! Trebali bismo imati radni poslužitelj resursa i prema zadanim postavkama svi zahtjevi zahtijevat će valjani pristupni token u Ovlaštenje Zaglavlje.

5.2. Zaštita API-ja poslužitelja resursa

Dalje, dodamo ipak neke krajnje točke koje vrijedi zaštititi.

Mi ćemo dodati a RestController s dvije krajnje točke, jedna ovlaštena za korisnike koji imaju resurs.čitati opseg, a drugi za korisnike koji imaju opseg resursa.write:

@GetMapping ("/ read") public String read (Principal principal) {return "Hello write:" + principal.getName (); } @GetMapping ("/ write") public String write (Principal principal) {return "Hello write:" + principal.getName (); }

Sljedeći, zamijenit ćemo zadanu konfiguraciju Spring Boot kako bi zaštitili dva resursa:

@EnableWebSecurity javna klasa OAuth2ResourceServerSecurityConfiguration proširuje WebSecurityConfigurerAdapter {@Override zaštićena void konfiguracija (HttpSecurity http) baca izuzetak {http.authorizeRequests () .antMatchers ("/ read / **"). write / ** "). hasAuthority (" SCOPE_resource.write ") .anyRequest (). authenticated () .and () .oauth2ResourceServer (). jwt (); }}

Imajte na umu da su opsezi isporučeni u pristupnom tokenu s prefiksom OPSEG_ kad se prevedu u proljetni osiguranik OdobrenoAutority.

5.3. Traženje zaštićenog resursa od klijenta

Iz klijentske aplikacije nazvat ćemo dva zaštićena resursa pomoću RestTemplate. Prije podnošenja zahtjeva, pristupni token dohvaćamo iz konteksta i dodajemo ga u Ovlaštenje Zaglavlje:

private String callResourceServer (OAuth2AuthenticationToken authenticationToken, String url) {OAuth2AuthorizedClient oAuth2AuthorizedClient = this.authorizedClientService. loadAuthorizedClient (authenticationToken.getAuthorizedClientRegistrationId (), authenticationToken.getName ()); OAuth2AccessToken oAuth2AccessToken = oAuth2AuthorizedClient.getAccessToken (); HttpHeaders zaglavlja = novi HttpHeaders (); headers.add ("Autorizacija", "Donositelj" + oAuth2AccessToken.getTokenValue ()); // odgovor na povrat krajnje točke resursa; }

Ipak, imajte na umu da možemo ukloniti ovaj okvir ako ga koristimo WebClient umjesto RestTemplate.

Zatim ćemo dodati dva poziva krajnjim točkama poslužitelja resursa:

@GetMapping ("/ read") javni niz čitanja (OAuth2AuthenticationToken authenticationToken) {URL niza = remoteResourceServer + "/ read"; povratni callResourceServer (authenticationToken, url); } @GetMapping ("/ write") javni zapis niza (OAuth2AuthenticationToken authenticationToken) {URL niza = remoteResourceServer + "/ write"; povratni callResourceServer (authenticationToken, url); }

Očekivano, poziv /čitati API će uspjeti, ali ne i /pisati jedan. HTTP status 403 govori nam da korisnik nije ovlašten.

6. Zaključak

U ovom smo članku započeli kratki pregled OAuth 2.0 jer je temelj za UAA, OAuth 2.0 Autorizacijski poslužitelj. Zatim smo ga konfigurirali za izdavanje pristupnih tokena za klijenta i zaštitu aplikacije poslužitelja resursa.

Potpuni izvorni kod za primjere dostupan je na Githubu.