Jarná bezpečnosť: Skúmanie autentifikácie JDBC

Perzistencia hore

Práve som oznámil nové Naučte sa jar kurz zameraný na základy jari 5 a Spring Boot 2:

>> SKONTROLUJTE KURZ

1. Prehľad

V tomto krátkom tutoriáli preskúmame možnosti, ktoré ponúka Spring na vykonávanie autentifikácie JDBC pomocou existujúceho Dátový zdroj konfigurácia.

V našom príspevku Authentication with a Database-backed UserDetailsService sme analyzovali jeden prístup, ako to dosiahnuť, implementáciou UserDetailService rozhranie sami.

Tentokrát využijeme AuthenticationManagerBuilder # jdbcAuthentication smernice analyzovať výhody a nevýhody tohto jednoduchšieho prístupu.

2. Používanie zabudovaného pripojenia H2

Najskôr analyzujeme, ako môžeme dosiahnuť autentifikáciu pomocou zabudovanej databázy H2.

Je to ľahké dosiahnuť, pretože väčšina automatickej konfigurácie Spring Boot je pre tento scenár pripravená priamo z krabice.

2.1. Závislosti a konfigurácia databázy

Začnime podľa pokynov z nášho predchádzajúceho príspevku Spring Boot With H2 Database na adresu:

  1. Zahrňte zodpovedajúce spring-boot-starter-data-jpa a h2 závislosti
  2. Nakonfigurujte pripojenie k databáze s vlastnosťami aplikácie
  3. Povolte konzolu H2

2.2. Konfigurácia autentifikácie JDBC

Použijeme Spring Security AuthenticationManagerBuilder pomocný konfiguračný modul na konfiguráciu autentifikácie JDBC:

@Autowired private DataSource dataSource; @Autowired public void configureGlobal (AuthenticationManagerBuilder auth) vyvolá výnimku {auth.jdbcAuthentication () .dataSource (dataSource) .withDefaultSchema () .withUser (User.withUsername ("user") .password (passwordEncoder (). Encode ("pass") ) .roles („POUŽÍVATEĽ“)); } @Bean public PasswordEncoder passwordEncoder () {vrátiť nový BCryptPasswordEncoder (); }

Ako vidíme, používame automaticky nakonfigurované Dátový zdroj. The withDefaultSchema smernica pridáva databázový skript, ktorý vyplní predvolenú schému a umožní tak ukladanie používateľov a orgánov.

Táto základná schéma používateľa je zdokumentovaná v jarnej prílohe k zabezpečeniu.

Na záver programovo vytvoríme záznam v databáze s predvoleným používateľom.

2.3. Overenie konfigurácie

Vytvorme veľmi jednoduchý koncový bod na získanie autentifikovaných údajov Principal informácie:

@RestController @RequestMapping ("/ principal") verejná trieda UserController {@GetMapping public Principal retrievePrincipal (Principal principal) {návratový principál; }}

Okrem toho zabezpečíme tento koncový bod a zároveň povolíme prístup k konzole H2:

@Configuration verejná trieda SecurityConfiguration rozširuje WebSecurityConfigurerAdapter {@Override chránená neplatná konfigurácia (HttpSecurity httpSecurity) vyvolá výnimku {httpSecurity.authorizeRequests () .antMatchers ("/ h2-console / **") .permitAll () .anyRequest (). . a () .formLogin (); httpSecurity.csrf () .ignoringAntMatchers ("/ h2-console / **"); httpSecurity.headers () .frameOptions () .sameOrigin (); }}

Poznámka: tu reprodukujeme predchádzajúcu konfiguráciu zabezpečenia implementovanú programom Spring Boot, ale v skutočnom scenári pravdepodobne konzolu H2 vôbec neaktivujeme.

Teraz spustíme aplikáciu a prehľadáme konzolu H2. Môžeme to overiť Jar vytvára v našej vloženej databáze dve tabuľky: používateľov a orgánmi.

Ich štruktúra zodpovedá štruktúre definovanej v jarnom dodatku o bezpečnosti, ktorý sme spomínali predtým.

Nakoniec sa poďme autentifikovať a požiadať o / principál koncový bod, aby ste videli súvisiace informácie vrátane podrobností používateľa.

2.4. Pod kapotou

Na začiatku tohto príspevku sme predstavili odkaz na návod, ktorý vysvetlil ako môžeme prispôsobiť autentizáciu založenú na databáze implementujúcu UserDetailsService rozhranie; dôrazne odporúčame pozrieť si tento príspevok, ak chceme pochopiť, ako veci fungujú pod kapotou.

V tomto prípade sa spoliehame na implementáciu toho istého rozhrania, ktoré poskytuje Spring Security; the JdbcDaoImpl.

Ak túto triedu preskúmame, uvidíme UserDetails implementácia, ktorú používa, a mechanizmy na získavanie informácií o používateľoch z databázy.

Pre tento jednoduchý scenár to funguje celkom dobre, ale má to niekoľko nevýhod, ak chceme prispôsobiť databázovú schému alebo dokonca chceme použiť iného dodávateľa databázy.

Pozrime sa, čo sa stane, ak zmeníme konfiguráciu tak, aby používala inú službu JDBC.

3. Prispôsobenie schémy inej databáze

V tejto časti nakonfigurujeme autentifikáciu nášho projektu pomocou databázy MySQL.

Ako uvidíme ďalej, na dosiahnutie tohto cieľa sa budeme musieť vyhnúť používaniu predvolenej schémy a poskytnúť svoju vlastnú.

3.1. Závislosti a konfigurácia databázy

Pre začiatočníkov odstránime h2 závislosť a nahraďte ju zodpovedajúcou knižnicou MySQL:

 mysql mysql-konektor-java 8.0.17 

Ako vždy, môžeme vyhľadať najnovšiu verziu knižnice v Maven Central.

Teraz podľa toho znova nastavíme vlastnosti aplikácie:

spring.datasource.url = jdbc: mysql: // localhost: 3306 / jdbc_authentication spring.datasource.username = root spring.datasource.password = heslo

3.2. Spustenie predvolenej konfigurácie

Tieto by samozrejme mali byť prispôsobené na pripojenie k vášmu spustenému serveru MySQL. Na účely testovania tu začneme novú inštanciu pomocou Dockeru:

docker run -p 3306: 3306 --name bael-mysql -e MYSQL_ROOT_PASSWORD = pass -e MYSQL_DATABASE = jdbc_authentication mysql: najnovšie

Poďme teraz spustiť projekt, aby sme zistili, či je predvolená konfigurácia vhodná pre MySQL databázu.

Aplikácia v skutočnosti nebude môcť začať, pretože SQLSyntaxErrorException. Toto má vlastne zmysel; ako sme povedali, väčšina predvolenej automatickej konfigurácie je vhodná pre HSQLDB.

V tomto prípade, skript DDL dodávaný s withDefaultSchema smernica používa dialekt, ktorý nie je vhodný pre MySQL.

Preto sa musíme vyhnúť použitiu tejto schémy a poskytnúť vlastnú.

3.3. Prispôsobenie konfigurácie autentifikácie

Pretože nechceme používať predvolenú schému, budeme musieť z príkazu AuthenticationManagerBuilder konfigurácia.

Pretože tiež poskytujeme svoje vlastné skripty SQL, môžeme sa vyhnúť pokusu o programové vytvorenie používateľa:

@Autowired public void configureGlobal (AuthenticationManagerBuilder auth) vyvolá výnimku {auth.jdbcAuthentication () .dataSource (dataSource); }

Teraz sa pozrime na inicializačné skripty databázy.

Najprv náš schema.sql:

VYTVORIŤ TABUĽKU používateľov (používateľské meno VARCHAR (50) NIE NULL, heslo VARCHAR (100) NIE NULL, povolený TINYINT NIE NULL VÝCHOZÍ 1, PRIMÁRNY KLÍČ (používateľské meno)); VYTVORIŤ TABUĽKU autority (meno používateľa VARCHAR (50) NIE JE NULL, autorita VARCHAR (50) NIE JE NULL, ZAHRANIČNÝ KLÍČ (meno používateľa) REFERENCIE používatelia (meno používateľa)); VYTVORTE JEDINEČNÝ INDEX ix_auth_username na autoritách (meno používateľa, autorita);

A potom, náš data.sql:

- Používateľ user / pass INSERT INTO users (username, password, enabled) values ​​('user', '$ 2a $ 10 $ 8.UnVuG9HHgffUDAlk8qfOuVGkqRzgVymGe07xd00DMxs.AQubh4a', 1); VLOŽTE DO DO autorít (užívateľské meno, autorita) hodnoty ('užívateľ', 'ROLE_USER');

Nakoniec by sme mali upraviť niektoré ďalšie vlastnosti aplikácie:

  • Pretože teraz neočakávame, že Hibernate vytvorí schému, mali by sme deaktivovať ddl-auto nehnuteľnosť
  • V predvolenom nastavení Spring Boot inicializuje zdroj údajov iba pre vložené databázy, čo v tomto prípade nie je:
spring.datasource.initialization-mode = always spring.jpa.hibernate.ddl-auto = none

Vo výsledku by sme teraz mali byť schopní správne spustiť našu aplikáciu, autentifikovať a načítať Principal údaje z koncového bodu.

4. Prispôsobenie dotazov pre inú schému

Poďme ešte o krok ďalej. Predstavte si, že predvolená schéma nie je vhodná pre naše potreby.

4.1. Zmena predvolenej schémy

Predstavte si napríklad, že už máme databázu so štruktúrou, ktorá sa mierne líši od predvolenej:

CREATE TABLE bael_users (meno VARCHAR (50) NOT NULL, email VARCHAR (50) NOT NULL, heslo VARCHAR (100) NOT NULL, povolené TINYINT NOT NULL DEFAULT 1, PRIMARY KEY (email)); CREATE TABLE autority (e-mail VARCHAR (50) NIE NULL, autorita VARCHAR (50) NIE NULL, ZAHRANIČNÝ KLÍČ (e-mail) REFERENCIE bael_users (e-mail)); VYTVORTE JEDINEČNÝ INDEX ix_auth_email na autoritách (e-mail, autorita);

Nakoniec náš data.sql skript bude prispôsobený aj tejto zmene:

- Používateľ [chránený e-mailom] / odovzdať INSERT INTO bael_users (meno, e-mail, heslo, povolené) hodnoty ('user', '[email protected]', '$ 2a $ 10 $ 8.UnVuG9HHgffUDAlk8qfOuVGkqRzgVymGe07xd00DMxs.AQubh4a', 1); VLOŽTE DO DO autorít hodnoty (e-mail, autorita) ('[email protected]', 'ROLE_USER');

4.2. Spustenie aplikácie s novou schémou

Spustíme našu aplikáciu. Inicializuje sa správne, čo dáva zmysel, pretože naša schéma je správna.

Teraz, ak sa pokúsime prihlásiť, zistíme, že pri uvádzaní prihlasovacích údajov sa zobrazí výzva k chybe.

Jarná bezpečnosť stále hľadá používateľské meno pole v databáze. Našťastie pre nás konfigurácia overenia JDBC ponúka možnosť prispôsobenie dotazov použitých na získanie podrobností používateľa v procese autentifikácie.

4.3. Prispôsobenie vyhľadávacích dotazov

Prispôsobenie dotazov je celkom jednoduché. Pri konfigurácii jednoducho musíme poskytnúť svoje vlastné príkazy SQL AuthenticationManagerBuilder:

@Autowired public void configureGlobal (AuthenticationManagerBuilder auth) vyvolá výnimku {auth.jdbcAuthentication () .dataSource (dataSource) .usersByUsernameQuery ("vyberte e-mail, heslo, povolené" + "od bael_users" + "kde email =?") .AuthoritiesByUsername vyberte e-mail, orgán "+" z orgánov "+" kde email =? "); }

Môžeme aplikáciu spustiť ešte raz a pristupovať k / principál koncový bod pomocou nových poverení.

5. Záver

Ako vidíme, tento prístup je oveľa jednoduchší ako vytváranie vlastného UserDetailServiceimplementácia, ktorá znamená náročný proces; vytváranie entít a tried implementujúcich UserDetail rozhranie a pridávanie úložísk do nášho projektu.

Nevýhodou je samozrejme malá flexibilita, ktorú ponúka, keď sa naša databáza alebo naša logika líši od predvolenej stratégie poskytované riešením jarnej bezpečnosti.

Na záver sa môžeme pozrieť na úplné príklady v našom úložisku GitHub. Zahrnuli sme dokonca príklad používajúci PostgreSQL, ktorý sme v tomto tutoriáli neukázali, len kvôli zjednodušeniu.

Perzistencia dno

Práve som oznámil nové Naučte sa jar kurz zameraný na základy jari 5 a Spring Boot 2:

>> SKONTROLUJTE KURZ

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