Tavaszi biztonság 5 - OAuth2 bejelentkezés
1. Áttekintés
A Spring Security 5 bemutat egy újat OAuth2LoginConfigurer osztály, amelyet egy külső Authorization Server konfigurálásához használhatunk.
Ebben a cikkben, megvizsgáljuk a oauth2Login () elem.
2. Maven-függőségek
A Spring Boot projektben csak arra van szükségünk, hogy hozzáadjuk az indítót spring-boot-starter-oauth2-kliens:
org.springframework.boot spring-boot-starter-oauth2-client 2.3.3. KÖZLEMÉNY
Egy nem Boot projektben a szokásos tavaszi és tavaszi biztonsági függőségeken kívül kifejezetten hozzá kell adnunk a spring-security-oauth2-client és spring-security-oauth2-jose függőségek:
org.springframework.security spring-security-oauth2-client 5.3.4.RELEASE org.springframework.security spring-security-oauth2-jose 5.3.4.RELEASE
3. Ügyfelek beállítása
A Spring Boot projektben csak annyit kell tennünk, hogy hozzáadunk néhány szabványtulajdonságot minden egyes konfigurálni kívánt ügyfélhez.
Állítsuk be a projektünket a Google és a Facebook hitelesítés-szolgáltatóként regisztrált kliensekkel történő bejelentkezéshez.
3.1. Ügyfél-hitelesítő adatok beszerzése
A Google OAuth2 hitelesítéshez szükséges ügyfél-hitelesítő adatok megszerzéséhez lépjen tovább a Google API Console „Hitelesítő adatok” szakaszába.
Itt létrehozzuk az „OAuth2 Client ID” típusú hitelesítő adatokat webalkalmazásunkhoz. Ennek eredményeként a Google ügyfél-azonosítót és titkot állít be számunkra.
Be kell állítanunk egy engedélyezett átirányítási URI-t is a Google Console-ban, amely az az út, amelyre a felhasználókat átirányítják, miután sikeresen bejelentkeztek a Google-lal.
Alapértelmezés szerint a Spring Boot ezt az átirányítási URI-t konfigurálja / login / oauth2 / code / {registrationId}. Ezért a Google számára hozzáadjuk az URI-t:
// localhost: 8081 / login / oauth2 / code / google
A kliens hitelesítő adatainak megszerzéséhez a Facebookon történő hitelesítéshez regisztrálnunk kell egy alkalmazást a Facebook fejlesztőknek webhelyen, és be kell állítanunk a megfelelő URI-t „Valid OAuth átirányítási URI” néven:
// localhost: 8081 / login / oauth2 / code / facebook
3.3. Biztonsági konfiguráció
Ezután hozzá kell adnunk az ügyfél hitelesítő adatait a alkalmazás.tulajdonságok fájl. A Spring Security tulajdonságai előtaggal vannak ellátva „Tavasz.biztonság.oauth2.ügyfél.regisztráció” utána az ügyfél neve, majd az ügyfél tulajdonság neve:
spring.security.oauth2.client.registration.google.client-id = spring.security.oauth2.client.registration.google.client-secret = spring.security.oauth2.client.registration.facebook.client-id = spring. security.oauth2.client.registration.facebook.client-secret =
Ha ezeket a tulajdonságokat hozzáadja legalább egy klienshez, akkor engedélyezi a Oauth2ClientAutoConfiguration osztály amely felállítja az összes szükséges babot.
Az automatikus webbiztonsági konfiguráció megegyezik egy egyszerű definiálásával oauth2Login () elem:
A @Configuration public class SecurityConfig kiterjeszti a WebSecurityConfigurerAdapter {@Orride védett void konfigurációt (HttpSecurity http) dobja a {http.authorizeRequests () .anyRequest (). Hitelesített () .és () .oauth2Login (); }}
Itt láthatjuk a oauth2Login () elemet a már ismerthez hasonló módon használják httpBasic () és formLogin () elemek.
Most, amikor megpróbálunk hozzáférni egy védett URL-hez, az alkalmazás automatikusan létrehozott bejelentkezési oldalt jelenít meg két klienssel:
3.4. Egyéb ügyfelek
Ne feledje, hogy a Google és a Facebook mellett a Spring Security projekt alapértelmezett konfigurációkat is tartalmaz a GitHub és az Okta számára. Ezek az alapértelmezett konfigurációk minden szükséges információt megadnak a hitelesítéshez, ami lehetővé teszi számunkra, hogy csak az ügyfél hitelesítő adatait adjuk meg.
Ha egy másik hitelesítés-szolgáltatót akarunk használni, amely nincs konfigurálva a Spring Security alkalmazásban, meg kell határoznunk a teljes konfigurációt, olyan információkkal együtt, mint az engedélyezés URI és a token URI. Az alábbiakban áttekintjük a Spring Security alapértelmezett konfigurációit, hogy képet kapjunk a szükséges tulajdonságokról.
4. Beállítás nem indító projektben
4.1. A. Létrehozása ClientRegistrationRepository Bab
Ha nem egy Spring Boot alkalmazással dolgozunk, akkor meg kell határoznunk a ClientRegistrationRepository bab amely tartalmazza a hitelesítési kiszolgáló tulajdonában lévő ügyfélinformációk belső ábrázolását:
@Configuration @EnableWebSecurity @PropertySource ("classpath: application.properties") nyilvános osztályú SecurityConfig kiterjeszti a 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 ()); return new InMemoryClientRegistrationRepository (regisztrációk); }}
Itt létrehozunk egy InMemoryClientRegistrationRepository listával ClientRegistration tárgyakat.
4.2. Épület ClientRegistration Tárgyak
Lássuk a getRegistration () módszer, amely ezeket az objektumokat építi fel:
privát statikus karakterlánc CLIENT_PROPERTY_KEY = "spring.security.oauth2.client.registration."; @Autowired privát környezet env; privát ClientRegistration getRegistration (String kliens) {String clientId = env.getProperty (CLIENT_PROPERTY_KEY + kliens + ".client-id"); if (clientId == null) {return null; } Karakterlánc clientSecret = env.getProperty (CLIENT_PROPERTY_KEY + kliens + ".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; }
Itt egy hasonló hitelesítő adatait olvassuk alkalmazás.tulajdonságok fájlt, majd a CommonOauth2Provider A Spring Security már meghatározta a Google és a Facebook ügyfelek többi ügyféltulajdonságát.
Minden egyes ClientRegistration példány megfelel egy ügyfélnek.
4.3. A ClientRegistrationRepository
Végül létre kell hoznunk egy OAuth2AuthorizedClientService bab alapján a ClientRegistrationRepository babot és regisztrálja mindkettőt a oauth2Login () elem:
A @Orride protected void configure (HttpSecurity http) dobja a (z) {http.authorizeRequests (). AnyRequest (). AnyRequest (). Authenticated () .and () .oauth2Login () .clientRegistrationRepository (clientRegistrationRepository ()) .authorizedClientService (engedéllyelClientService (engedéllyelClientService) (engedélyezettClientService) } @Bean public OAuth2AuthorizedClientService AuthorClientService () {return new InMemoryOAuth2AuthorizedClientService (clientRegistrationRepository ()); }
Amint azt itt bizonyítják, használhatjuk a clientRegistrationRepository () a metódusa oauth2Login () egyedi regisztrációs adattár regisztrálásához.
Meg kell határoznunk egy egyedi bejelentkezési oldalt is, mivel az már nem jön létre automatikusan. Erről további információkat a következő szakaszban találunk.
Folytassuk a bejelentkezési folyamat további testreszabását.
5. Testreszabás oauth2Login ()
Az OAuth 2 folyamat számos elemet használ, amelyekkel testre szabhatjuk oauth2Login () mód.
Ne feledje, hogy ezeknek az elemeknek alapértelmezett konfigurációja van a Spring Boot alkalmazásban, és nem szükséges explicit konfiguráció.
Nézzük meg, hogyan tudjuk ezeket testreszabni a konfigurációnkban.
5.1. Egyéni bejelentkezési oldal
Annak ellenére, hogy a Spring Boot generál számunkra egy alapértelmezett bejelentkezési oldalt, általában saját testreszabott oldalunkat szeretnénk meghatározni.
Kezdjük egy új bejelentkezési URL konfigurálásával a oauth2Login () elemet abejelentkezési oldal() módszer:
A @Orride protected void configure (HttpSecurity http) dobja a {http.authorizeRequests () .antMatchers ("/ oauth_login") .permitAll () .anyRequest () .authenticated () .and () .oauth2Login () .loginPage ("/ oauth_login "); }
Itt állítottuk be bejelentkezési URL-jünket / oauth_login.
Ezután definiáljuk a LoginController erre az URL-re leképezett módszerrel:
@Controller public class LoginController {private static String authenticationRequestBaseUri = "oauth2 / authorisation"; Map oauth2AuthenticationUrls = new HashMap (); @Autowired private ClientRegistrationRepository clientRegistrationRepository; @GetMapping ("/ oauth_login") public String getLoginPage (Model model) {// ... return "oauth_login"; }}
Ennek a módszernek el kell küldenie a rendelkezésre álló kliensek és engedélyezési végpontjaik térképét a nézethez, amelyet a ClientRegistrationRepository bab:
public String getLoginPage (modellmodell) {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 (regisztrálás -> oauth2AuthenticationUrls.put (registration.getClientName (), authorisationRequestBaseUri + "/" + registration.getRegistrationId ())); model.addAttribute ("urls", oauth2AuthenticationUrls); return "oauth_login"; }
Végül meg kell határoznunk a sajátunkat oauth_login.html oldal:
Bejelentkezés vele:
Ügyfél
Ez egy egyszerű HTML oldal, amely hivatkozásokat mutat az egyes kliensek hitelesítéséhez.
Néhány stílus hozzáadása után megváltoztathatjuk a bejelentkezési oldal megjelenését:
5.2. Egyéni hitelesítési siker és sikertelenség
Különböző módszerek segítségével szabályozhatjuk a hitelesítés utáni viselkedést:
- defaultSuccessUrl () és FailUrl () - a felhasználó átirányítása egy adott URL-re
- successHandler () és FailHandler () - az egyedi logika végrehajtása a hitelesítési folyamat nyomán
Nézzük meg, hogyan állíthatjuk be az egyéni URL-eket a felhasználó átirányítására:
.oauth2Login () .defaultSuccessUrl ("/ loginSuccess") .failureUrl ("/ loginFailure");
Ha a felhasználó egy hitelesített oldalt látogatott meg a hitelesítés előtt, a bejelentkezés után átirányítják az adott oldalra; különben átirányítják őket / loginSuccess.
Ha azt akarjuk, hogy a felhasználót mindig a / loginSuccess URL függetlenül attól, hogy korábban egy biztonságos oldalon voltak-e vagy sem, használhatjuk a módszert defaultSuccessUrl (“/ loginSuccess”, igaz).
Egyéni kezelő használatához létre kell hoznunk egy osztályt, amely megvalósítja a AuthenticationSuccessHandler vagy AuthenticationFailureHandler interfészeket, felülírja az örökölt módszereket, majd állítsa be a babot a successHandler () és FailHandler () módszerek.
5.3. Egyéni hitelesítési végpont
Az engedélyezési végpont az a végpont, amelyet a Spring Security használ a hitelesítési kérelem kiváltására a külső kiszolgálóhoz.
Első, állítsunk be új tulajdonságokat az engedélyezési végponthoz:
.oauth2Login [].
Itt módosítottuk a baseUri nak nek / oauth2 / autorize-client az alapértelmezett helyett / oauth2 / engedély. Kifejezetten beállítunk egy authorityRequestRepository () bab, amelyet meg kell határoznunk:
@Bean public AuthorizationRequestRepository authorityRequestRepository () {return new HttpSessionOAuth2AuthorizationRequestRepository (); }
Példánkban a tavaszi megvalósítást használtuk babunkhoz, de egyedi megoldást is tudnánk biztosítani.
5.4. Egyéni token végpont
A jelző végpont feldolgozza a hozzáférési tokeneket.
Konfiguráljuk kifejezetten a tokenEndpoint ()az alapértelmezett válasz ügyfél-megvalósítással:
.oauth2Login () .tokenEndpoint () .accessTokenResponseClient (accessTokenResponseClient ());
És itt van a válasz kliens bab:
@Bean public OAuth2AccessTokenResponseClient accessTokenResponseClient () {return new NimbusAuthorizationCodeTokenResponseClient (); }
Ez a konfiguráció megegyezik az alapértelmezettel, és a tavaszi implementációt használja, amely az engedélyezési kód cseréjén alapszik a szolgáltatóval.
Természetesen helyettesíthetnénk egy egyedi válaszügyfelet is.
5.5. Egyéni átirányítási végpont
Ez az a végpont, ahová át kell irányítani a külső szolgáltatóval történő hitelesítést követően.
Lássuk, hogyan változtathatjuk meg a baseUri az átirányítási végponthoz:
.oauth2Login () .redirectionEndpoint () .baseUri ("/ oauth2 / redirect")
Az alapértelmezett URI login / oauth2 / code.
Vegye figyelembe, hogy ha megváltoztatjuk, akkor a redirectUriTemplate tulajdonságai mindegyiknek ClientRegistration és adja hozzá az új URI-t minden egyes ügyfél engedélyezett átirányítási URI-ként.
5.6. Egyéni felhasználói információk végpont
A felhasználói információs végpont az a hely, amelyet felhasználhatunk a felhasználói információk megszerzéséhez.
Testreszabhatjuk ezt a végpontot a userInfoEndpoint () módszer. Ehhez használhatunk olyan módszereket, mint a userService () és customUserType () a felhasználói információk lekérésének módjának módosítása.
6. Hozzáférés a felhasználói információkhoz
Gyakori feladat, amelyet el szeretnénk érni, hogy információt keressünk a bejelentkezett felhasználóról. Ezért, kérelmet intézhetünk a felhasználói információk végpontjához.
Először meg kell szereznünk az aktuális felhasználói tokennek megfelelő klienst:
@Autowired private OAuth2AuthorizedClientService AuthorClientService; @GetMapping ("/ loginSuccess") nyilvános karakterlánc getLoginInfo (modellmodell, OAuth2AuthenticationToken hitelesítés) {OAuth2AuthorizedClient kliens = authorisedClientService .loadAuthorizedClient (authentication.getAuthorizedClientRegistrationId ()), authentication.getName // ... return "loginSuccess"; }
Ezután küldünk egy kérést az ügyfél felhasználói információs végpontjának, és lekérjük a userAttributes Map:
Karakterlánc userInfoEndpointUri = client.getClientRegistration () .getProviderDetails (). GetUserInfoEndpoint (). GetUri (); if (! StringUtils.isEmpty (userInfoEndpointUri)) {RestTemplate restTemplate = új RestTemplate (); HttpHeaders fejlécek = new HttpHeaders (); headers.add (HttpHeaders.AUTHORIZATION, "Bearer" + client.getAccessToken () .getTokenValue ()); HttpEntity entitás = new HttpEntity ("", fejlécek); ResponseEntity response = restTemplate .exchange (userInfoEndpointUri, HttpMethod.GET, entitás, Map.class); Map userAttributes = response.getBody (); model.addAttribute ("név", userAttributes.get ("név")); }
A név ingatlan, mint a Modell attribútummal megjeleníthetjük a loginSuccess megtekintés üdvözlő üzenetként a felhasználónak:
mellett név, a userAttributes Map olyan tulajdonságokat is tartalmaz, mint e-mail, családi név,kép, területi beállítás.
7. Következtetés
Ebben a cikkben megnéztük, hogyan használhatjuk a oauth2Login () elem a Spring Security-nél, hogy hitelesítsen különböző szolgáltatóknál, például a Google-nél és a Facebookon. A folyamat testreszabásának néhány általános forgatókönyvét is átéltük.
A példák teljes forráskódja megtalálható a GitHub oldalon.