Spring Security Kerberos-integratie met MiniKdc

Beveiliging Top

Ik heb zojuist de nieuwe Learn Spring Security-cursus aangekondigd, inclusief het volledige materiaal gericht op de nieuwe OAuth2-stack in Spring Security 5:

>> BEKIJK DE CURSUS

1. Overzicht

In deze tutorial geven we een overzicht van Spring Security Kerberos.

We schrijven een Kerberos-client in Java die zichzelf autoriseert om toegang te krijgen tot onze Kerberized-service. En we zullen ons eigen embedded Key Distribution Center runnen om volledige, end-to-end Kerberos-authenticatie uit te voeren. Dat alles, zonder enige externe infrastructuur die nodig is dankzij Spring Security Kerberos.

2. Kerberos en zijn voordelen

Kerberos is een netwerkauthenticatieprotocol dat MIT in de jaren tachtig heeft gemaakt, met name handig voor het centraliseren van authenticatie op een netwerk.

In 1987 bracht MIT het uit aan de Open Source-gemeenschap en het is nog steeds in actieve ontwikkeling. In 2005 werd het heilig verklaard als een IETF-standaard onderRFC 4120.

Meestal is Kerberos gebruikt in zakelijke omgevingen. Daarin beveiligt het de omgeving op een zodanige manier dat de de gebruiker hoeft zich niet afzonderlijk voor elke service te authenticeren. Deze architectonische oplossing staat bekend alsEenmalig inloggen.

Simpel gezegd, Kerberos is een ticketingsysteem. Een gebruiker authenticeert eenmaal en ontvangt een Ticket-verlenend Ticket (TGT). Vervolgens ruilt de netwerkinfrastructuur die TGT in voor servicetickets. Met deze servicetickets kan de gebruiker communiceren met infrastructuurservices, zolang de TGT geldig is, meestal voor een paar uur.

Het is dus geweldig dat de gebruiker zich maar één keer aanmeldt. Maar er is ook een beveiligingsvoordeel: in een dergelijke omgeving kan de het wachtwoord van de gebruiker wordt nooit via het netwerk verzonden. In plaats daarvan gebruikt Kerberos het als een factor om een ​​andere geheime sleutel te genereren die zal worden gebruikt om berichten te versleutelen en te ontsleutelen.

Een ander voordeel is dat we kunnen gebruikers vanaf een centrale plek beheren, zeg er een die wordt ondersteund door LDAP. Daarom, als we een account in onze gecentraliseerde database uitschakelen voor een bepaalde gebruiker, zullen we zijn toegang tot onze infrastructuur intrekken. De beheerders hoeven de toegang dus niet afzonderlijk in elke service in te trekken.

Inleiding tot SPNEGO / Kerberos-verificatie in het voorjaar biedt een diepgaand overzicht van de technologie.

3. Kerberized omgeving

Laten we dus een omgeving maken voor authenticatie met het Kerberos-protocol. De omgeving zal bestaan ​​uit drie afzonderlijke applicaties die tegelijkertijd draaien.

Eerste, we hebben een sleuteldistributiecentrum dat zal fungeren als het authenticatiepunt. Vervolgens zullen we een client en een servicetoepassing schrijven die we zullen configureren om het Kerberos-protocol te gebruiken.

Nu vereist het draaien van Kerberos een beetje installatie en configuratie. We maken echter gebruik van Spring Security Kerberos, dus we voeren het Key Distribution Center programmatisch uit, in embedded modus. Ook de MiniKdc hieronder weergegeven is handig in het geval van integratietests met een Kerberized-infrastructuur.

3.1. Een sleuteldistributiecentrum runnen

Eerst lanceren we ons sleuteldistributiecentrum, dat de TGT's voor ons zal uitgeven:

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

Kortom, we hebben gegeven MiniKdc een set van principals en een configuratiebestand; bovendien hebben we het verteld MiniKdc hoe te noemen keytab het genereert.

MiniKdc zal een krb5.conf bestand dat we aan onze klant- en servicetoepassingen leveren. Dit bestand bevat de informatie waar we onze KDC kunnen vinden - de host en poort voor een bepaald domein.

MiniKdc. Hoofd start de KDC en zou iets moeten uitvoeren als:

Standalone MiniKdc actief ----------------------------------------------- ---- Realm: EXAMPLE.COM Draait op: localhost: localhost krb5conf:. \ Spring-security-sso \ spring-security-sso-kerberos \ krb-test-workdir \ krb5.conf gemaakt keytab:. \ Spring-security -sso \ spring-security-sso-kerberos \ krb-test-workdir \ example.keytab met principals: [client / localhost, HTTP / localhost]

3.2. Client-applicatie

Onze klant zal een Spring Boot-applicatie zijn die een RestTemplate om een ​​externe REST API aan te roepen.

Maar we gaan wel gebruik KerberosRestTemplate in plaats daarvan. Het heeft de keytab en de opdrachtgever nodig:

@Configuration publieke klasse KerberosConfig {@Value ("$ {app.user-principal: client / localhost}") private String-principal; @Value ("$ {app.keytab-location}") private String keytabLocation; @Bean openbare RestTemplate restTemplate () {retourneer nieuwe KerberosRestTemplate (keytabLocation, principal); }}

En dat is het! KerberosRestTemplate onderhandelt voor ons over de clientzijde van het Kerberos-protocol.

Laten we dus een snelle klasse maken die gegevens opvraagt ​​van een Kerberized-service, gehost op het eindpunt app.access-url:

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

Dus laten we nu onze servicetoepassing maken, zodat deze klas iets te bellen heeft!

3.3. Servicetoepassing

We gebruiken Spring Security en configureren het met de juiste Kerberos-specifieke bonen.

Merk ook op dat de service zijn principal heeft en ook de keytab gebruikt:

@Configuration @EnableWebSecurity openbare klasse WebSecurityConfig breidt WebSecurityConfigurerAdapter {@Value ("$ {app.service-principal: HTTP / localhost}") private String servicePrincipal uit; @Value ("$ {app.keytab-location}") private String keytabLocation; @Override protected void configure (HttpSecurity http) genereert uitzondering {http .authorizeRequests () .antMatchers ("/", "/ home"). AllowAll () .anyRequest (). Authenticated () .and () .exceptionHandling (). authenticationEntryPoint (spnegoEntryPoint ()) .and () .formLogin () .loginPage ("/ login"). allowAll () .and () .logout (). allowAll () .and () .addFilterBefore (spnegoAuthenticationProcessingFilter (authenticationManagerBean () ), BasicAuthenticationFilter.class); } @Override beschermde ongeldige configuratie (AuthenticationManagerBuilder auth) genereert Uitzondering {auth .authenticationProvider (kerberosAuthenticationProvider ()) .authenticationProvider (kerberosServiceAuthenticationProvider ()); } @Bean openbare KerberosAuthenticationProvider kerberosAuthenticationProvider () {KerberosAuthenticationProvider provider = nieuwe KerberosAuthenticationProvider (); // provider configuratie retour provider; } @Bean public SpnegoEntryPoint spnegoEntryPoint () {retourneer nieuwe SpnegoEntryPoint ("/ login"); } @Bean openbaar SpnegoAuthenticationProcessingFilter spnegoAuthenticationProcessingFilter (AuthenticationManager authenticationManager) {SpnegoAuthenticationProcessingFilter filter = nieuw SpnegoAuthenticationProcessingFilter (); // filterconfiguratie retourfilter; } @Bean openbare KerberosServiceAuthenticationProvider kerberosServiceAuthenticationProvider () {KerberosServiceAuthenticationProvider provider = nieuwe KerberosServiceAuthenticationProvider (); // auth provider configuratie retour provider; } @Bean openbaar SunJaasKerberosTicketValidator sunJaasKerberosTicketValidator () {SunJaasKerberosTicketValidator ticketValidator = nieuw SunJaasKerberosTicketValidator (); // validator configuratie retour ticketValidator; }}

Merk op dat we Spring Security hebben geconfigureerd voor SPNEGO-authenticatie. Op deze manier kunnen we authenticeren via het HTTP-protocol, maar we kunnen ook SPNEGO-authenticatie bereiken met core Java.

4. Testen

Nu zullen we een integratietest uitvoeren om dat te laten zien onze client haalt met succes gegevens op van een externe server via het Kerberos-protocol. Om deze test uit te voeren, hebben we onze infrastructuur nodig, dus MiniKdc en onze servicetoepassing moeten beide worden gestart.

In principe gebruiken we onze SampleClient van de Klantentoepassing om een ​​verzoek in te dienen bij onze Servicetoepassing. Laten we het uittesten:

@Autowired privé SampleClient sampleClient; @Test openbare ongeldig gegevenKerberizedRestTemplate_whenServiceCall_thenSuccess () {assertEquals ("gegevens van verharde server", sampleClient.getData ()); }

Merk op dat we ook kunnen bewijzen dat de KerberizedRestTemplate is belangrijk door de service zonder te raken:

@Test openbare ongeldig gegevenRestTemplate_whenServiceCall_thenFail () {sampleClient.setRestTemplate (nieuwe RestTemplate ()); assertThrows (RestClientException.class, sampleClient :: getData); }

Als een kanttekening: er is een kans onze tweede test zou het ticket kunnen hergebruiken dat al in de referentiecache is opgeslagen. Dit zou gebeuren vanwege de automatische SPNEGO-onderhandeling die wordt gebruikt in HttpUrlConnection.

Als resultaat, de gegevens kunnen daadwerkelijk terugkeren, waardoor onze test ongeldig wordt. Afhankelijk van onze behoeften kunnen we het gebruik van ticketcache uitschakelen via de systeemeigenschap http.use.global.creds = false.

5. Conclusie

In deze tutorial we hebben Kerberos onderzocht voor gecentraliseerd gebruikersbeheer en hoe Spring Security het Kerberos-protocol en het SPNEGO-verificatiemechanisme ondersteunt.

We gebruikten MiniKdc om een ​​embedded KDC op te zetten en ook een zeer eenvoudige Kerberized client en server te creëren. Deze opzet was handig voor verkenning en vooral handig toen we een integratietest maakten om dingen uit te testen.

Nu hebben we zojuist het oppervlak bekrast. Om dieper te duiken, ga je naar de Kerberos-wikipagina of de bijbehorende RFC. Ook zal de officiële documentatiepagina nuttig zijn. Anders dan dat, om te zien hoe de dingen kunnen worden gedaan in core java, toont de volgende Oracle-tutorial het in details.

Zoals gewoonlijk is de code te vinden op onze GitHub-pagina.

Beveiligingsbodem

Ik heb zojuist de nieuwe Learn Spring Security-cursus aangekondigd, inclusief het volledige materiaal gericht op de nieuwe OAuth2-stack in Spring Security 5:

>> BEKIJK DE CURSUS