Een beknopte handleiding voor het gebruik van Cloud Foundry UAA

1. Overzicht

Cloud Foundry User Account and Authentication (CF UAA) is een service voor identiteitsbeheer en autorisatie. Om precies te zijn, het is een OAuth 2.0-provider die authenticatie en het uitgeven van tokens aan clienttoepassingen mogelijk maakt.

In deze tutorial behandelen we de basisprincipes van het opzetten van een CF UAA-server. We zullen dan bekijken hoe we het kunnen gebruiken om Resource Server-applicaties te beschermen.

Maar laten we eerst de rol van UAA in het OAuth 2.0-autorisatiekader verduidelijken.

2. Cloud Foundry UAA en OAuth 2.0

Laten we beginnen met te begrijpen hoe UAA zich verhoudt tot de OAuth 2.0-specificatie.

De OAuth 2.0-specificatie definieert vier deelnemers die met elkaar kunnen verbinden: een resource-eigenaar, een resource-server, een client en een autorisatieserver.

Als OAuth 2.0-provider speelt UAA de rol van de autorisatie server. Dit betekent het primaire doel is het uitgeven van toegangstokens voor cliënt applicaties en het valideren van deze tokens voor resource servers.

Om de interactie van deze deelnemers mogelijk te maken, moeten we eerst een UAA-server opzetten en vervolgens nog twee applicaties implementeren: de ene als een client en de andere als een bronserver.

We gebruiken de Authorisatie Code verlenen stroom met de klant. En we zullen Bearer-tokenautorisatie gebruiken met de bronserver. Voor een veiligere en efficiëntere handdruk gebruiken we ondertekende JWT's als onze toegangstokens.

3. Opzetten van een UAA-server

Eerste, we installeren UAA en vullen het met enkele demogegevens.

Na installatie registreren we een clienttoepassing met de naam webapp-client. Vervolgens maken we een gebruiker met de naam appuser met twee rollen, resource.read en resource.write.

3.1. Installatie

UAA is een Java-webtoepassing die kan worden uitgevoerd in elke compatibele servletcontainer. In deze tutorial gebruiken we Tomcat.

Laten we doorgaan en download de UAA-oorlog en deponeer deze in onze Tomcat inzet:

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. oorlog

Voordat we het opstarten, moeten we de gegevensbron en het JWS-sleutelpaar configureren.

3.2. Vereiste configuratie

Standaard leest UAA de configuratie uit uaa.yml op zijn klassenpad. Maar aangezien we zojuist het oorlog bestand, is het beter voor ons om UAA een aangepaste locatie op ons bestandssysteem te geven.

We kunnen dit doen door instellen van de UAA_CONFIG_PATH eigendom:

exporteer UAA_CONFIG_PATH = ~ / .uaa

Als alternatief kunnen we instellen CLOUD_FOUNDRY_CONFIG_PATH. Of we kunnen een externe locatie specificeren met UAA_CONFIG_URL.

Vervolgens kunnen we de vereiste configuratie van UAA naar ons configuratiepad kopiëren:

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

Merk op dat we de laatste drie regels verwijderen omdat we ze straks gaan vervangen.

3.3. De gegevensbron configureren

Laten we dus de gegevensbron configureren, waar UAA informatie over klanten gaat opslaan.

Voor deze tutorial gaan we HSQLDB gebruiken:

export SPRING_PROFILES = "standaard, hsqldb"

Omdat dit een Spring Boot-applicatie is, kunnen we dit natuurlijk ook specificeren in uaa.yml als de lente.profielen eigendom.

3.4. Het JWS-sleutelpaar configureren

Omdat we JWT gebruiken, UAA heeft een privésleutel nodig om elke JWT die UAA uitgeeft te ondertekenen.

OpenSSL maakt dit eenvoudig:

openssl genrsa -out signingkey.pem 2048 openssl rsa -in signingkey.pem -pubout -out verificatiekey.pem

De autorisatieserver zal teken de JWT met de privésleutel, en onze client en resource server zullen verifiëren die handtekening met de publieke sleutel.

We exporteren ze naar JWT_TOKEN_SIGNING_KEY en JWT_TOKEN_VERIFICATION_KEY:

export JWT_TOKEN_SIGNING_KEY = $ (kat signingkey.pem) export JWT_TOKEN_VERIFICATION_KEY = $ (kat verificatiekey.pem) 

Nogmaals, we zouden deze kunnen specificeren in uaa.yml via de jwt.token.signing-key en jwt.token.verification-key eigendommen.

3.5. UAA opstarten

Laten we tot slot beginnen:

$ CATALINA_HOME / bin / catalina.sh uitvoeren

Op dit punt zouden we een werkende UAA-server beschikbaar moeten hebben op // localhost: 8080 / uaa.

Als we naar // localhost: 8080 / uaa / info, dan zien we wat basis opstartinformatie

3.6. De UAA-opdrachtregelclient installeren

De CF UAA Command-Line Client is de belangrijkste tool voor het beheren van UAA, maar om het te gebruiken, moeten we Ruby eerst installeren:

sudo apt install rubygems gem install cf-uaac

Vervolgens kunnen we configureren uaac om te verwijzen naar ons actieve exemplaar van UAA:

uaac target // localhost: 8080 / uaa

Merk op dat als we de opdrachtregelclient niet willen gebruiken, we natuurlijk de HTTP-client van UAA kunnen gebruiken.

3.7. Cliënten en gebruikers vullen met UAAC

Nu dat we hebben uaac geïnstalleerd, laten we UAA vullen met enkele demogegevens. We hebben minimaal nodig: A cliënt, een gebruiker, en resource.read en resource.write groepen.

Dus om enige administratie te doen, moeten we onszelf authenticeren. We kiezen de standaardbeheerder die bij UAA wordt geleverd, die machtigingen heeft om andere clients, gebruikers en groepen te maken:

uaac token client krijgt admin -s adminsecret

(Natuurlijk, we moeten dit account beslist wijzigen - via het oauth-clients.xml-bestand - vóór verzending!)

In principe kunnen we dit commando lezen als: “Geef me een teken, gebruik makend van cliënt inloggegevens met de client_id van beheerder en een secret van admingeheim“.

Als alles goed gaat, zien we een succesbericht:

Token met succes opgehaald via toekenning van clientreferenties.

Het token is opgeslagen in uaac‘S staat.

Nu opererend als beheerder, kunnen we een klant met de naam registreren webappclient met klant toevoegen:

uaac client add webappclient -s webappclientsecret \ --name WebAppClient \ --scope resource.read, resource.write, openid, profiel, e-mail, adres, telefoon \ --authorized_grant_types autorisatiecode, refresh_token, client_credentials, wachtwoord \ --authorities uaa. resource \ --redirect_uri // localhost: 8081 / login / oauth2 / code / uaa

En we kunnen ook een gebruiker met de naam registreren appuser met gebruiker toevoegen:

uaac-gebruiker appuser toevoegen -p appusersecret --emails [e-mailbeveiliging]

Vervolgens voegen we twee groepen toe - resource.read en resource.write - gebruiken met groep toevoegen:

uaac-groep voeg resource.read toe uaac-groep voeg resource.write toe

En tot slot zullen we deze groepen toewijzen aan appuser met lid toevoegen:

uaac-lid voeg resource.read appuser toe uaac-lid voeg resource.write appuser

Opluchting! Dus wat we tot nu toe hebben gedaan, is:

  • UAA geïnstalleerd en geconfigureerd
  • Geïnstalleerd uaac
  • Een demo-client, gebruikers en groepen toegevoegd

Laten we dus deze stukjes informatie in gedachten houden en naar de volgende stap gaan.

4. OAuth 2.0-client

In deze sectie we gebruiken Spring Boot om een ​​OAuth 2.0 Client-applicatie te maken.

4.1. Applicatie-instellingen

Laten we beginnen met Spring Initializr te openen en een Spring Boot-webtoepassing te genereren. We kiezen alleen de Web en OAuth2-client componenten:

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

In dit voorbeeld hebben we versie 2.1.3 van Spring Boot gebruikt.

De volgende, we moeten onze klant registreren, web applicatiecliënt.

Heel eenvoudig, we moeten de app de klant identificatie, cliëntgeheim, en UAA's uitgever-uri. We specificeren ook de OAuth 2.0-bereiken die deze client wil dat de gebruiker eraan toekent:

#registratie 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, profiel #provider spring.security.oauth2.client.provider.uaa.issuer-uri = // localhost: 8080 / uaa / oauth / token

Voor meer informatie over deze eigenschappen kunnen we de Java-documenten voor de registratie- en providerbeans bekijken.

En aangezien we poort 8080 al gebruiken voor UAA, laten we dit uitvoeren op 8081:

server.port = 8081

4.2. Log in

Als we nu toegang hebben tot het /Log in pad, we zouden een lijst moeten hebben van alle geregistreerde klanten. In ons geval hebben we maar één geregistreerde klant:

Als u op de link klikt, worden we doorgestuurd naar de UAA-inlogpagina:

Hier, laten we inloggen met appuser / appusersecret.

Het indienen van het formulier moet ons doorverwijzen naar een goedkeuringsformulier waar de gebruiker de toegang aan onze klant kan autoriseren of weigeren:

De gebruiker kan vervolgens de rechten verlenen die ze wil. Voor onze doeleinden, we zullen alles selecteren behalve bron: schrijven.

Wat de gebruiker ook controleert, het zijn de bereiken in het resulterende toegangstoken.

Om dit te bewijzen, kunnen we het token kopiëren dat wordt weergegeven op het indexpad, // localhost: 8081, en decodeer het met behulp van de JWT-debugger. We zouden de bereiken moeten zien die we hebben gecontroleerd op de goedkeuringspagina:

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

Zodra onze clienttoepassing dit token heeft ontvangen, kan deze de gebruiker verifiëren en hebben ze toegang tot de app.

Nu, een app die geen gegevens laat zien, is niet erg nuttig, dus onze volgende stap is het opzetten van een resourceserver - die de gegevens van de gebruiker bevat - en de client ermee verbinden.

De voltooide bronserver heeft twee beveiligde API's: een waarvoor de resource.read reikwijdte en een andere die vereist resource.write.

Wat we zullen zien is dat de klant kan, met behulp van de door ons toegekende scopes, het lezen API maar niet schrijven.

5. Bronserver

De bronserver host de beschermde bronnen van de gebruiker.

Het authenticeert clients via het Autorisatie header en in overleg met een autorisatieserver - in ons geval is dat UAA.

5.1. Applicatie instellen

Om onze resource-server te maken, gebruiken we Spring Initializr opnieuw om een ​​Spring Boot-webtoepassing te genereren. Deze keer kiezen we voor de Web en OAuth2-bronserver componenten:

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

Net als bij de Client-applicatie gebruiken we versie 2.1.3 van Spring Boot.

De volgende stap is het aangeven van de locatie van de actieve CF UAA in het application.properties het dossier:

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

Laten we hier natuurlijk ook een nieuwe poort uitkiezen. 8082 werkt prima:

server.port = 8082

En dat is het! We zouden een werkende bronserver moeten hebben en standaard hebben alle verzoeken een geldig toegangstoken in het Autorisatie koptekst.

5.2. Bescherming van Resource Server-API's

Laten we vervolgens enkele eindpunten toevoegen die de moeite waard zijn om te beschermen.

We voegen een RestController met twee eindpunten, één geautoriseerd voor gebruikers met de resource.read scope en de andere voor gebruikers met de resource.write bereik:

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

De volgende, we overschrijven de standaard Spring Boot-configuratie om de twee bronnen te beschermen:

@EnableWebSecurity openbare klasse OAuth2ResourceServerSecurityConfiguration breidt WebSecurityConfigurerAdapter uit {@Override protected void configure (HttpSecurity http) gooit uitzondering {http.authorizeRequests () .antMatchers ("/ read / **"). HasAuthority (".readers "). write / ** "). hasAuthority (" SCOPE_resource.write ") .anyRequest (). geverifieerd () .and () .oauth2ResourceServer (). jwt (); }}

Merk op dat de scopes die in het toegangstoken worden geleverd, worden voorafgegaan door TOEPASSINGSGEBIED_ wanneer ze worden vertaald naar een Spring Security ToegegevenAuthority.

5.3. Een beschermde bron aanvragen bij een klant

Vanuit de clienttoepassing bellen we de twee beschermde bronnen met RestTemplate. Voordat we het verzoek doen, halen we het toegangstoken op uit de context en voegen we het toe aan het Autorisatie koptekst:

private String callResourceServer (OAuth2AuthenticationToken authenticationToken, String url) {OAuth2AuthorizedClient oAuth2AuthorizedClient = this.authorizedClientService. loadAuthorizedClient (authenticationToken.getAuthorizedClientRegistrationId (), authenticationToken.getName ()); OAuth2AccessToken oAuth2AccessToken = oAuth2AuthorizedClient.getAccessToken (); HttpHeaders headers = nieuwe HttpHeaders (); headers.add ("Autorisatie", "Bearer" + oAuth2AccessToken.getTokenValue ()); // call resource endpoint return response; }

Merk echter op dat we deze boilerplate kunnen verwijderen als we Web cliënt in plaats van RestTemplate.

Vervolgens voegen we twee aanroepen toe aan de eindpunten van de resourceserver:

@GetMapping ("/ read") public String read (OAuth2AuthenticationToken authenticationToken) {String url = remoteResourceServer + "/ read"; return callResourceServer (authenticationToken, url); } @GetMapping ("/ write") public String write (OAuth2AuthenticationToken authenticationToken) {String url = remoteResourceServer + "/ write"; return callResourceServer (authenticationToken, url); }

Zoals verwacht, de oproep van de /lezen API zal slagen, maar niet de /schrijven een. De HTTP-status 403 vertelt ons dat de gebruiker niet geautoriseerd is.

6. Conclusie

In dit artikel zijn we begonnen met een kort overzicht van OAuth 2.0, aangezien dit de basis is voor UAA, een OAuth 2.0-autorisatieserver. Vervolgens hebben we het geconfigureerd voor het uitgeven van toegangstokens voor een client en het beveiligen van een resource servertoepassing.

De volledige broncode voor de voorbeelden is beschikbaar op Github.


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