En introduksjon til Java SASL

Java Top

Jeg kunngjorde nettopp det nye Lær våren kurs, med fokus på det grunnleggende i vår 5 og vårstøvel 2:

>> KONTROLLER KURSET

1. Oversikt

I denne opplæringen vil vi gå gjennom det grunnleggende om Simple Authentication and Security Layer (SASL). Vi forstår hvordan Java støtter adopsjon av SASL for å sikre kommunikasjon.

I prosessen vil vi bruke enkel klient- og serverkommunikasjon, og sikre den med SASL.

2. Hva er? SASL?

SASL er et rammeverk for autentisering og datasikkerhet i internettprotokoller. Det tar sikte på å koble internettprotokoller fra spesifikke autentiseringsmekanismer. Vi vil bedre forstå deler av denne definisjonen når vi går videre.

Behovet for sikkerhet i kommunikasjonen er implisitt. La oss prøve å forstå dette i sammenheng med klient- og serverkommunikasjon. Vanligvis utveksler klient og server data over nettverket. Det er viktig at begge parter kan stole på hverandre og sende data sikkert.

2.1. Hvor gjør SASL Passe inn?

I et program kan vi bruke SMTP til å sende e-post og bruke LDAP for å få tilgang til katalogtjenester. Men hver av disse protokollene støtter kanskje en annen autentiseringsmekanisme, som Digest-MD5 eller Kerberos.

Hva om det var en måte for protokoller å bytte autentiseringsmekanismer mer erklærende på? Det er akkurat her SASL kommer inn i bildet. Protokoller som støtter SASL kan alltid støtte noen av SASL-mekanismene.

Derfor, applikasjoner kan forhandle om en passende mekanisme og vedta det for autentisering og sikker kommunikasjon.

2.2. Hvordan gjør SASL Arbeid?

Nå som vi har sett hvor SASL passer inn i den generelle sikkerhetsplanen, la oss forstå hvordan det fungerer.

SASL er et rammeverk for utfordringsrespons. Her utsteder serveren en utfordring til klienten, og klienten sender et svar basert på utfordringen. Utfordringen og responsen er byte-arrays av vilkårlig lengde og kan derfor bære mekanismespesifikke data.

Dette utveksling kan fortsette for flere iterasjoner og til slutt avsluttes når serveren ikke gir noen ytterligere utfordring.

Videre kan klienten og serveren forhandle om et sikkerhetslag etter godkjenning. All etterfølgende kommunikasjon kan da utnytte dette sikkerhetslaget. Vær imidlertid oppmerksom på at noen av mekanismene bare støtter autentisering.

Det er viktig å forstå her at SASL gir bare et rammeverk for utveksling av utfordring og respons data. Det nevner ikke noe om selve dataene eller hvordan de utveksles. Disse detaljene er igjen for applikasjonene som bruker SASL.

3. SASL-støtte i Java

Det er APIer i Java som støtte utvikling av både applikasjoner på klientsiden og serversiden med SASL. API-en er ikke avhengig av selve mekanismene. Programmer som bruker Java SASL API kan velge en mekanisme basert på nødvendige sikkerhetsfunksjoner.

3.1. Java SASL API

Nøkkelgrensesnittene å merke, som en del av pakken “javax.security.sasl”, er SaslServer og SaslClient.

SaslServer representerer server-mekanismen til SASL.

La oss se hvordan vi kan instantiere en SaslServer:

SaslServer ss = Sasl.createSaslServer (mekanisme, protokoll, servernavn, rekvisitter, callbackHandler);

Vi bruker fabrikklassen Sasl å instansiere SaslServer. Metoden createSaslServer godtar flere parametere:

  • mekanisme - det IANA-registrerte navnet på en SASL-støttet mekanisme
  • protokoll - navnet på protokollen som autentisering gjøres for
  • Server navn - det fullt kvalifiserte vertsnavnet til serveren
  • Rekvisitter - et sett med egenskaper som brukes til å konfigurere autentiseringsutvekslingen
  • tilbakeringingHandler - en tilbakeringingsbehandler som skal brukes av den valgte mekanismen for å få ytterligere informasjon

Av de ovennevnte er bare de to første obligatoriske, og resten er ugyldige.

SaslClient representerer klientsidesmekanismen til SASL. La oss se hvordan vi kan instantiere en SaslClient:

SaslClient sc = Sasl.createSaslClient (mekanismer, autorisasjons-ID, protokoll, servernavn, rekvisitter, callbackHandler);

Også her bruker vi fabrikklassen Sasl å instansiere vår SaslClient. Listen over parametere som createSaslClient godtar er stort sett det samme som før.

Imidlertid er det noen subtile forskjeller:

  • mekanismer - her er dette en liste over mekanismer å prøve fra
  • autorisasjonId - dette er en protokollavhengig identifikasjon som skal brukes til autorisasjon

Resten av parametrene har samme betydning og valgfrihet.

3.2. Java SASL sikkerhetsleverandør

Under Java SASL API er de faktiske mekanismene som gir sikkerhetsfunksjonene. De implementering av disse mekanismene er gitt av sikkerhetsleverandører registrert med Java Cryptography Architecture (JCA).

Det kan være flere sikkerhetsleverandører registrert hos JCA. Hver av disse kan støtte en eller flere av SASL-mekanismene.

Java leveres med SunSASL som en sikkerhetsleverandør, som blir registrert som en JCA-leverandør som standard. Dette kan imidlertid fjernes eller bestilles med andre tilgjengelige leverandører.

Dessuten er det alltid mulig å tilby en tilpasset sikkerhetsleverandør. Dette vil kreve at vi implementerer grensesnittene SaslClient og SaslServer. Ved å gjøre dette kan vi også implementere vår tilpassede sikkerhetsmekanisme!

4. SASL gjennom et eksempel

Nå som vi har sett hvordan vi kan lage en SaslServer og en SaslClient, er det på tide å forstå hvordan du bruker dem. Vi skal utvikle klient- og serverkomponenter. Disse vil utveksle utfordring og respons iterativt for å oppnå autentisering. Vi bruker DIGEST-MD5-mekanismen i vårt enkle eksempel her.

4.1. Klient og server CallbackHandler

Som vi så tidligere, må vi gi implementeringer av CallbackHandler til SaslServer og SaslClient. Nå, CallbackHandler er et enkelt grensesnitt som definerer en enkelt metode - håndtak. Denne metoden godtar en rekke Ring tilbake.

Her, Ring tilbake presenterer en måte for sikkerhetsmekanismen å samle autentiseringsdata fra anropsapplikasjonen. For eksempel kan en sikkerhetsmekanisme kreve brukernavn og passord. Det er ganske mange Ring tilbake implementeringer som NameCallback og PasswordCallback tilgjengelig for bruk.

La oss se hvordan vi kan definere en CallbackHandler til serveren, til å begynne med:

public class ServerCallbackHandler implementerer CallbackHandler {@Override public void handle (Callback [] cbs) kaster IOException, UnsupportedCallbackException {for (Callback cb: cbs) {if (cb instanceof AuthorizeCallback) {AuthorizeCallback ac = (AuthorizeCallback) cb; // Utfør applikasjonsspesifikk autorisasjonshandling ac.setAuthorized (true); } annet hvis (cb forekomst av NameCallback) {NameCallback nc = (NameCallback) cb; // Samle brukernavn på applikasjonsspesifikk måte nc.setName ("brukernavn"); } annet hvis (cb forekomst av PasswordCallback) {PasswordCallback pc = (PasswordCallback) cb; // Samle passord på applikasjonsspesifikk måte pc.setPassword ("passord" .toCharArray ()); } annet hvis (cb forekomst av RealmCallback) {RealmCallback rc = (RealmCallback) cb; // Samle inn riksdata på applikasjonsspesifikk måte rc.setText ("myServer"); }}}}

La oss nå se på klientsiden vår av Tilbakebehandler:

offentlig klasse ClientCallbackHandler implementerer CallbackHandler {@Override public void handle (Callback [] cbs) kaster IOException, UnsupportedCallbackException {for (Callback cb: cbs) {if (cb instanceof NameCallback) {NameCallback nc = (NameCallback) cb; // Samle brukernavn på applikasjonsspesifikk måte nc.setName ("brukernavn"); } annet hvis (cb forekomst av PasswordCallback) {PasswordCallback pc = (PasswordCallback) cb; // Samle passord på applikasjonsspesifikk måte pc.setPassword ("passord" .toCharArray ()); } annet hvis (cb forekomst av RealmCallback) {RealmCallback rc = (RealmCallback) cb; // Samle inn riksdata på applikasjonsspesifikk måte rc.setText ("myServer"); }}}}

For å avklare er vi det looping gjennom Ring tilbake array og håndtering bare spesifikke. De som vi må håndtere er spesifikke for mekanismen i bruk, som er DIGEST-MD5 her.

4.2. SASL-godkjenning

Så vi har skrevet klienten og serveren vår CallbackHandler. Vi har også instantiert SaslClient og SaslServer for DIGEST-MD5 mekanisme.

Nå er det på tide å se dem i aksjon:

@Test offentlig ugyldighet gittHandlers_whenStarted_thenAutenticationWorks () kaster SaslException {byte [] utfordring; byte [] respons; utfordring = saslServer.evaluateResponse (ny byte [0]); respons = saslClient.evaluateChallenge (utfordring); utfordring = saslServer.evaluateResponse (respons); respons = saslClient.evaluateChallenge (utfordring); assertTrue (saslServer.isComplete ()); assertTrue (saslClient.isComplete ()); }

La oss prøve å forstå hva som skjer her:

  • Først får klienten vår standardutfordring fra serveren
  • Klienten evaluerer deretter utfordringen og forbereder et svar
  • Denne utfordringen og responsutvekslingen fortsetter i en syklus til
  • I prosessen bruker klienten og serveren tilbakeringingsbehandlere for å samle inn ytterligere data etter behov av mekanismen
  • Dette avslutter vår autentisering her, men i virkeligheten kan den gjentas over flere sykluser

EN typisk utveksling av utfordrings- og responsbyte-arrays skjer over nettverket. Men for enkelhets skyld har vi antatt lokal kommunikasjon.

4.3. SASL Sikker kommunikasjon

Som vi diskuterte tidligere, er SASL et rammeverk som kan støtte sikker kommunikasjon utover bare autentisering. Derimot, dette er bare mulig hvis den underliggende mekanismen støtter det.

La oss først sjekke om vi har vært i stand til å forhandle om en sikker kommunikasjon:

String qop = (String) saslClient.getNegotiatedProperty (Sasl.QOP); assertEquals ("auth-conf", qop);

Her, QOP står for kvaliteten på beskyttelsen. Dette er noe klienten og serveren forhandler under autentisering. Verdien “auth-int” indikerer autentisering og integritet. Mens verdien "auth-conf" indikerer autentisering, integritet og konfidensialitet.

Når vi har et sikkerhetslag, kan vi utnytte det for å sikre kommunikasjonen vår.

La oss se hvordan vi kan sikre utgående kommunikasjon i klienten:

byte [] utgående = "Baeldung" .getBytes (); byte [] secureOutgoing = saslClient.wrap (utgående, 0, utgående.lengde); // Send safeOutgoing til serveren over nettverket

Og på samme måte kan serveren behandle innkommende kommunikasjon:

// Motta sikker innkommende fra klienten via nettverksbyte [] innkommende = saslServer.unwrap (sikker innkommende, 0, netIn.length); assertEquals ("Baeldung", ny streng (innkommende, StandardCharsets.UTF_8));

5. SASL i den virkelige verden

Så vi har nå en god forståelse av hva SASL er og hvordan vi bruker det i Java. Men det er vanligvis ikke det vi ender med å bruke SASL til, i det minste i vår daglige rutine.

Som vi så tidligere, SASL er primært ment for protokoller som LDAP og SMTP. Selv om flere og flere applikasjoner og kommer ombord med SASL - for eksempel Kafka. Så, hvordan bruker vi SASL til å autentisere med slike tjenester?

La oss anta at vi har konfigurert Kafka Broker for SASL med PLAIN som den valgte mekanismen. PLAIN betyr ganske enkelt at den autentiserer ved hjelp av en kombinasjon av brukernavn og passord i ren tekst.

La oss nå se hvordan vi kan konfigurere en Java-klient til å bruke SASL / PLAIN til å autentisere mot Kafka Broker.

Vi begynner med å tilby en enkel JAAS-konfigurasjon, “kafka_jaas.conf”:

KafkaClient {org.apache.kafka.common.security.plain.PlainLoginModule krevde brukernavn = "brukernavn" passord = "passord"; };

Vi bruker denne JAAS-konfigurasjonen mens vi starter JVM:

-Djava.security.auth.login.config = kafka_jaas.conf

Til slutt må vi legge til noen få eiendommer for å overføre produsent- og forbrukerforekomster:

security.protocol = SASL_SSL sasl.mechanism = RETT

Det er alt det er med det. Dette er bare en liten del av Kafka-klientkonfigurasjoner. Bortsett fra PLAIN, støtter Kafka også GSSAPI / Kerberos for autentisering.

6. SASL i sammenligning

Selv om SASL er ganske effektiv i å tilby en mekanismenøytral måte å autentisere og sikre klient- og serverkommunikasjon på. Derimot, SASL er ikke den eneste tilgjengelige løsningen i denne forbindelse.

Java selv gir andre mekanismer for å oppnå dette målet. Vi vil kort diskutere dem og forstå hvordan de har det mot SASL:

  • Java Secure Socket Extension (JSSE): JSSE er et sett med pakker i Java som implementerer Secure Sockets Layer (SSL) for Java. Det gir datakryptering, klient- og serverautentisering og meldingsintegritet. I motsetning til SASL er JSSE avhengig av en PKI (Public Key Infrastructure) for å fungere. Derfor fungerer SASL som mer fleksibel og lett enn JSSE.
  • Java GSS API (JGSS): JGGS er Java-språkbindingen for Generic Security Service Application Programming Interface (GSS-API). GSS-API er en IETF-standard for applikasjoner som får tilgang til sikkerhetstjenester. I Java, under GSS-API, er Kerberos den eneste mekanismen som støttes. Kerberos krever igjen en Kerberisert infrastruktur for å fungere. Sammenlignet med SASL, her ennå, er valgene begrensede og tunge.

Samlet sett er SASL et veldig lett rammeverk og tilbyr et bredt utvalg av sikkerhetsfunksjoner gjennom pluggbare mekanismer. Søknader som tar i bruk SASL har mange valg for å implementere riktig sett med sikkerhetsfunksjoner, avhengig av behovet.

7. Konklusjon

For å oppsummere, i denne opplæringen, forsto vi det grunnleggende i SASL-rammeverket, som gir autentisering og sikker kommunikasjon. Vi diskuterte også API-ene som er tilgjengelige i Java for implementering av klient- og serversiden av SASL.

Vi så hvordan vi bruker en sikkerhetsmekanisme gjennom en JCA-leverandør. Til slutt snakket vi også om bruken av SASL i arbeidet med forskjellige protokoller og applikasjoner.

Som alltid kan koden bli funnet på GitHub.

Java bunn

Jeg kunngjorde nettopp det nye Lær våren kurs, med fokus på det grunnleggende i vår 5 og vårstøvel 2:

>> KONTROLLER KURSET

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