OAuth2.0 en dynamische clientregistratie (met behulp van de Spring Security OAuth legacy-stack)

1. Inleiding

In deze tutorial gaan we een dynamische clientregistratie voorbereiden met de OAuth2.0. De OAuth2.0 is een autorisatieframework dat het mogelijk maakt om beperkte toegang te krijgen tot gebruikersaccounts op een HTTP-service. De OAuth2.0-client is de applicatie die toegang wil tot het gebruikersaccount. Deze client kan een externe webapplicatie, een user-agent of gewoon een native client zijn.

Om een ​​dynamische clientregistratie te bereiken, gaan we de referenties opslaan in de database, in plaats van in een hardcoded configuratie. De applicatie die we gaan uitbreiden, werd aanvankelijk beschreven in de Spring REST API + OAuth2-zelfstudie.

Opmerking: dit artikel maakt gebruik van het verouderde Spring OAuth-project.

2. Maven afhankelijkheden

We zullen eerst de volgende reeks afhankelijkheden instellen:

 org.springframework.boot spring-boot-starter-web org.springframework spring-jdbc org.springframework.security.oauth spring-security-oauth2 

Merk op dat we spring-jdbc omdat we een database gaan gebruiken om de nieuw geregistreerde gebruikers met wachtwoorden op te slaan.

3. OAuth2.0-serverconfiguratie

Eerst moeten we onze OAuth2.0-autorisatieserver configureren. De hoofdconfiguratie bevindt zich in de volgende klasse:

@Configuration @PropertySource ({"classpath: persistence.properties"}) @EnableAuthorizationServer public class OAuth2AuthorizationServerConfig breidt AuthorizationServerConfigurerAdapter {// config} uit

Er zijn een paar belangrijke dingen die we moeten configureren; laten we beginnen met ClientDetailsServiceConfigurer:

@Override public void configure (laatste ClientDetailsServiceConfigurer-clients) genereert uitzondering {clients.jdbc (dataSource ()) // ...}

Dit zorgt ervoor dat we persistentie gebruiken om de klantinformatie van te halen.

Laten we natuurlijk deze standaard gegevensbron opzetten:

@Bean openbare DataSource dataSource () {DriverManagerDataSource dataSource = nieuwe DriverManagerDataSource (); dataSource.setDriverClassName (env.getProperty ("jdbc.driverClassName")); dataSource.setUrl (env.getProperty ("jdbc.url")); dataSource.setUsername (env.getProperty ("jdbc.user")); dataSource.setPassword (env.getProperty ("jdbc.pass")); retourneer dataSource; }

En dus zal onze applicatie nu de database gebruiken als een bron van geregistreerde clients, in plaats van de typische hardgecodeerde geheugenclients.

4. De DB-regeling

Laten we nu de SQL-structuur definiëren voor het opslaan van onze OAuth-clients:

tabel maken oauth_client_details (client_id VARCHAR (256) PRIMAIRE SLEUTEL, resource_ids VARCHAR (256), client_secret VARCHAR (256), bereik VARCHAR (256), geautoriseerde_grant_types VARCHAR (256), web_server_redirect_grijper VARCHAR (256), autoriteiten VARCHAR (256), autoriteiten VARCHAR (256), autoriteiten VARCHAR (256) , refreshtoken_validity INTEGER, aanvullende_informatie VARCHAR (4096), autoapprove VARCHAR (256));

De belangrijkste velden uit de oauth_client_details waar we ons op moeten concentreren zijn:

  • klant identificatie - om de id van nieuw geregistreerde klanten op te slaan
  • client_secret - om het wachtwoord van klanten op te slaan
  • access_token_validity - wat aangeeft of de cliënt nog geldig is
  • autoriteiten - om aan te geven welke rollen zijn toegestaan ​​bij een bepaalde klant
  • reikwijdte - toegestane acties, bijvoorbeeld het schrijven van statussen op Facebook etc.
  • geautoriseerde_grant_types, die informatie geeft hoe gebruikers kunnen inloggen op de specifieke client (in ons voorbeeld is het een formulier login met wachtwoord)

Houd er rekening mee dat elke klant een een-tot-veel-relatie heeft met gebruikers, wat dat natuurlijk betekent meerdere gebruikers kunnen een enkele client gebruiken.

5. Laten we enkele klanten volhouden

Met SQL-schema definiëren, kunnen we eindelijk enkele gegevens in het systeem creëren - en in feite een client definiëren.

We gaan het volgende gebruiken data.sql script - dat Spring Boot standaard zal draaien - om de database te initialiseren:

VOEG IN oauth_client_details (client_id, client_secret, scope, geautoriseerde_grant_types, web_server_redirect_uri, autoriteiten, access_token_validity, refresh_token_validity, aanvullende_informatie, autoapprove) VALUES ("fooClientIdPassword", "secret", " , null, 36000, 36000, null, true);

De beschrijving van de belangrijkste velden in oauth_client_details staat in de vorige sectie.

6. Testen

Om de dynamische clientregistratie te testen, moeten we beide uitvoeren spring-security-oauth-server en spring-security-oauth-resource projecten, op respectievelijk de 8081- en 8082-poorten.

Nu kunnen we eindelijk een paar live tests schrijven.

Laten we aannemen dat we de klant hebben geregistreerd met de naam id fooClientIdPassword, dat toegang heeft tot het lezen van foos.

Eerst proberen we een toegangstoken van de Auth-server te verkrijgen, met behulp van een reeds gedefinieerde client:

@Test openbare ongeldig gegevenDBUser_whenRevokeToken_thenAuthorized () {String accessToken = getAccessToken ("fooClientIdPassword", "john", "123"); assertNotNull (accessToken); }

En hier is de logica van het verkrijgen van het toegangstoken:

private String gainAccessToken (String clientId, String gebruikersnaam, String wachtwoord) {Map params = new HashMap (); params.put ("grant_type", "wachtwoord"); params.put ("client_id", clientId); params.put ("gebruikersnaam", gebruikersnaam); params.put ("wachtwoord", wachtwoord); Antwoordantwoord = RestAssured.given (). Auth (). Preemptive () .basic (clientId, "secret"). En (). Met (). Params (params) .when () .post ("// localhost: 8081 / spring-security-oauth-server / oauth / token "); return response.jsonPath (). getString ("access_token"); }

7. Conclusie

In deze zelfstudie hebben we geleerd hoe we dynamisch een onbeperkt aantal clients kunnen registreren met het OAuth2.0-framework.

De volledige implementatie van deze tutorial is te vinden op GitHub - dit is een op Maven gebaseerd project, dus het moet gemakkelijk te importeren en uit te voeren zijn zoals het is.

Houd er rekening mee dat u om te testen clients moet toevoegen aan DB en dat het .inMemory () config zal niet langer geldig zijn. Als je het oude wilt gebruiken.inMemory () config, is er een tweede bestand met configuratie met hardgecodeerde clients.