Kulcstartó beágyazva egy tavaszi csomagtartó alkalmazásba

1. Áttekintés

A Keycloak egy nyílt forráskódú Identity and Access Management megoldás a RedHat adminisztrálta, Java-ban pedig a JBoss fejlesztette ki.

Ebben az oktatóanyagban megtanuljuk a Spring Boot alkalmazásba ágyazott Keycloak szerver beállítása. Ez megkönnyíti az előre konfigurált Keycloak szerver indítását.

A Keycloak önálló kiszolgálóként is futtatható, de ez magában foglalja annak letöltését és beállítását a Kezelői konzolon keresztül.

2. Kulcstartó előkonfigurálása

Először is, értsük meg, hogyan konfigurálhatjuk előre a Keycloak szervert.

A szerver egy sor tartományt tartalmaz, amelyek mindegyike elkülönített egységként működik a felhasználói kezeléshez. Az előzetes konfiguráláshoz meg kell adnunk egy tartomány meghatározási fájlt JSON formátumban.

Minden, ami a Keycloak Felügyeleti Konzol segítségével konfigurálható, továbbra is fennmarad ebben a JSON-ban.

A Hitelesítési Szerverünket előre konfiguráljuk baeldung-realm.json. Lássunk néhány releváns konfigurációt a fájlban:

  • felhasználók: alapértelmezett felhasználóink ​​lennének [e-mail védett] és [e-mail védett]; itt lesznek a hitelesítő adatok is
  • ügyfelek: megadunk egy klienst az azonosítóval newClient
  • standardFlowEnabled: true értékre állítva az engedélyezési kód folyamatának aktiválásához newClient
  • redirectUris: newClientItt vannak azok az URL-címek, amelyekre a szerver átirányít a sikeres hitelesítés után
  • webOrigins: állítva “+” hogy engedélyezze a CORS-támogatást az összes URL-ként redirectUris

A Keycloak szerver alapértelmezés szerint JWT tokent ad ki, ezért ehhez nincs szükség külön konfigurációra. Nézzük a következő Maven konfigurációkat.

3. Maven konfiguráció

Mivel beillesztjük a Keycloakot egy Spring Boot alkalmazásba, nincs szükség külön letöltésre.

Helyette, a következő függőségeket állítjuk be:

 org.springframework.boot spring-boot-starter-web org.springframework.boot spring-boot-starter-actuator org.springframework.boot spring-boot-starter-data-jpa com.h2database h2 futásidejű 

Vegye figyelembe, hogy itt használjuk a Spring Boot 2.2.6.RELEASE verzióját. A függőségek spring-boot-starter-data-jpa és H2-t adtak hozzá a kitartás érdekében. A másik rugókeret.csizma a függőségek a webes támogatást jelentik, mivel képesnek kell lennünk futtatni a Keycloak jogosultságkiszolgálót, valamint az adminisztrációs konzolt is webszolgáltatásként.

Szükségünk lesz néhány függőségre a Keycloak és a RESTEasy számára:

 org.jboss.resteasy resteasy-jackson2-szolgáltató 3.12.1. Végső org.keycloak kulcstartó-függőségek-kiszolgáló-mind 11.0.2 pom 

Keresse meg a Maven webhelyét a Keycloak és a RESTEasy legújabb verzióival kapcsolatban.

És végül felül kell írnunk a tulajdonság, a Keycloak által deklarált verzió használata a Spring Boot által definiált verzió helyett:

 10.1.8.Döntő 

4. Beágyazott Keycloak konfiguráció

Most definiáljuk az engedélyezési kiszolgálónk Spring konfigurációját:

@Configuration public class EmbeddedKeycloakConfig {@Bean ServletRegistrationBean keycloakJaxRsApplication (KeycloakServerProperties keycloakServerProperties, DataSource dataSource) dobja a Kivétel {mockJndiEnvironment (dataSource); EmbeddedKeycloakApplication.keycloakServerProperties = keycloakServerProperties; ServletRegistrationBean servlet = new ServletRegistrationBean (új HttpServlet30Dispatcher ()); servlet.addInitParameter ("javax.ws.rs.Application", EmbeddedKeycloakApplication.class.getName ()); servlet.addInitParameter (ResteasyContextParameters.RESTEASY_SERVLET_MAPPING_PREFIX, keycloakServerProperties.getContextPath ()); servlet.addInitParameter (ResteasyContextParameters.RESTEASY_USE_CONTAINER_FORM_PARAMS, "true"); servlet.addUrlMappings (keycloakServerProperties.getContextPath () + "/ *"); servlet.setLoadOnStartup (1); servlet.setAsyncSupported (true); visszatérő servlet; } @Bean FilterRegistrationBean keycloakSessionManagement (KeycloakServerProperties keycloakServerProperties) {FilterRegistrationBean filter = new FilterRegistrationBean (); filter.setName ("Keycloak munkamenet-kezelés"); filter.setFilter (új EmbeddedKeycloakRequestFilter ()); filter.addUrlPatterns (keycloakServerProperties.getContextPath () + "/ *"); visszatérő szűrő; } private void mockJndiEnvironment (DataSource dataSource) dobja a NamingException {NamingManager.setInitialContextFactoryBuilder ((env) -> (környezet) -> new InitialContext () {@Override public Object lookup (név neve) {return lookup (név.toString ()); } @Orride public Object lookup (String name) {if ("spring / datasource" .equals (name)) {return dataSource;} return null;} @Orride public NameParser getNameParser (String name) {return CompositeName :: new;} @Orride public void close () {}}); }} 

Megjegyzés: Ne aggódjon a fordítási hiba miatt, mi definiáljuk a EmbeddedKeycloakRequestFilter osztály később.

Amint itt láthatjuk, először a Keycloak-ot JAX-RS alkalmazásként konfiguráltuk KeycloakServerProperties a Keycloak tulajdonságainak tartós tárolásához, a birodalmi definíciós fájlunkban meghatározottak szerint. Ezután hozzáadtunk egy munkamenet-kezelő szűrőt, és kigúnyoltunk egy JNDI környezetet az a használatához tavasz / adatforrás, amely a memóriában lévő H2 adatbázisunk.

5. KeycloakServerProperties

Most vessünk egy pillantást a KeycloakServerProperties most említettük:

@ConfigurationProperties (előtag = "keycloak.server") nyilvános osztály KeycloakServerProperties {String contextPath = "/ auth"; String realmImportFile = "baeldung-realm.json"; AdminUser adminUser = új AdminUser (); // getters and setters public static class AdminUser {String felhasználónév = "admin"; Karakterlánc jelszó = "admin"; // szerelők és beállítók}} 

Ahogy látjuk, ez egy egyszerű POJO a contextPath, adminUser és birodalomdefiníció.

6. EmbeddedKeycloakApplication

Ezután nézzük meg az osztályt, amely a korábban beállított konfigurációkat használja a birodalmak létrehozásához:

public class EmbeddedKeycloakApplication kiterjeszti a KeycloakApplication {private static final Logger LOG = LoggerFactory.getLogger (EmbeddedKeycloakApplication.class); statikus KeycloakServerProperties keycloakServerProperties; védett void loadConfig () {JsonConfigProviderFactory gyár = új RegularJsonConfigProviderFactory (); Config.init (factory.create () .orElseThrow (() -> new NoSuchElementException ("Nincs érték jelen"))); } public EmbeddedKeycloakApplication () {createMasterRealmAdminUser (); createBaeldungRealm (); } private void createMasterRealmAdminUser () {KeycloakSession session = getSessionFactory (). create (); ApplianceBootstrap applianceBootstrap = új ApplianceBootstrap (munkamenet); AdminUser admin = keycloakServerProperties.getAdminUser (); próbáld ki a {session.getTransactionManager (). begin (); applianceBootstrap.createMasterRealmUser (admin.getUsername (), admin.getPassword ()); session.getTransactionManager (). kötelezettség (); } catch (Exception ex) {LOG.warn ("Nem sikerült létrehozni a Keycloak master admin felhasználót: {}", ex.getMessage ()); session.getTransactionManager (). rollback (); } session.close (); } private void createBaeldungRealm () {KeycloakSession session = getSessionFactory (). create (); próbáld ki a {session.getTransactionManager (). begin (); RealmManager manager = új RealmManager (munkamenet); Erőforrás leckeRealmImportFile = új ClassPathResource (keycloakServerProperties.getRealmImportFile ()); manager.importRealm (JsonSerialization.readValue (lessonRealmImportFile.getInputStream (), RealmRepresentation.class)); session.getTransactionManager (). kötelezettség (); } catch (Exception ex) {LOG.warn ("Nem sikerült importálni a Realm json fájlt: {}", ex.getMessage ()); session.getTransactionManager (). rollback (); } session.close (); }} 

7. Egyéni platformmegvalósítások

Mint mondtuk, a Keycloakot a RedHat / JBoss fejlesztette ki. Ezért funkcionalitást és kiterjesztési könyvtárakat biztosít az alkalmazás Wildfly kiszolgálón vagy Quarkus megoldásként történő telepítéséhez.

Ebben az esetben eltávolodunk ettől az alternatívától, és ennek következtében egyes platformspecifikus interfészekhez és osztályokhoz egyedi megvalósításokat kell biztosítanunk.

Például a EmbeddedKeycloakApplication most konfiguráltuk, először betöltöttük a Keycloak szerver konfigurációját keycloak-server.json, az absztrakt üres alosztályát használva JsonConfigProviderFactory:

public class RegularJsonConfigProviderFactory kiterjeszti a JsonConfigProviderFactory {}

Aztán meghosszabbítottuk KeycloakApplication két birodalom létrehozásához: fő- és baeldung. Ezeket a tartománydefiníciós fájlunkban megadott tulajdonságok szerint hozzuk létre, baeldung-realm.json.

Mint láthatja, a KeycloakSession az összes tranzakció végrehajtásához, és ennek megfelelő működéséhez létre kellett hoznunk egy szokást AbstractRequestFilter (EmbeddedKeycloakRequestFilter), és ehhez állítson be egy babot az a használatával KeycloakSessionServletFilter ban,-ben EmbeddedKeycloakConfig fájl.

Ezenkívül szükségünk van párra egyedi szolgáltatók, hogy saját megvalósításunk legyen org.keycloak.common.util.ResteasyProvider és org.keycloak.platform.PlatformProvider és ne támaszkodjon külső függőségekre.

Fontos, hogy ezekre az egyedi szolgáltatókra vonatkozó információkat fel kell venni a projektbe META-INF / szolgáltatások mappát, hogy futás közben vegye fel őket.

8. Az összes összefogása

Ahogy láttuk, A Keycloak az alkalmazás oldaláról sokkal egyszerűbbé tette a szükséges konfigurációkat. Nincs szükség az adatforrás vagy bármilyen biztonsági konfiguráció programozott meghatározására.

Hogy mindezt összehozzuk, meg kell határoznunk a Spring és a Spring Boot alkalmazás konfigurációját.

8.1. alkalmazás.yml

Egy egyszerű YAML-t fogunk használni a tavaszi konfigurációkhoz:

szerver: port: 8083 tavasz: adatforrás: felhasználónév: sa url: jdbc: h2: mem: testdb billentyűzet: szerver: contextPath: / auth adminUser: felhasználónév: bael-admin jelszó: ******** realmImportFile: baeldung- birodalom.json

8.2. Tavaszi csomagtartó alkalmazás

Végül itt van a Spring Boot alkalmazás:

@SpringBootApplication (kizárja = LiquibaseAutoConfiguration.class) @EnableConfigurationProperties (KeycloakServerProperties.class) public class AuthorizationServerApp {private static final Logger LOG = LoggerFactory.getLogger (AuthorizationServerApp.class); public static void main (String [] args) a {SpringApplication.run (AuthorizationServerApp.class, args) kivételt dobja; } @Bean ApplicationListener onApplicationReadyEventListener (ServerProperties serverProperties, KeycloakServerProperties keycloakServerProperties) {return (evt) -> {Integer port = serverProperties.getPort (); String keycloakContextPath = keycloakServerProperties.getContextPath (); LOG.info ("Beágyazott Keycloak indult: // localhost: {} {} a Keycloak használatához", port, keycloakContextPath); }; }}

Nevezetesen itt engedélyeztük a KeycloakServerProperties konfigurációt, hogy befecskendezhesse a ApplicationListener bab.

Az osztály vezetése után elérhetjük az engedélyezési szerver üdvözlő oldalát a // localhost: 8083 / auth / címen..

9. Következtetés

Ebben a gyors bemutatóban láthattuk, hogyan kell beállítani a Spring Boot alkalmazásba ágyazott Keycloak szervert. Az alkalmazás forráskódja elérhető a GitHubon.

A megvalósítás eredeti ötletét Thomas Darimont dolgozta ki, és megtalálható a projekt beágyazott-rugós-boot-kulcsos-kiszolgálójában.