Spring Security 5 - OAuth2 Login

1. Prehľad

Jarná bezpečnosť 5 predstavuje nový OAuth2LoginConfigurer triedy, ktorú môžeme použiť na konfiguráciu externého autorizačného servera.

V tomto článku preskúmame niektoré z rôznych možností konfigurácie dostupných pre oauth2Login () element.

2. Maven závislosti

V projekte Spring Boot stačí pridať štartér spring-boot-starter-oauth2-client:

 org.springframework.boot spring-boot-starter-oauth2-client 2.3.3.RELEASE 

V projekte, ktorý nie je spustený, musíme okrem štandardných závislostí Spring a Spring Security tiež výslovne pridať znak spring-security-oauth2-client a spring-security-oauth2-jose závislosti:

 org.springframework.security spring-security-oauth2-client 5.3.4.RELEASE org.springframework.security spring-security-oauth2-jose 5.3.4.RELEASE 

3. Nastavenie klientov

V projekte Spring Boot všetko, čo musíme urobiť, je pridať niekoľko štandardných vlastností pre každého klienta, ktorého chceme nakonfigurovať.

Poďme nastaviť náš projekt na prihlásenie s klientmi registrovanými v Google a Facebook ako poskytovatelia autentifikácie.

3.1. Získanie poverení klienta

Ak chcete získať poverenia klienta pre autentifikáciu Google OAuth2, choďte ďalej do konzoly Google API Console - časť „Poverenia“.

Tu vytvoríme poverenia typu „ID klienta OAuth2“ pre našu webovú aplikáciu. Výsledkom je, že Google pre nás nastaví ID a tajomstvo klienta.

Musíme tiež nakonfigurovať autorizovaný identifikátor URI presmerovania v konzole Google, čo je cesta, na ktorú budú používatelia presmerovaní po úspešnom prihlásení pomocou účtu Google.

Spring Boot predvolene konfiguruje tento identifikátor URI presmerovania ako / login / oauth2 / code / {registrationId}. Preto pre Google pridáme URI:

// localhost: 8081 / login / oauth2 / code / google

Ak chcete získať poverenia klienta na autentifikáciu pomocou Facebooku, musíme si zaregistrovať aplikáciu na webe Facebook for Developers a nastaviť zodpovedajúci URI ako „Platný URI presmerovania OAuth“:

// localhost: 8081 / login / oauth2 / code / facebook

3.3. Konfigurácia zabezpečenia

Ďalej musíme pridať poverenia klienta do servera application.properties spis. Vo vlastnostiach Spring Security je predpona „Spring.security.oauth2.client.registration“ za ktorým nasleduje meno klienta, potom názov vlastnosti klienta:

spring.security.oauth2.client.registration.google.client-id = spring.security.oauth2.client.registration.google.client-secret = spring.security.oauth2.client.registration.facebook.client-id = jar. security.oauth2.client.registration.facebook.client-secret =

Pridaním týchto vlastností aspoň k jednému klientovi povolíte Oauth2ClientAutoConfiguration trieda čím sa nastavia všetky potrebné fazule.

Automatická konfigurácia zabezpečenia webu je ekvivalentná definovaniu jednoduchého oauth2Login () element:

@Configuration verejná trieda SecurityConfig rozširuje WebSecurityConfigurerAdapter {@Override chránená neplatná konfigurácia (HttpSecurity http) vyvolá výnimku {http.authorizeRequests () .anyRequest (). }}

Tu vidíme oauth2Login () prvok sa používa podobným spôsobom, aký je už známy httpBasic () a formLogin () prvkov.

Teraz, keď sa pokúsime získať prístup k chránenej adrese URL, aplikácia zobrazí automaticky generovanú prihlasovaciu stránku s dvoma klientmi:

3.4. Ostatní klienti

Upozorňujeme, že okrem služieb Google a Facebook obsahuje projekt Spring Security aj predvolené konfigurácie pre GitHub a Okta. Tieto predvolené konfigurácie poskytujú všetky potrebné informácie na overenie, čo nám umožňuje zadávať iba poverenia klienta.

Ak chceme použiť iného poskytovateľa autentifikácie, ktorý nie je nakonfigurovaný v Spring Security, budeme musieť definovať úplnú konfiguráciu s informáciami ako URI autorizácie a URI tokenu. Tu je pohľad na predvolené konfigurácie v Spring Security, aby ste získali predstavu o potrebných vlastnostiach.

4. Nastavenie v projekte bez spustenia

4.1. Vytvorenie a ClientRegistrationRepository Bean

Ak nepracujeme s aplikáciou Spring Boot, budeme musieť definovať a ClientRegistrationRepository fazuľa ktorý obsahuje internú reprezentáciu informácií o klientovi vo vlastníctve autorizačného servera:

@Configuration @EnableWebSecurity @PropertySource ("classpath: application.properties") verejná trieda SecurityConfig rozširuje WebSecurityConfigurerAdapter {private static List clients = Arrays.asList ("google", "facebook"); @Bean public ClientRegistrationRepository clientRegistrationRepository () {List registrations = clients.stream () .map (c -> getRegistration (c)) .filter (registration -> registration! = Null) .collect (Collectors.toList ()); vrátiť nové InMemoryClientRegistrationRepository (registrácie); }}

Tu tvoríme InMemoryClientRegistrationRepository so zoznamom ClientRegistration predmety.

4.2. Budova ClientRegistration Predmety

Pozrime sa na getRegistration () metóda, ktorá vytvára tieto objekty:

private static String CLIENT_PROPERTY_KEY = "spring.security.oauth2.client.registration."; @Autowired private Environment env; private ClientRegistration getRegistration (String client) {String clientId = env.getProperty (CLIENT_PROPERTY_KEY + client + ".client-id"); if (clientId == null) {return null; } Reťazec clientSecret = env.getProperty (CLIENT_PROPERTY_KEY + klient + ".client-secret"); if (client.equals ("google")) {return CommonOAuth2Provider.GOOGLE.getBuilder (client) .clientId (clientId) .clientSecret (clientSecret) .build (); } if (client.equals ("facebook")) {return CommonOAuth2Provider.FACEBOOK.getBuilder (client) .clientId (clientId) .clientSecret (clientSecret) .build (); } return null; }

Tu čítame prihlasovacie údaje klienta z podobného servera application.properties súbor, potom použite CommonOauth2Provider enum už definované v Spring Security pre ostatné vlastnosti klientov pre klientov Google a Facebook.

Každý ClientRegistration inštancia zodpovedá klientovi.

4.3. Registruje sa ClientRegistrationRepository

Nakoniec musíme vytvoriť OAuth2AuthorizedClientService fazuľa na základe ClientRegistrationRepository fazuľa a zaregistrovať sa na oauth2Login () element:

@Override protected void configure (HttpSecurity http) vyvolá výnimku {http.authorizeRequests (). AnyRequest (). Authenticated (). A () .oauth2Login () .clientRegistrationRepository (clientRegistrationRepository ()) .authorizedClientService (authorizedClient) } @Bean public OAuth2AuthorizedClientService authorizedClientService () {return new InMemoryOAuth2AuthorizedClientService (clientRegistrationRepository ()); }

Ako je dokázané tu, môžeme použiť clientRegistrationRepository () metóda oauth2Login () zaregistrovať vlastné registračné úložisko.

Budeme tiež musieť definovať vlastnú prihlasovaciu stránku, pretože sa už nebude automaticky generovať. Viac informácií o tom uvidíme v nasledujúcej časti.

Pokračujme v ďalšom prispôsobovaní nášho procesu prihlásenia.

5. Prispôsobenie oauth2Login ()

Existuje niekoľko prvkov, ktoré proces OAuth 2 používa a ktoré môžeme pomocou nich prispôsobiť oauth2Login () metódy.

Upozorňujeme, že všetky tieto prvky majú predvolenú konfiguráciu v Spring Boot a explicitná konfigurácia sa nevyžaduje.

Pozrime sa, ako ich môžeme prispôsobiť v našej konfigurácii.

5.1. Vlastná prihlasovacia stránka

Aj keď Spring Boot pre nás generuje predvolenú prihlasovaciu stránku, zvyčajne budeme chcieť definovať našu vlastnú prispôsobenú stránku.

Začnime s konfiguráciou novej prihlasovacej adresy URL pre server oauth2Login () element pomocouloginPage () metóda:

@Override protected void configure (HttpSecurity http) vyvolá výnimku {http.authorizeRequests () .antMatchers ("/ oauth_login") .permitAll () .anyRequest () .authenticated (). A () .oauth2Login () .loginPage ("/ oauth_login "); }

Tu sme nastavili našu prihlasovaciu URL tak, aby bola / oauth_login.

Ďalej definujeme a LoginController pomocou metódy, ktorá sa mapuje na túto adresu URL:

@Controller verejná trieda LoginController {súkromný statický reťazec autorizáciaRequestBaseUri = "oauth2 / autorizácia"; Mapa oauth2AuthenticationUrls = nový HashMap (); @Autowired private ClientRegistrationRepository clientRegistrationRepository; @GetMapping ("/ oauth_login") public String getLoginPage (model model) {// ... return "oauth_login"; }}

Táto metóda musí do zobrazenia poslať mapu dostupných klientov a ich koncových bodov autorizácie, ktoré získame od ClientRegistrationRepository fazuľa:

public String getLoginPage (model model) {Iterable clientRegistrations = null; ResolvableType type = ResolvableType.forInstance (clientRegistrationRepository) .as (Iterable.class); if (type! = ResolvableType.NONE && ClientRegistration.class.isAssignableFrom (type.resolveGenerics () [0])) {clientRegistrations = (Iterable) clientRegistrationRepository; } clientRegistrations.forEach (registration -> oauth2AuthenticationUrls.put (registration.getClientName (), authorizationRequestBaseUri + "/" + registration.getRegistrationId ())); model.addAttribute ("urls", oauth2AuthenticationUrls); vrátiť "oauth_login"; }

Nakoniec musíme definovať naše oauth_login.html stránka:

Prihlásiť sa s:

Zákazník

Toto je jednoduchá stránka HTML, ktorá zobrazuje odkazy na autentizáciu u každého klienta.

Po pridaní niektorých štýlov môžeme zmeniť vzhľad prihlasovacej stránky:

5.2. Úspešnosť a zlyhanie vlastného overenia

Správanie po overení môžeme riadiť pomocou rôznych metód:

  • defaultSuccessUrl () a failureUrl () - presmerovať používateľa na zadanú adresu URL
  • successHandler () a failureHandler () - vykonať vlastnú logiku po procese autentifikácie

Pozrime sa, ako môžeme nastaviť vlastné adresy URL na presmerovanie používateľa na:

.oauth2Login () .defaultSuccessUrl ("/ loginSuccess") .failureUrl ("/ loginFailure");

Ak používateľ navštívil zabezpečenú stránku pred autentifikáciou, bude po prihlásení presmerovaný na túto stránku; inak budú presmerovaní na / loginSuccess.

Ak chceme, aby bol používateľ vždy odoslaný na server / loginSuccess Metódu môžeme použiť bez ohľadu na to, či už boli alebo neboli na zabezpečenej stránke defaultSuccessUrl (“/ loginSuccess”, true).

Aby sme mohli použiť vlastný obslužný program, museli by sme vytvoriť triedu, ktorá implementuje AuthenticationSuccessHandler alebo AuthenticationFailureHandler rozhrania, prepísať zdedené metódy a potom nastaviť fazuľa pomocou successHandler () a zlyhanieHandler () metódy.

5.3. Koncový bod vlastnej autorizácie

Koncový bod autorizácie je koncový bod, ktorý Spring Security používa na spustenie žiadosti o autorizáciu na externý server.

Najprv, nastavme nové vlastnosti pre koncový bod autorizácie:

.oauth2Login () .authorizationEndpoint () .baseUri ("/ oauth2 / authorize-client") .authorizationRequestRepository (authorizedRequestRepository ());

Tu sme upravili baseUri do / oauth2 / authorize-client namiesto predvolenej hodnoty / oauth2 / autorizácia. Explicitne tiež nastavujeme znak authorisationRequestRepository () fazuľa, ktorú musíme definovať:

@Bean public AuthorizationRequestRepository authorizedRequestRepository () {return new HttpSessionOAuth2AuthorizationRequestRepository (); }

V našom príklade sme použili implementáciu poskytnutú na jar pre našu fazuľu, ale mohli by sme poskytnúť aj vlastnú.

5.4. Koncový bod vlastného tokenu

Token koncový bod spracováva prístupové tokeny.

Poďme explicitne nakonfigurovať tokenEndpoint ()s implementáciou klienta s predvolenou odpoveďou:

.oauth2Login () .tokenEndpoint () .accessTokenResponseClient (accessTokenResponseClient ());

A tu je odpoveď klienta bean:

@Bean public OAuth2AccessTokenResponseClient accessTokenResponseClient () {return new NimbusAuthorizationCodeTokenResponseClient (); }

Táto konfigurácia je rovnaká ako predvolená a používa jarnú implementáciu, ktorá je založená na výmene autorizačného kódu s poskytovateľom.

Samozrejme by sme mohli nahradiť aj klienta vlastnej odpovede.

5.5. Koncový bod vlastného presmerovania

Toto je koncový bod, na ktorý sa má po autentifikácii u externého poskytovateľa presmerovať.

Pozrime sa, ako môžeme zmeniť baseUri pre koncový bod presmerovania:

.oauth2Login () .redirectionEndpoint () .baseUri ("/ oauth2 / redirect")

Predvolený identifikátor URI je prihlásenie / oauth2 / kód.

Upozorňujeme, že ak to zmeníme, musíme tiež aktualizovať redirectUriTemplate majetok každého ClientRegistration a pridajte nový URI ako autorizovaný URI presmerovania pre každého klienta.

5.6. Koncový bod vlastných informácií o používateľovi

Koncový bod informácií o používateľovi je umiestnenie, ktoré môžeme využiť na získanie informácií o používateľovi.

Tento koncový bod môžeme prispôsobiť pomocou userInfoEndpoint () metóda. K tomu môžeme použiť metódy ako napr userService () a customUserType () upraviť spôsob získavania informácií o používateľovi.

6. Prístup k informáciám o používateľovi

Spoločnou úlohou, ktorú by sme mohli chcieť dosiahnuť, je vyhľadanie informácií o prihlásenom používateľovi. Pre to, môžeme podať požiadavku na koncový bod s informáciami o používateľovi.

Najskôr budeme musieť získať klienta zodpovedajúceho aktuálnemu používateľskému tokenu:

@Autowired private OAuth2AuthorizedClientService authorizedClientService; @GetMapping ("/ loginSuccess") verejný reťazec getLoginInfo (model modelu, autentifikácia OAuth2AuthenticationToken) {OAuth2AuthorizedClient client = authorizedClientService .loadAuthorizedClient (authentication.getAuthorizedClientRegistrationId (), authentication.getName ()); // ... return "loginSuccess"; }

Ďalej pošleme žiadosť do koncového bodu s informáciami o používateľovi klienta a načítame Mapa atribútov používateľa:

Reťazec userInfoEndpointUri = client.getClientRegistration () .getProviderDetails (). GetUserInfoEndpoint (). GetUri (); if (! StringUtils.isEmpty (userInfoEndpointUri)) {RestTemplate restTemplate = new RestTemplate (); Hlavičky HttpHeaders = nové HttpHeaders (); headers.add (HttpHeaders.AUTHORIZATION, "Nositeľ" + client.getAccessToken () .getTokenValue ()); HttpEntity entity = new HttpEntity ("", hlavičky); ResponseEntity response = restTemplate .exchange (userInfoEndpointUri, HttpMethod.GET, entita, Map.class); Mapovať userAttributes = response.getBody (); model.addAttribute ("meno", userAttributes.get ("meno")); }

Pridaním názov majetok ako a Model atribút, môžeme ho zobraziť v loginSuccess zobraziť ako uvítaciu správu pre používateľa:

Okrem toho názov, the mapa atribútov používateľa obsahuje aj vlastnosti ako napr e-mail, priezvisko,obrázok, miestne nastavenie.

7. Záver

V tomto článku sme videli, ako môžeme používať oauth2Login () prvok v Spring Security na autentifikáciu u rôznych poskytovateľov, ako sú Google a Facebook. Prešli sme tiež niekoľkými bežnými scenármi prispôsobenia tohto procesu.

Celý zdrojový kód príkladov nájdete na GitHub.


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