Vårsikkerhet Kerberos-integrasjon med MiniKdc

Sikkerhetstopp

Jeg kunngjorde nettopp det nye Learn Spring Security-kurset, inkludert hele materialet med fokus på den nye OAuth2-stakken i Spring Security 5:

>> KONTROLLER KURSET

1. Oversikt

I denne veiledningen gir vi en oversikt over Spring Security Kerberos.

Vi skriver en Kerberos-klient på Java som autoriserer seg selv til å få tilgang til Kerberized-tjenesten vår. Og vi kjører vårt eget innebygde Key Distribution Center for å utføre fullstendig Kerberos-autentisering. Alt dette uten ekstern infrastruktur som kreves takket være Spring Security Kerberos.

2. Kerberos og fordelene

Kerberos er en nettverksautentiseringsprotokoll som MIT opprettet på 1980-tallet, spesielt nyttig for sentralisering av autentisering i et nettverk.

I 1987 ga MIT den ut til Open Source-fellesskapet, og den er fortsatt under aktiv utvikling. I 2005 ble den kanonisert som en IETF-standard underRFC 4120.

Vanligvis er Kerberos det brukes i bedriftsmiljøer. Der inne sikrer det miljøet på en slik måte at brukeren trenger ikke å godkjenne hver tjeneste hver for seg. Denne arkitektoniske løsningen er kjent somEnkelt pålogging.

Enkelt sagt, Kerberos er et billettsystem. En bruker autentiserer en gang og mottar en billett som gir billett (TGT). Deretter bytter nettverksinfrastrukturen den TGT-en mot servicebilletter. Disse tjenestebillettene tillater brukeren å samhandle med infrastrukturtjenester, så lenge TGT er gyldig, som vanligvis varer i et par timer.

Så det er flott at brukeren bare logger på en gang. Men det er også en sikkerhetsfordel: I et slikt miljø, brukerens passord blir aldri sendt over nettverket. I stedet bruker Kerberos det som en faktor for å generere en annen hemmelig nøkkel som skal brukes til å kryptere og dekryptere meldinger.

En annen fordel er at vi kan administrere brukere fra et sentralt sted, si en som er støttet av LDAP. Derfor, hvis vi deaktiverer en konto i vår sentraliserte database for en gitt bruker, vil vi tilbakekalle tilgangen til infrastrukturen vår. Dermed trenger ikke administratorene å tilbakekalle tilgangen separat i hver tjeneste.

Introduksjon til SPNEGO / Kerberos Authentication in Spring gir en grundig oversikt over teknologien.

3. Kerberisert miljø

Så la oss lage et miljø for autentisering med Kerberos-protokollen. Miljøet vil bestå av tre separate applikasjoner som vil kjøre samtidig.

Først, vi har et nøkkeldistribusjonssenter som vil fungere som godkjenningspunkt. Deretter skriver vi en klient og et tjenesteapplikasjon som vi konfigurerer til å bruke Kerberos-protokollen.

Nå krever kjøring av Kerberos litt installasjon og konfigurasjon. Imidlertid vil vi utnytte Spring Security Kerberos, så vi kjører Key Distribution Center programmatisk, i innebygd modus. Også, den MiniKdc vist nedenfor er nyttig i tilfelle integrasjonstesting med Kerberized infrastruktur.

3.1. Kjører et sentralt distribusjonssenter

Først lanserer vi vårt Key Distribution Center, som vil utstede TGT-ene for oss:

Streng [] config = MiniKdcConfigBuilder.builder () .workDir (prepareWorkDir ()) .principals ("client / localhost", "HTTP / localhost") .confDir ("minikdc-krb5.conf") .keytabName ("example.keytab ") .bygge(); MiniKdc.main (config);

I utgangspunktet har vi gitt MiniKdc et sett med rektorer og en konfigurasjonsfil; i tillegg har vi fortalt MiniKdc hva du skal kalle tastaturfane det genererer.

MiniKdc vil generere en krb5.conf fil som vi leverer til våre klient- og tjenesteapplikasjoner. Denne filen inneholder informasjonen hvor du finner KDC - verten og porten for et gitt rike.

MiniKdc.hoved starter KDC og skal sende ut noe sånt som:

Frittstående MiniKdc Running ----------------------------------------------- ---- Rike: EXAMPLE.COM Kjører på: localhost: localhost krb5conf:. \ Spring-security-sso \ spring-security-sso-kerberos \ krb-test-workdir \ krb5.conf opprettet tastaturfelt:. \ Spring-security -sso \ spring-security-sso-kerberos \ krb-test-workdir \ example.keytab med prinsipaler: [client / localhost, HTTP / localhost]

3.2. Kundesøknad

Vår klient vil være en Spring Boot-applikasjon som bruker en RestTemplate for å ringe til eksternt et REST API.

Men vi skal bruk KerberosRestTemplate i stedet. Det trenger tastaturfanen og klientens rektor:

@Configuration public class KerberosConfig {@Value ("$ {app.user-principal: client / localhost}") private streng rektor; @Value ("$ {app.keytab-location}") privat streng keytabLocation; @Bean public RestTemplate restTemplate () {returner nye KerberosRestTemplate (keytabLocation, rektor); }}

Og det er det! KerberosRestTemplate forhandler klientsiden av Kerberos-protokollen for oss.

Så la oss lage en rask klasse som vil spørre om data fra en Kerberized-tjeneste, vert på endepunktet app.access-url:

@Service class SampleClient {@Value ("$ {app.access-url}") private String endpoint; private RestTemplate restTemplate; // constructor, getter, setter String getData () {return restTemplate.getForObject (endpoint, String.class); }}

Så la oss lage vår tjenesteapplikasjon nå slik at denne klassen har noe å ringe!

3.3. Serviceapplikasjon

Vi bruker Spring Security og konfigurerer den med passende Kerberos-spesifikke bønner.

Vær også oppmerksom på at tjenesten vil ha sin prinsipp og bruke tastaturfanen også:

@Configuration @EnableWebSecurity offentlig klasse WebSecurityConfig utvider WebSecurityConfigurerAdapter {@Value ("$ {app.service-principal: HTTP / localhost}") private streng servicePrincipal; @Value ("$ {app.keytab-location}") privat streng keytabLocation; @ Override beskyttet ugyldig konfigurering (HttpSecurity http) kaster Unntak {http .authorizeRequests () .antMatchers ("/", "/ home"). PermitAll () .anyRequest (). Autentisert (). Og () .exceptionHandling (). authenticationEntryPoint (spnegoEntryPoint ()). og () .formLogin () .loginPage ("/ login"). permitAll () .and () .logout (). permitAll () .and () .addFilterBefore (spnegoAuthenticationProcessingFilter (authenticationManagerBean) ), BasicAuthenticationFilter.class); } @ Override beskyttet ugyldig konfigurasjon (AuthenticationManagerBuilder auth) kaster Unntak {auth .authenticationProvider (kerberosAuthenticationProvider ()) .authenticationProvider (kerberosServiceAuthenticationProvider ()); } @Bean public KerberosAuthenticationProvider kerberosAuthenticationProvider () {KerberosAuthenticationProvider provider = new KerberosAuthenticationProvider (); // leverandørkonfigurasjonsreturleverandør; } @Bean public SpnegoEntryPoint spnegoEntryPoint () {return new SpnegoEntryPoint ("/ login"); } @Bean public SpnegoAuthenticationProcessingFilter spnegoAuthenticationProcessingFilter (AuthenticationManager authenticationManager) {SpnegoAuthenticationProcessingFilter filter = new SpnegoAuthenticationProcessingFilter (); // returfilter for filterkonfigurasjon; } @Bean public KerberosServiceAuthenticationProvider kerberosServiceAuthenticationProvider () {KerberosServiceAuthenticationProvider provider = new KerberosServiceAuthenticationProvider (); // leverandør av konfigurering av autentleverandør; } @Bean public SunJaasKerberosTicketValidator sunJaasKerberosTicketValidator () {SunJaasKerberosTicketValidator ticketValidator = new SunJaasKerberosTicketValidator (); // validatorkonfigurasjon returbillettValidator; }}

Merk at vi har konfigurert Spring Security for SPNEGO-autentisering. På denne måten vil vi kunne autentisere gjennom HTTP-protokollen, selv om vi også kan oppnå SPNEGO-autentisering med kjernen Java.

4. Testing

Nå skal vi kjøre en integrasjonstest for å vise det klienten henter vellykket data fra en ekstern server over Kerberos-protokollen. For å kjøre denne testen, må vi ha infrastrukturen vår i gang MiniKdc og vår tjenestesøknad må begge startes.

I utgangspunktet vil vi bruke vår SampleClient fra klientapplikasjonen for å gjøre en forespørsel til tjenesteapplikasjonen vår. La oss teste det ut:

@Autowired private SampleClient sampleClient; @Test public void givenKerberizedRestTemplate_whenServiceCall_thenSuccess () {assertEquals ("data from kerberized server", sampleClient.getData ()); }

Merk at vi også kan bevise at KerberizedRestTemplate er viktig ved å trykke på tjenesten uten den:

@Test offentlig ugyldig gittRestTemplate_whenServiceCall_thenFail () {sampleClient.setRestTemplate (ny RestTemplate ()); assertThrows (RestClientException.class, sampleClient :: getData); }

Som en sidemerknad er det en sjanse vår andre test kan gjenbruke billetten som allerede er lagret i legitimasjonsbufferen. Dette ville skje på grunn av den automatiske SPNEGO-forhandlingen som ble brukt i HttpUrlConnection.

Som et resultat, dataene kan faktisk komme tilbake, og ugyldiggjøre testen vår. Avhengig av våre behov kan vi derfor deaktivere bruk av billettbuffer gjennom systemegenskapen http.use.global.creds = usann.

5. Konklusjon

I denne veiledningen, vi utforsket Kerberos for sentralisert brukeradministrasjon og hvordan Spring Security støtter Kerberos-protokollen og SPNEGO-autentiseringsmekanismen.

Vi brukte MiniKdc å stå opp en innebygd KDC og opprettet også en veldig enkel Kerberized klient og server. Dette oppsettet var praktisk for leting og spesielt praktisk når vi opprettet en integrasjonstest for å teste ting ut.

Nå har vi bare skrapet overflaten. For å dykke dypere, sjekk ut Kerberos wiki-siden eller dens RFC. Den offisielle dokumentasjonssiden vil også være nyttig. Annet enn det, for å se hvordan ting kan gjøres i core java, viser følgende Oracle-opplæring det i detaljer.

Som vanlig kan koden bli funnet på GitHub-siden vår.

Sikkerhetsbunn

Jeg kunngjorde nettopp det nye Learn Spring Security-kurset, inkludert hele materialet med fokus på den nye OAuth2-stakken i Spring Security 5:

>> KONTROLLER KURSET

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