Keycloak vložený do aplikácie Spring Boot

1. Prehľad

Keycloak je open-source riešenie pre správu identít a prístupu spravuje RedHat a vyvinul v Jave JBoss.

V tejto príručke sa naučíme ako nastaviť server Keycloak vložený do aplikácie Spring Boot. Toto uľahčuje spustenie predkonfigurovaného servera Keycloak.

Keycloak je možné spustiť aj ako samostatný server, ktorý však zahrnuje jeho stiahnutie a nastavenie pomocou správcovskej konzoly.

2. Predkonfigurácia Keycloak

Na začiatok pochopíme, ako môžeme predkonfigurovať server Keycloak.

Server obsahuje množinu sfér, z ktorých každá sa chová ako izolovaná jednotka pre správu používateľov. Aby sme to predkonfigurovali, musíme zadať definičný súbor sféry vo formáte JSON.

V tomto JSON je pretrvávajúce všetko, čo je možné nakonfigurovať pomocou správcovskej konzoly Keycloak.

Náš autorizačný server bude vopred nakonfigurovaný na baeldung-realm.json. Pozrime sa na niekoľko relevantných konfigurácií v súbore:

  • používateľov: naši predvolení používatelia by boli [chránené e-mailom] a [chránené e-mailom]; tu tiež budú mať svoje poverenia
  • klientov: definujeme klienta s id nový klient
  • standardFlowEnabled: nastavený na true, aby sa aktivoval tok autorizačného kódu pre nový klient
  • redirectUris: nový klientTu sú uvedené adresy URL, na ktoré server presmeruje po úspešnej autentifikácii
  • webOrigins: nastavený na “+” povoliť podporu CORS pre všetky adresy URL uvedené ako redirectUris

Server Keycloak štandardne vydáva tokeny JWT, takže na to nie je potrebná samostatná konfigurácia. Pozrime sa ďalej na konfigurácie Maven.

3. Konfigurácia Maven

Pretože Keycloak vložíme do aplikácie Spring Boot, nie je potrebné ho sťahovať osobitne.

Namiesto toho nastavíme nasledujúcu sadu závislostí:

 org.springframework.boot spring-boot-starter-web org.springframework.boot spring-boot-starter-aktor org.springframework.boot spring-boot-starter-data-jpa com.h2database h2 runtime 

Upozorňujeme, že tu používame verziu 2.2.6.RELEASE verzie Spring Boot. Závislosti spring-boot-starter-data-jpa a H2 boli pridané kvôli perzistencii. Ostatný springframework.boot závislosti sú pre webovú podporu, pretože tiež musíme byť schopní spustiť autorizačný server Keycloak, ako aj administrátorskú konzolu ako webové služby.

Budeme tiež potrebovať niekoľko závislostí pre Keycloak a RESTEasy:

 org.jboss.resteasy resteasy-jackson2-provider 3.12.1. Konečný org.keycloak keycloak-dependencies-server-all 11.0.2 pom 

Na webe Maven nájdete najnovšie verzie služieb Keycloak a RESTEasy.

A nakoniec musíme prekonať vlastnosť používať verziu deklarovanú Keycloakom namiesto verzie definovanej Spring Boot:

 10.1.8. Konečné 

4. Vstavaná konfigurácia keycloak

Teraz definujme jarnú konfiguráciu pre náš autorizačný server:

@Configuration verejná trieda EmbeddedKeycloakConfig {@Bean ServletRegistrationBean keycloakJaxRsApplication (KeycloakServerProperties keycloakServerProperties, DataSource dataSource) vyvolá výnimku {mockJndiEnvironment (dataSource); EmbeddedKeycloakApplication.keycloakServerProperties = keycloakServerProperties; ServletRegistrationBean servlet = nový ServletRegistrationBean (nový 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); spätný servlet; } @Bean FilterRegistrationBean keycloakSessionManagement (KeycloakServerProperties keycloakServerProperties) {FilterRegistrationBean filter = nový FilterRegistrationBean (); filter.setName ("Správa relácie Keycloak"); filter.setFilter (nový EmbeddedKeycloakRequestFilter ()); filter.addUrlPatterns (keycloakServerProperties.getContextPath () + "/ *"); spätný filter; } private void mockJndiEnvironment (DataSource dataSource) vrhá NamingException {NamingManager.setInitialContextFactoryBuilder ((env) -> (prostredie) -> nový InitialContext () {@Override verejné vyhľadávanie objektov (názov názvu) {návrat vyhľadávanie (name.toString ()); } @Override verejné vyhľadávanie objektov (názov reťazca) {if ("spring / datasource" .equals (name)) {return dataSource;} return null;} @Override public NameParser getNameParser (názov reťazca) {return CompositeName :: new;} @Override public void close () {}}); }} 

Poznámka: Nerobte si starosti s chybou kompilácie, zadefinujeme EmbeddedKeycloakRequestFilter triedy neskôr.

Ako tu vidíme, najskôr sme Keycloak nakonfigurovali ako aplikáciu JAX-RS s KeycloakServerProperties pre trvalé ukladanie vlastností Keycloak, ako je uvedené v našom definičnom súbore sféry. Potom sme pridali filter na správu relácií a posmievali sa prostrediu JNDI, aby sme použili a jar / zdroj údajov, čo je naša H2 databáza v pamäti.

5. KeycloakServerProperties

Teraz sa pozrime na KeycloakServerProperties práve sme spomenuli:

@ConfigurationProperties (prefix = "keycloak.server") verejná trieda KeycloakServerProperties {String contextPath = "/ auth"; Reťazec realmImportFile = "baeldung-realm.json"; AdminUser adminUser = nový AdminUser (); // getre a setre verejné statické triedy AdminUser {String username = "admin"; Reťazcové heslo = "admin"; // zakladatelia a zakladatelia}} 

Ako vidíme, toto je jednoduchý POJO na nastavenie contextPath, adminUser a definičný súbor sféry.

6. EmbeddedKeycloakApplication

Ďalej sa pozrime na triedu, ktorá na vytváranie sfér používa konfigurácie, ktoré sme nastavili predtým:

verejná trieda EmbeddedKeycloakApplication rozširuje KeycloakApplication {private static final Logger LOG = LoggerFactory.getLogger (EmbeddedKeycloakApplication.class); statické KeycloakServerProperties keycloakServerProperties; protected void loadConfig () {JsonConfigProviderFactory factory = new RegularJsonConfigProviderFactory (); Config.init (factory.create () .orElseThrow (() -> nový NoSuchElementException ("nie je k dispozícii žiadna hodnota"))); } public EmbeddedKeycloakApplication () {createMasterRealmAdminUser (); createBaeldungRealm (); } private void createMasterRealmAdminUser () {KeycloakSession session = getSessionFactory (). create (); ApplianceBootstrap applianceBootstrap = nový ApplianceBootstrap (relácia); AdminUser admin = keycloakServerProperties.getAdminUser (); skúste {session.getTransactionManager (). begin (); applianceBootstrap.createMasterRealmUser (admin.getUsername (), admin.getPassword ()); session.getTransactionManager (). commit (); } catch (Výnimka okrem) {LOG.warn ("Nepodarilo sa vytvoriť hlavného správcu používateľa keycloak: {}", ex.getMessage ()); session.getTransactionManager (). rollback (); } session.close (); } private void createBaeldungRealm () {KeycloakSession session = getSessionFactory (). create (); skúste {session.getTransactionManager (). begin (); Správca RealmManager = nový RealmManager (relácia); Resource lessonRealmImportFile = nový ClassPathResource (keycloakServerProperties.getRealmImportFile ()); manager.importRealm (JsonSerialization.readValue (lessonRealmImportFile.getInputStream (), RealmRepresentation.class)); session.getTransactionManager (). commit (); } catch (Exception ex) {LOG.warn ("Nepodarilo sa importovať súbor JSM Realm: {}", ex.getMessage ()); session.getTransactionManager (). rollback (); } session.close (); }} 

7. Implementácie vlastnej platformy

Ako sme už povedali, Keycloak vyvinula spoločnosť RedHat / JBoss. Preto poskytuje knižnice funkcií a rozšírení na nasadenie aplikácie na serveri Wildfly alebo ako riešenie Quarkus.

V tomto prípade sa odkláňame od týchto alternatív a v dôsledku toho musíme pre niektoré rozhrania a triedy špecifické pre platformu poskytnúť vlastné implementácie.

Napríklad v EmbeddedKeycloakApplication práve sme nakonfigurovali, najskôr sme načítali konfiguráciu servera Keycloak keycloak-server.jsonpomocou prázdnej podtriedy abstraktu JsonConfigProviderFactory:

verejná trieda RegularJsonConfigProviderFactory rozširuje JsonConfigProviderFactory {}

Potom sme predĺžili KeycloakApplication na vytvorenie dvoch sfér: pán a baeldung. Tieto sa vytvárajú podľa vlastností špecifikovaných v našom súbore definície sféry, baeldung-realm.json.

Ako vidíte, používame a KeycloakSession aby sme mohli vykonať všetky transakcie a aby to správne fungovalo, museli sme vytvoriť zvyk AbstractRequestFilter (EmbeddedKeycloakRequestFilter) a nastavíte na to fazuľu pomocou a KeycloakSessionServletFilter v EmbeddedKeycloakConfig spis.

Ďalej potrebujeme niekoľko vlastných poskytovateľov, aby sme mali vlastné implementácie org.keycloak.common.util.ResteasyProvider a org.keycloak.platform.PlatformProvider a nespoliehajte sa na vonkajšie závislosti.

Dôležité je, že informácie o týchto vlastných poskytovateľoch by mali byť zahrnuté v projekte META-INF / služby priečinok, aby sa vybrali za behu programu.

8. Spojíme to všetko

Ako sme videli, Keycloak podstatne zjednodušil požadované konfigurácie zo strany aplikácie. Nie je potrebné programovo definovať zdroj údajov ani žiadne konfigurácie zabezpečenia.

Aby sme to všetko spojili, musíme definovať konfiguráciu pre Spring a Spring Boot Application.

8.1. aplikácia.yml

Pre jarné konfigurácie použijeme jednoduchý YAML:

server: port: 8083 pružina: zdroj údajov: používateľské meno: sa url: jdbc: h2: mem: testdb keycloak: server: contextPath: / auth adminUser: username: bael-admin heslo: ******** realmImportFile: baeldung- realm.json

8.2. Aplikácia Spring Boot

Na záver je tu aplikácia Spring Boot:

@SpringBootApplication (vylúčiť = LiquibaseAutoConfiguration.class) @EnableConfigurationProperties (KeycloakServerProperties.class) verejná trieda AuthorizationServerApp {private static final Logger LOG = LoggerFactory.getLogger (AuthorizationServerApp.class); public static void main (String [] args) vyvolá výnimku {SpringApplication.run (AuthorizationServerApp.class, args); } @Bean ApplicationListener onApplicationReadyEventListener (ServerProperties serverProperties, KeycloakServerProperties keycloakServerProperties) {return (evt) -> {Integer port = serverProperties.getPort (); Reťazec keycloakContextPath = keycloakServerProperties.getContextPath (); LOG.info ("Začal sa vložený keycloak: // localhost: {} {} používať keycloak", port, keycloakContextPath); }; }}

Najmä tu sme povolili KeycloakServerProperties konfigurácia na vloženie do ApplicationListener fazuľa.

Po spustení tejto triedy môžeme prejsť na uvítaciu stránku autorizačného servera na adrese // localhost: 8083 / auth /.

9. Záver

V tomto rýchlom výučbe sme videli, ako nastaviť server Keycloak vložený do aplikácie Spring Boot. Zdrojový kód tejto aplikácie je k dispozícii na GitHub.

Pôvodný nápad na túto implementáciu vytvoril Thomas Darimont a možno ho nájsť v serveri Embedded-Spring-Boot-Keycloak-Server.