Introducere în autentificarea SPNEGO / Kerberos în primăvară

1. Prezentare generală

În acest tutorial, vom înțelege elementele de bază ale protocolului de autentificare Kerberos. De asemenea, vom acoperi nevoia de SPNEGO în legătură cu Kerberos.

În cele din urmă, vom vedea cum să folosim extensia Spring Security Kerberos pentru a crea aplicații activate pentru Kerberos cu SPNEGO.

Înainte de a continua, merită să menționăm că acest tutorial va introduce mulți termeni noi pentru cei neinițiați în acest domeniu. Prin urmare, vom petrece ceva timp în față pentru a acoperi terenul.

2. Înțelegerea Kerberos

Kerberos este un protocol de autentificare a rețelei dezvoltat la Massachusetts Institute of Technology (MIT) la începutul anilor optzeci. După cum vă puteți da seama, acest lucru este relativ vechi și a rezistat testului timpului. Windows Server acceptă pe scară largă Kerberos ca mecanism de autentificare și chiar a făcut din acesta opțiunea de autentificare implicită.

Din punct de vedere tehnic, Kerberos este un protocol de autentificare bazat pe bilete care permite nodurilor dintr-o rețea de calculatoare să se identifice între ele.

2.1. Caz de utilizare simplu pentru Kerberos

Să întocmim o situație ipotetică pentru a demonstra acest lucru.

Să presupunem că un utilizator, prin intermediul clientului său de e-mail de pe echipamentul său, trebuie să-și extragă e-mailurile de pe un server de e-mail de pe un alt echipament din aceeași rețea. Aici este o nevoie evidentă de autentificare. Clientul de e-mail și serverul de e-mail trebuie să fie capabili să se identifice și să aibă încredere reciprocă pentru ca aceștia să comunice în siguranță.

Cum ne poate ajuta Kerberos aici? Kerberos introduce un terț numit Key Distribution Center (KDC) , care are o încredere reciprocă cu fiecare nod din rețea. Să vedem cum poate funcționa acest lucru în cazul nostru:

2.2. Aspecte cheie ale Protocolului Kerberos

Deși acest lucru poate părea ezoteric, acest lucru este destul de simplu și creativ în asigurarea comunicării printr-o rețea nesecurizată. Unele dintre problemele prezentate aici sunt destul de luate de la sine în era TLS peste tot!

Deși o discuție detaliată a Protocolului Kerberos nu este posibilă aici, să trecem prin câteva aspecte importante:

  • Se presupune că încrederea dintre noduri (client și server) și KDC există aici pe același tărâm
  • Parola nu este schimbată niciodată prin rețea
  • Încrederea dintre client și server este implicată pe baza faptului că aceștia pot decripta mesajele cu o cheie partajată numai cu KDC
  • Încrederea dintre client și server este reciprocă
  • Clientul poate memora în memorie bilete pentru utilizare repetată până la expirare, oferind o singură experiență de conectare
  • Mesajele de autentificare se bazează pe marcajul de timp și, prin urmare, sunt bune numai pentru o singură utilizare
  • Toate cele trei părți de aici trebuie să aibă un timp relativ sincronizat

În timp ce acest lucru doar zgârie suprafața acestui frumos protocol de autentificare, este suficient să ne dăm drumul cu tutorialul nostru.

3. Înțelegerea SPNEGO

SPNEGO înseamnă Mecanism de negociere GSS-API simplu și protejat. Un nume destul de mare! Să vedem mai întâi ce înseamnă GSS-API. Interfața programului de aplicație pentru serviciul de securitate generic (GSS-API) nu este altceva decât un standard IETF pentru ca clientul și serverul să comunice într-o manieră sigură și agnostică a furnizorului.

SPNEGO face parte din GSS-API pentru ca clientul și serverul să negocieze alegerea mecanismului de securitate pe care să îl folosească, de exemplu, Kerberos sau NTLM.

4. De ce avem nevoie de SPNEGO cu Kerberos?

După cum am văzut în secțiunea anterioară, Kerberos este un protocol pur de autentificare a rețelei care funcționează în principal în stratul de transport (TCP / UDP). Deși acest lucru este bun pentru multe cazuri de utilizare, acest lucru nu corespunde cerințelor pentru web-ul modern. Dacă avem o aplicație care funcționează pe o abstracție mai mare, cum ar fi HTTP, nu este posibil să folosim Kerberos direct.

Aici SPNEGO vine în ajutorul nostru. În cazul unei aplicații web, comunicarea are loc în principal între un browser web precum Chrome și un server web precum Tomcat care găzduiește aplicația web prin HTTP. Dacă este activat, pot negocia Kerberos ca mecanism de securitate prin SPNEGO și pot schimba bilete ca jetoane SPNEGO prin HTTP .

Deci, cum schimbă acest lucru scenariul nostru menționat anterior? Să înlocuim clientul nostru simplu de e-mail cu un browser web și serverul de e-mail cu o aplicație web:

Deci, nu s-au schimbat multe în acest sens în comparație cu diagrama noastră anterioară, cu excepția faptului că comunicarea dintre client și server se întâmplă explicit prin HTTP acum. Să înțelegem mai bine acest lucru:

  • Mașina client se autentifică împotriva KDC și memorează în cache TGT
  • Browserul web de pe computerul clientului este configurat pentru a utiliza SPNEGO și Kerberos
  • Aplicația web este, de asemenea, configurată pentru a sprijini SPNEGO și Kerberos
  • Aplicația web lansează o provocare „Negociați” browserului web care încearcă să acceseze o resursă protejată
  • Biletul de serviciu este înfășurat ca jeton SPNEGO și schimbat ca antet HTTP

5. Cerințe

Înainte de a putea continua să dezvoltăm o aplicație web care acceptă modul de autentificare Kerberos, trebuie să adunăm câteva setări de bază. Să parcurgem rapid aceste sarcini.

5.1. Configurarea KDC

Configurarea unui mediu Kerberos pentru producție nu depășește sfera acestui tutorial. Din păcate, aceasta nu este o sarcină banală și, de asemenea, fragilă. Există mai multe opțiuni disponibile pentru a obține o implementare a Kerberos, atât versiunea open source, cât și versiunile comerciale:

  • MIT pune la dispoziție implementarea Kerberos v5 pentru mai multe sisteme de operare
  • Apache Kerby este o extensie pentru Apache Directory, care oferă o legare Java Kerberos
  • Windows Server de la Microsoft acceptă Kerberos v5 susținut nativ de Active Directory
  • Heimdel are o implementare a Kerberos v5

The actual set-up of KDC and related infrastructure is dependent on the provider and should be followed from their respective documentation. However, Apache Kerby can be run inside a Docker container, which makes it platform-neutral.

5.2. Setting up Users in KDC

We need to set up two users — or, as they call it, principals — in KDC. We can use the “kadmin” command-line tool for this purpose. Let's suppose we've created a realm called “baeldung.com” in the KDC database and logged in to “kadmin” with a user having admin privileges.

We'll create our first user, whom we wish to authenticate from a web browser, with:

$ kadmin: addprinc -randkey kchandrakant -pw password Principal "[email protected]" created.

We'll also need to register our web application with the KDC:

$ kadmin: addprinc -randkey HTTP/[email protected] -pw password Principal "HTTP/[email protected]" created.

Note the convention for naming the principal here, as this must match the domain on which the application is accessible from the web browser. The web browser automatically tries to create a Service Principal Name (SPN) with this convention when presented with a “Negotiate” challenge.

We also need to export this as a keytab file to make it available to the web application:

$ kadmin: ktadd -k baeldung.keytab HTTP/[email protected]

This should give us a file named “baeldung.keytab”.

5.3. Browser Configuration

We need to enable the web browser that we use to access a protected resource on the web application for the “Negotiate” authentication scheme. Fortunately, most of the modern web browsers like Chrome support “Negotiate” as an authentication scheme by default.

Additionally, we can configure the browser to provide “Integrated Authentication”. In this mode, when presented with the “Negotiate” challenge, the browser tries to make use of the cached credentials in the host machine, which has already been logged into a KDC principal. However, we'll not use this mode in here to keep things explicit.

5.4. Domain Configuration

It is understandable that we may not have actual domains to test our web application. But sadly, we can't use localhost or 127.0.0.1 or any other IP address with Kerberos authentication. There is, however, an easy solution to this, which involves setting up entries in the “hosts” file like:

demo.kerberos.bealdung.com 127.0.0.1

6. Spring to Our Rescue!

Finally, as we've got the basics clear, it is time to test the theory. But, won't it be cumbersome to create a web application supporting SPNEGO and Kerberos? Not if we use Spring. Spring has a Kerberos Extension as part of Spring Security that supports SPNEGO with Kerberos seamlessly.

Almost all we have to do is just configurations in Spring Security to enable SPNEGO with Kerberos. We'll use Java-style configurations here, but an XML configuration can be set up as easily. We can extend the WebSecurityConfigurerAdapter class to configure all we need.

6.1. Maven Dependencies

The first thing we have to set up are the dependencies:

 org.springframework.security.kerberos spring-security-kerberos-web ${kerberos.extension.version}   org.springframework.security.kerberos spring-security-kerberos-client ${kerberos.extension.version} 

These dependencies are available for download from Maven Central.

6.2. SPNEGO Configurations

Firstly, SPNEGO is integrated into Spring Security as a Filter in HTTPSecurity:

@Override protected void configure(HttpSecurity http) throws Exception { http.authorizeRequests() .anyRequest() .authenticated() .and() .addFilterBefore( spnegoAuthenticationProcessingFilter(authenticationManagerBean()), BasicAuthenticationFilter.class); }

This only shows the part required to configure SPNEGO Filter and is not a complete HTTPSecurity configuration, which should be configured as per application security requirements.

Next, we need to provide the SPNEGO Filter as Bean:

@Bean public SpnegoAuthenticationProcessingFilter spnegoAuthenticationProcessingFilter( AuthenticationManager authenticationManager) { SpnegoAuthenticationProcessingFilter filter = new SpnegoAuthenticationProcessingFilter(); filter.setAuthenticationManager(authenticationManager); return filter; }

6.3. Kerberos Configurations

In addition, We can configure Kerberos by adding AuthenticationProvider to AuthenticationManagerBuilder in Spring Security:

@Override protected void configure(AuthenticationManagerBuilder auth) throws Exception { auth .authenticationProvider(kerberosAuthenticationProvider()) .authenticationProvider(kerberosServiceAuthenticationProvider()); }

The first thing we have to provide is a KerberosAuthenticationProvider as a Bean. This is an implementation of AuthenticationProvider, and this is where we set SunJaasKerberosClient as a KerberosClient:

@Bean public KerberosAuthenticationProvider kerberosAuthenticationProvider() { KerberosAuthenticationProvider provider = new KerberosAuthenticationProvider(); SunJaasKerberosClient client = new SunJaasKerberosClient(); provider.setKerberosClient(client); provider.setUserDetailsService(userDetailsService()); return provider; }

Next, we also have to provide a KerberosServiceAuthenticationProvider as a Bean. This is the class that validates Kerberos Service Tickets or SPNEGO Tokens:

@Bean public KerberosServiceAuthenticationProvider kerberosServiceAuthenticationProvider() { KerberosServiceAuthenticationProvider provider = new KerberosServiceAuthenticationProvider(); provider.setTicketValidator(sunJaasKerberosTicketValidator()); provider.setUserDetailsService(userDetailsService()); return provider; }

Lastly, we need to provide a SunJaasKerberosTicketValidator as a Bean. This is an implementation of KerberosTicketValidator and uses SUN JAAS Login Module:

@Bean public SunJaasKerberosTicketValidator sunJaasKerberosTicketValidator() { SunJaasKerberosTicketValidator ticketValidator = new SunJaasKerberosTicketValidator(); ticketValidator.setServicePrincipal("HTTP/[email protected]"); ticketValidator.setKeyTabLocation(new FileSystemResource("baeldung.keytab")); return ticketValidator; }

6.4. User Details

We've seen references to a UserDetailsService in our AuthenticationProvider earlier, so why do we need it? Well, as we've come to know Kerberos, it is purely an authentication mechanism that is ticket-based.

So, while it's able to identify the user, it doesn't provide other details related to the user, like their authorizations. We need a valid UserDetailsService provided to our AuthenticationProvider to fill this gap.

6.5. Running the Application

This is pretty much what we need to set up a web application with Spring Security enabled for SPNEGO with Kerberos. When we boot up the web application and access any page therein, the web browser should prompt for username and password, prepare a SPNEGO token with Service Ticket, and send it to the application.

The application should be able to process it using the credentials in the keytab file and respond with successful authentication.

However, as we saw earlier, setting up a working Kerberos environment is complicated and quite brittle. If things don't work as expected, it's worthwhile to check all the steps again. A simple mistake like mismatch in the domain name can lead to failure with error messages that aren't particularly helpful.

7. Practical Use of SPNEGO and Kerberos

Now that we've seen how Kerberos authentication works and how we can use SPNEGO with Kerberos in web applications, we may question the need for it. While this makes complete sense to use it as an SSO mechanism within an enterprise network, why should we use this in web applications?

Well, for one, even after so many years, Kerberos is still very actively used within enterprise applications, especially Windows-based applications. If an organization has several internal and external web applications, it does make sense to extend the same SSO infrastructure to cover them all. This makes it much easier for administrators and users of an organization to have a seamless experience through disparate applications.

8. Conclusion

Pentru a rezuma, în acest tutorial, am înțeles elementele de bază ale protocolului de autentificare Kerberos. De asemenea, am discutat despre SPNEGO ca parte a GSS-API și despre modul în care îl putem folosi pentru a facilita autentificarea bazată pe Kerberos într-o aplicație web prin HTTP. Mai mult, am încercat să construim o mică aplicație web, folosind suportul încorporat Spring Security pentru SPNEGO cu Kerberos.

Acest tutorial oferă doar o scurtă privire asupra unui mecanism de autentificare puternic și testat în timp. Există o mulțime de informații disponibile pentru a afla mai multe și, eventual, a aprecia chiar mai mult!

Ca întotdeauna, codul poate fi găsit pe GitHub.