X.509-godkendelse i forårssikkerhed
1. Oversigt
I denne artikel vil vi fokusere på de vigtigste brugssager til X.509-certifikatgodkendelse - verificering af identiteten af en kommunikations peer når du bruger HTTPS (HTTP over SSL) -protokollen.
Kort sagt - mens der oprettes en sikker forbindelse, verificerer klienten serveren i henhold til sit certifikat (udstedt af en betroet certifikatmyndighed).
Men ud over det kan X.509 i Spring Security bruges til verificere en klients identitet af serveren under tilslutning. Dette kaldes "Gensidig godkendelse", og vi vil se på, hvordan det også gøres her.
Endelig vil vi røre ved når det giver mening at bruge denne form for godkendelse.
For at demonstrere serverbekræftelse opretter vi en simpel webapplikation og installerer en tilpasset certifikatmyndighed i en browser.
Desuden til gensidig godkendelse, opretter vi et klientcertifikat og ændrer vores server, så kun godkendte klienter tillades.
Det anbefales stærkt at følge vejledningen trin for trin og oprette certifikaterne såvel som keystore og truststore selv i henhold til instruktionerne i de følgende afsnit. Imidlertid kan alle de klar til brug filer findes i vores GitHub-lager.
2. Selvunderskrevet rod CA
For at kunne underskrive vores server- og klientsidescertifikater skal vi først oprette vores eget selvsignerede root CA-certifikat. Denne måde vi fungerer som vores egen certifikatmyndighed.
Til dette formål bruger vi openssl-biblioteket, så vi skal have det installeret, inden vi følger det næste trin.
Lad os nu oprette CA-certifikatet:
openssl-anmodning -x509 -sha256-dage 3650 -nyt nøgle rsa: 4096 -keyout rootCA.key -out rootCA.crt
Når vi udfører ovenstående kommando, skal vi angive adgangskoden til vores private nøgle. I forbindelse med denne vejledning bruger vi Ændre det som en adgangssætning.
Derudover vi er nødt til at indtaste oplysninger, der danner et såkaldt særnavn. Her leverer vi kun CN (almindeligt navn) - Baeldung.com - og efterlader andre dele tomme.

3. Keystore
Valgfrit krav: For at bruge kryptografisk stærke nøgler sammen med krypterings- og dekrypteringsfunktioner har vi brug for "Java Cryptography Extension (JCE) Unlimited Strength Jurisdiction Policy Files”Installeret i vores JVM.
Disse kan f.eks. Downloades fra Oracle (følg installationsinstruktionerne inkluderet i downloadet). Nogle Linux-distributioner giver også en installerbar pakke gennem deres pakkehåndtering.
En nøglelager er et lager, som vores Spring Boot-applikation bruger til at holde vores servers private nøgle og certifikat. Med andre ord, vores applikation bruger keystore til at servere certifikatet til klienterne under SSL-håndtrykket.
I denne vejledning bruger vi Java Key-Store (JKS) format og et keytool kommandolinjeværktøj.
3.1. Server-side certifikat
For at implementere serversiden X.509-godkendelse i vores Spring Boot-applikation, vi skal først oprette et servercertifikat. Lad os starte med at oprette en såkaldt certifikatsigneringsanmodning (CSR): På samme måde som for CA-certifikatet skal vi angive adgangskoden til den private nøgle. Lad os derudover bruge lokal vært som et almindeligt navn (CN). Før vi fortsætter, skal vi oprette en konfigurationsfil - localhost.ext. Det gemmer nogle yderligere parametre, der er nødvendige under underskrivelsen af certifikatet. En klar til brug-fil er også tilgængelig her. Nu er det tid til underskriv anmodningen med vores rootCA.crt certifikat og dets private nøgle: Bemærk, at vi skal angive den samme adgangskode, som vi brugte, da vi oprettede vores CA-certifikat. På dette tidspunkt, vi har endelig en klar til brug localhost.crt certifikat underskrevet af vores egen certifikatmyndighed. For at udskrive vores certifikats detaljer i en menneskelig læsbar form kan vi bruge følgende kommando: I dette afsnit vil vi se, hvordan du gør det importer det underskrevne certifikat og den tilsvarende private nøgle til keystore.jks fil. Vi bruger PKCS 12-arkivet til at pakke vores servers private nøgle sammen med det underskrevne certifikat. Derefter importerer vi det til det nyoprettede keystore.jks. Vi kan bruge følgende kommando til at oprette en .p12 fil: Så vi har nu localhost.key og localhost.crt bundtet i singlen localhost.p12 fil. Lad os nu bruge keytool til lave en keystore.jks arkiv og importere localhost.p12 fil med en enkelt kommando: På dette stadium har vi alt på plads til servergodkendelsesdelen. Lad os fortsætte med vores Spring Boot-applikationskonfiguration. Vores SSL-sikrede serverprojekt består af en @SpringBootApplication kommenteret applikationsklasse (som er en slags @Konfiguration), en application.properties konfigurationsfil og en meget enkel front-end i MVC-stil. Alt, hvad applikationen skal gøre, er at præsentere en HTML-side med en “Hej {Bruger}!” besked. På denne måde kan vi inspicere servercertifikatet i en browser for at sikre, at forbindelsen er verificeret og sikret. Først opretter vi et nyt Maven-projekt med tre Spring Boot Starter-bundter inkluderet: Til reference: vi kan finde bundterne på Maven Central (sikkerhed, web, thymeleaf). Som det næste trin opretter vi hovedapplikationsklassen og brugercontrolleren: Nu fortæller vi applikationen, hvor den skal findes keystore.jks og hvordan man får adgang til det. Vi indstiller SSL til en "aktiveret" status og ændrer standardlytteporten til angive en sikret forbindelse. Derudover konfigurerer vi nogle brugeroplysninger for at få adgang til vores server via grundlæggende godkendelse: Dette vil være HTML-skabelonen, der findes på ressourcer / skabeloner folder: Inden vi afslutter dette afsnit og kigger på stedet, vi har brug for at installere vores genererede rodcertifikatmyndighed som et betroet certifikat i en browser. En eksemplarisk installation af vores certifikatmyndighed for Mozilla Firefox ser ud som følger: Bemærk: Hvis du ikke vil tilføje vores certifikatmyndighed til listen over betroede myndigheder, har du senere mulighed for at lave en undtagelse og vis hjemmesiden hård, selv når den nævnes som usikker. Men så ser du et 'gult udråbstegn'-symbol i adresselinjen, der angiver den usikre forbindelse! Bagefter navigerer vi til spring-security-x509-basic-auth modul og kør: Endelig ramte vi // localhost: 8443 / bruger, indtast vores brugeroplysninger fra application.properties og skulle se en “Hej administrator!” besked. Nu er vi i stand til at inspicere forbindelsesstatus ved at klikke på symbolet "grøn lås" i adresselinjen, og det skal være en sikret forbindelse. I det foregående afsnit præsenterede vi, hvordan du implementerer det mest almindelige SSL-godkendelsesskema - server-side-godkendelse. Dette betyder, at kun en server godkendte sig over for klienter. I dette afsnit, vi beskriver, hvordan du tilføjer den anden del af godkendelsen - klientside-godkendelse. På denne måde er det kun klienter med gyldige certifikater underskrevet af den myndighed, som vores server har tillid til, at få adgang til vores sikre websted. Men inden vi fortsætter, lad os se, hvad der er fordele og ulemper ved at bruge den gensidige SSL-godkendelse. Fordele: Ulemper: En trustsore på en eller anden måde er det modsatte af en keystore. Det har certifikaterne for de eksterne enheder, som vi stoler på. I vores tilfælde er det nok at beholde root CA-certifikatet i tillidsbutikken. Lad os se, hvordan man opretter en truststore.jks fil og importer rootCA.crt ved hjælp af nøgleværktøj: Bemærk, vi skal angive adgangskoden til det nyoprettede trusstore.jks. Her brugte vi igen Ændre det adgangskode. Det er det, vi har importeret vores eget CA-certifikat, og truststore er klar til brug. For at fortsætte ændrer vi vores X509AuthenticationServer at strække sig fra WebSecurityConfigurerAdapter og tilsidesætte en af de medfølgende konfigurationsmetoder. Her konfigurerer vi x.509-mekanismen til at analysere Almindeligt navn (CN) felt i et certifikat til udpakning af brugernavne. Med disse udpakkede brugernavne ser Spring Security op i en forudsat UserDetailsService til matchende brugere. Så vi implementerer også denne serviceinterface, der indeholder en demo-bruger. Tip: I produktionsmiljøer er dette UserDetailsService kan indlæse sine brugere for eksempel fra en JDBC-datakilde. Du skal bemærke, at vi kommenterer vores klasse med @EnableWebSecurity og @EnableGlobalMethodSecurity med aktiveret pre- / post-autorisation. Med sidstnævnte kan vi kommentere vores ressourcer med @PreAuthorize og @PostAuthorize til finkornet adgangskontrol: Som tidligere nævnt er vi nu i stand til at bruge Ekspressionsbaseret adgangskontrol i vores controller. Mere specifikt respekteres vores bemærkninger om tilladelse på grund af @EnableGlobalMethodSecurity kommentar i vores @Konfiguration: En oversigt over alle mulige godkendelsesmuligheder findes i officiel dokumentation. Som et sidste ændringstrin skal vi fortælle applikationen, hvor vores truststore er placeret og det SSL-klientgodkendelse er nødvendigt (server.ssl.client-auth = behov). Så vi sætter følgende i vores application.properties: Nu, hvis vi kører applikationen og peger vores browser på // localhost: 8443 / bruger, vi bliver informeret om, at peer ikke kan verificeres, og det nægter at åbne vores websted. Nu er det tid til at oprette certifikatet på klientsiden. De trin, vi skal tage, er stort set de samme som for det servercertifikat, vi allerede har oprettet. Først skal vi oprette en anmodning om certifikatsignering: Vi bliver nødt til at give oplysninger, der vil blive indarbejdet i certifikatet. Til denne øvelse lad os kun indtaste det fælles navn (CN) - Bob. Det er vigtigt, da vi bruger denne post under godkendelsen, og kun Bob genkendes af vores prøveapplikation. Dernæst skal vi underskrive anmodningen med vores CA: Det sidste skridt, vi skal tage, er at pakke det underskrevne certifikat og den private nøgle i PKCS-filen: Langt om længe, vi er klar til at installere klientcertifikatet i browseren. Igen bruger vi Firefox: Når vi opdaterer vores websted, bliver vi nu bedt om at vælge det klientcertifikat, vi gerne vil bruge: Hvis vi ser en velkomstbesked som "Hej Bob!", det betyder, at alt fungerer som forventet! Tilføjelse af X.509-klientgodkendelse til en http sikkerhedskonfiguration i XML er også muligt: For at konfigurere en underliggende Tomcat er vi nødt til at sætte vores keystore og vores truststore ind i dens konf mappe og rediger server.xml: Tip: Med clientAuth indstillet til "vil have", SSL er stadig aktiveret, selvom klienten ikke leverer et gyldigt certifikat. Men i dette tilfælde skal vi bruge en anden godkendelsesmekanisme, for eksempel en loginformular, for at få adgang til de sikrede ressourcer. Sammenfattende har vi lært hvordan man opretter et selvsigneret CA-certifikat, og hvordan man bruger det til at underskrive andre certifikater. Derudover har vi oprettet både server- og klientsidescertifikater. Så har vi præsenteret, hvordan du importerer dem til en keystore og en truststore i overensstemmelse hermed. Desuden skal du nu kunne pakke et certifikat sammen med sin private nøgle i PKCS12-formatet. Vi har også diskuteret, hvornår det giver mening at bruge Spring Security X.509-klientgodkendelse, så det er op til dig at beslutte, om du vil implementere det i din webapplikation eller ej. Og for at afslutte, find kildekoden til denne artikel på Github.openssl req -nyt -nytkey rsa: 4096 -keyout localhost.key –out localhost.csr
AuthorityKeyIdentifier = keyid, udsteder basicConstraints = CA: FALSE subjectAltName = @alt_names [alt_names] DNS.1 = localhost
openssl x509 -req -CA rootCA.crt -CAkey rootCA.key -in localhost.csr -out localhost.crt-dage 365 -CAcreateserial -extfile localhost.ext
openssl x509 -in localhost.crt -tekst
3.2. Import til Keystore
openssl pkcs12 -eksport -out localhost.p12 -navn "localhost" -inkey localhost.key -in localhost.crt
nøgleværktøj -importkeystore -srckeystore localhost.p12 -srcstoretype PKCS12 -destkeystore keystore.jks -deststoretype JKS
4. Eksempel på anvendelse
4.1. Maven afhængigheder
org.springframework.boot spring-boot-starter-sikkerhed org.springframework.boot spring-boot-starter-web org.springframework.boot spring-boot-starter-thymeleaf
4.2. Spring Boot ansøgning
@SpringBootApplication public class X509AuthenticationServer {public static void main (String [] args) {SpringApplication.run (X509AuthenticationServer.class, args); }} @Controller public class UserController {@RequestMapping (value = "/ user") public String user (Model model, Principal principal) {UserDetails currentUser = (UserDetails) ((Authentication) principal) .getPrincipal (); model.addAttribute ("brugernavn", currentUser.getUsername ()); returner "bruger"; }}
server.ssl.key-store = .. / store / keystore.jks server.ssl.key-store-password = $ {PASSWORD} server.ssl.key-alias = localhost server.ssl.key-password = $ {PASSWORD } server.ssl.enabled = sand server.port = 8443 spring.security.user.name = Admin spring.security.user.password = admin
X.509-godkendelsesdemo
Hej !
4.3. Root CA Installation
mvn spring-boot: løb
5. Gensidig godkendelse
5.1. Truststore
keytool -import -trustcacerts -noprompt -alias ca -ext san = dns: localhost, ip: 127.0.0.1 -fil rootCA.crt -keystore truststore.jks
5.2. Forårssikkerhedskonfiguration
@SpringBootApplication @EnableWebSecurity @EnableGlobalMethodSecurity (prePostEnabled = true) offentlig klasse X509AuthenticationServer udvider WebSecurityConfigurerAdapter {... @Override-beskyttet ugyldig konfiguration (HttpSecurity http) kaster Exception $) ") service (bruger service)) (bruger service)) (bruger service)) (brugertjeneste) {return new UserDetailsService () {@Override public UserDetails loadUserByUsername (String username) {if (username.equals ("Bob")) {return new User (username, "", AuthorityUtils .commaSeparatedStringToAuthorityList ("ROLE_USER"));} throw nyt brugernavnNotFoundException ("Bruger ikke fundet!");}};}}
@Controller public class UserController {@PreAuthorize ("hasAuthority ('ROLE_USER')") @RequestMapping (value = "/ user") public String user (Model model, Principal principal) {...}}
server.ssl.trust-store = store / truststore.jks server.ssl.trust-store-password = $ {PASSWORD} server.ssl.client-auth = behov
5.3. Certifikat på klientsiden
openssl req -nyt -nyt nøgle rsa: 4096 -noder -nøgle-clientBob.key -out clientBob.csr
openssl x509 -req -CA rootCA.crt -CAkey rootCA.key -in clientBob.csr -out clientBob.crt -days 365 -CAcreateserial
openssl pkcs12 -eksport-ud clientBob.p12 -name "clientBob" -inkey clientBob.key -in clientBob.crt
6. Gensidig godkendelse med XML
... ...
7. Konklusion