Postavljanje Swaggera 2 s Spring REST API-jem

Sigurnost Vrh

Upravo sam najavio novi tečaj Learn Spring Security, uključujući puni materijal usredotočen na novi OAuth2 stog u Spring Security 5:

>> PROVJERITE TEČAJ OSTALO Vrh

Upravo sam najavio novo Uči proljeće tečaj, usredotočen na osnove Spring 5 i Spring Boot 2:

>> PROVJERITE TEČAJ

1. Pregled

U današnje vrijeme front-end i back-end komponente često odvajaju web aplikaciju. Obično API-je izlažemo kao pozadinsku komponentu za integraciju prednje komponente ili nezavisne aplikacije.

U takvom je scenariju bitno imati odgovarajuće specifikacije za pozadinske API-je. Istodobno, API dokumentacija trebala bi biti informativna, čitljiva i laka za slijediti.

Štoviše, referentna dokumentacija trebala bi istodobno opisivati ​​svaku promjenu API-ja. Ručno postizanje ovoga dosadna je vježba, pa je automatizacija postupka bila neizbježna.

U ovom uputstvu ćemo pogledati Swagger 2 za web uslugu Spring REST, koristeći Springfoxovu implementaciju Swagger 2 specifikacije.

Ako niste upoznati sa Swaggerom, posjetite njegovu web stranicu kako biste saznali više prije nego što nastavite s ovim vodičem.

2. Ciljani projekt

Stvaranje REST usluge koju ćemo koristiti nije u dosegu ovog članka. Ako već imate prikladan projekt, iskoristite ga. Ako nisu, ove su veze dobro mjesto za početak:

  • Izgradite REST API s člankom Spring 4 i Java Config
  • Izgradnja RESTful web usluge

3. Dodavanje ovisnosti Maven

Kao što je gore spomenuto, koristit ćemo Springfoxovu implementaciju Swaggerove specifikacije. Najnoviju verziju možete pronaći na Maven Central.

Da bismo ga dodali našem projektu Maven, potrebna nam je ovisnost o pom.xml datoteka:

 io.springfox springfox-swagger2 2.9.2 

3.1. Ovisnost o proljetnom pokretanju

Za projekte temeljene na Spring Boot-u, dovoljno je dodati singl springfox-boot-starter ovisnost:

 io.springfox springfox-boot-starter 3.0.0 

4. Integriranje Swaggera 2 u projekt

4.1. Java konfiguracija

Konfiguracija Swaggera uglavnom se usredotočuje na Etiketa grah:

@Configuration javna klasa SpringFoxConfig {@Bean public Docket api () {return new Docket (DocumentationType.SWAGGER_2) .select () .apis (RequestHandlerSelectors.any ()) .paths (PathSelectors.any ()) .build (); }}

Nakon definiranja Etiketa grah, njegov Odaberi() metoda vraća instancu ApiSelectorBuilder, koji pruža način za kontrolu krajnjih točaka koje je izložio Swagger.

Možemo konfigurirati predikate za odabir RequestHandlers pomoću RequestHandlerSelectors i PathSelectors. Koristeći bilo koji () jer će oboje učiniti dostupnim dokumentaciju za cijeli naš API putem Swaggera.

4.2. Konfiguracija bez proljetnog pokretanja

U običnim proljetnim projektima moramo izričito omogućiti Swagger 2. Učiniti tako, moramo koristiti @ EnableSwagger2WebMvc na našoj klasi konfiguracije:

@Configuration @ EnableSwagger2WebMvc javna klasa SpringFoxConfig {}

Uz to, bez Spring Boota nemamo luksuz automatske konfiguracije naših rukovatelja resursima.

Swagger UI dodaje skup resursa koje moramo konfigurirati kao dio klase koja se proširuje WebMvcConfigurerAdapter a bilježi se s @EnableWebMvc:

@Override public void addResourceHandlers (Registry ResourceHandlerRegistry) {registry.addResourceHandler ("swagger-ui.html") .addResourceLocations ("classpath: / META-INF / resources /"); registry.addResourceHandler ("/ webjars / **") .addResourceLocations ("put do klase: / META-INF / resources / webjars /"); }

4.3. Verifikacija

Da bismo provjerili radi li Springfox, u našem pregledniku možemo posjetiti ovaj URL:

// localhost: 8080 / spring-security-rest / api / v2 / api-docs

Rezultat je JSON odgovor s velikim brojem parova ključ / vrijednost, koji nije baš čitljiv za ljude. Srećom, Swagger pruža Swagger UI za ovu svrhu.

5. Swagger UI

Swagger UI je ugrađeno rješenje koje znatno olakšava interakciju korisnika s API dokumentacijom generiranom Swaggerom.

5.1. Omogućavanje Springfoxova korisničkog sučelja Swagger

Da bismo koristili Swagger UI, moramo dodati dodatnu Mavenovu ovisnost:

 io.springfox springfox-swagger-ui 2.9.2 

Sada ga možemo testirati u našem pregledniku posjetom:

// localhost: 8080 / your-app-root / swagger-ui /

U našem slučaju, inače, točan URL bit će:

// localhost: 8080 / spring-security-rest / api / swagger-ui /

Rezultat bi trebao izgledati otprilike ovako:

5.2. Istraživanje Swaggerove dokumentacije

Unutar Swaggerovog odgovora nalazi se a popis svih kontrolora definirano u našoj prijavi. Klikom na bilo koji od njih prikazat će se važeće HTTP metode (IZBRISATI, DOBITI, GLAVA, OPCIJE, ZAKRPA, OBJAVI, STAVITI).

Proširivanjem svake metode dobivaju se dodatni korisni podaci, poput statusa odgovora, vrste sadržaja i popisa parametara. Također je moguće isprobati svaku metodu pomoću korisničkog sučelja.

Swaggerova sposobnost sinkronizacije s našom bazom koda je presudna. Da bismo to demonstrirali, u našu aplikaciju možemo dodati novi kontroler:

@RestController javna klasa CustomController {@RequestMapping (value = "/ custom", method = RequestMethod.POST) public String custom () {return "custom"; }}

Sad ako osvježimo Swaggerovu dokumentaciju, vidimo custom-controller na popisu kontrolora. Kao što znamo, postoji samo jedna metoda (OBJAVI) prikazan u Swaggerovom odgovoru.

6. Spring Data REST

Springfox pruža podršku za Spring Data REST putem svog springfox-data-rest knjižnica.

Spring Boot pobrinut će se za automatsku konfiguraciju ako otkrije spring-boot-starter-data-rest na razrednoj stazi.

Ajmo sada stvoriti entitet s imenom Korisnik:

@ Entitet javne klase Korisnik {@Id private Long id; private String firstName; privatno int doba; privatni String e-mail; // geteri i postavljači}

Tada ćemo stvoriti UserRepository za dodavanje CRUD operacija na Korisnik entitet:

Javno sučelje @Repository UserRepository proširuje CrudRepository {}

Na kraju ćemo uvesti SpringDataRestConfiguration razred do SpringFoxConfig razred:

@ EnableSwagger2WebMvc @Import (SpringDataRestConfiguration.class) javna klasa SpringFoxConfig {// ...}

Napomena: Koristili smo @ EnableSwagger2WebMvc napomena kako bi se omogućio Swagger, jer je zamijenio @ EnableSwagger2 napomena u verziji 3 knjižnica.

Ponovno pokrenimo aplikaciju kako bismo generirali specifikacije za Spring Data REST API-je:

Vidimo da je Springfox generirao specifikacije za Korisnik entitet s HTTP metodama poput DOBITI, OBJAVITE, STAVITE, ZAPAČITE, i IZBRISATI.

7. Provjere graha

Springfox također podržava bilješke za provjeru graha putem svojih springfox-potvrđivači graha knjižnica.

Prvo ćemo našoj ovisnosti dodati Maven pom.xml:

 io.springfox springfox-validatori za grah 2.9.2 

Opet, ako koristimo Spring Boot, gornju ovisnost ne moramo pružiti izričito.

Dalje, dodajmo nekoliko napomena o provjeri, poput @NotNull i @ Min prema Korisnik entitet:

@Entity javna klasa Korisnik {// ... @NotNull (message = "Ime ne može biti null") private String firstName; @Min (vrijednost = 15, message = "Dob ne smije biti manja od 15") @Max (vrijednost = 65, message = "Dob ne smije biti veća od 65") private int age; }

Napokon ćemo uvesti BeanValidatorPluginsConfiguration razred do SpringFoxConfig razred:

@ EnableSwagger2 @Import (BeanValidatorPluginsConfiguration.class) javna klasa SpringFoxConfig {// ...}

Pogledajmo promjene u API specifikacijama:

Ovdje možemo primijetiti da Korisnik model ima * obavezno na ime. Također, minimum i maksimum vrijednosti su definirane za dob.

8. Dodatak

Kako bismo API specifikacijama dodali određene značajke, možemo stvoriti dodatak Springfox. Dodatak može ponuditi razne značajke, od obogaćivanja modela i svojstava do prilagođenih API popisa i zadanih postavki.

Springfox podržava stvaranje dodatka kroz svoj spi modul. Modul spi nudi nekoliko sučelja poput ModelBuilderPlugin, ModelPropertyBuilderPlugin, i ApiListingBuilderPlugin koji djeluju kao kuka proširivosti za implementaciju prilagođenog dodatka.

Da bismo demonstrirali mogućnosti, stvorimo dodatak za obogaćivanje e-mail vlasništvo Korisnik model. Koristit ćemo ModelPropertyBuilderPlugin sučelje i postavite vrijednosti uzorak i primjer.

Prvo, kreirajmo Dodatak za e-poštu klase i nadjačati podupire metoda koja omogućuje bilo koju vrstu dokumentacije, poput Swagger 1.2 i Swagger 2:

@Component @Order (Validators.BEAN_VALIDATOR_PLUGIN_ORDER) javna klasa EmailAnnotationPlugin implementira ModelPropertyBuilderPlugin {@Override javne logičke potpore (graničnik DocumentationType) {return true; }}

Tada ćemo poništiti primijeniti metoda ModelPropertyBuilderPlugin za postavljanje vrijednosti svojstava graditelja:

@Override javna praznina se primjenjuje (ModelPropertyContext context) {Neobvezna adresa e-pošte = annotationFromBean (context, Email.class); if (email.isPresent ()) {context.getSpecificationBuilder (). facetBuilder (StringElementFacetBuilder.class) .pattern (email.get (). regexp ()); context.getSpecificationBuilder (). primjer ("[e-pošta zaštićena]"); }}

Dakle, API specifikacije će pokazati uzorak i primjer vrijednosti svojstva označene s @E-mail bilješka.

Dalje ćemo dodati @E-mail bilješka na Korisnik entitet:

Korisnik javne klase @Entity {// ... @Email (regexp = ". * @. * \ .. *", message = "E-pošta treba biti valjana") private String email; }

Posljednje, omogućit ćemo Dodatak za e-poštu u SpringFoxConfig klase registracijom kao grah:

@Import ({BeanValidatorPluginsConfiguration.class}) javna klasa SpringFoxConfig {// ... @Bean public EmailAnnotationPlugin emailPlugin () {return new EmailAnnotationPlugin (); }}

Provjerimo Dodatak za e-poštu u akciji:

Možemo vidjeti vrijednost uzorak je isti regularni izraz (. * @. * \ .. *) iz e-mail vlasništvo Korisnik entitet.

Slično tome, vrijednost primjer ([e-mail zaštićen]) je isti, kao što je definirano u primijeniti metoda Dodatak za e-poštu.

9. Napredna konfiguracija

The Etiketa bean naše aplikacije može se konfigurirati tako da nam daje veću kontrolu nad postupkom generiranja API dokumentacije.

9.1. API za filtriranje Swaggerovog odgovora

Nije uvijek poželjno izlagati dokumentaciju za cijeli API. Swaggerov odgovor možemo ograničiti prosljeđivanjem parametara na apis() i staze () metode Etiketa razred.

Kao što se vidi gore, RequestHandlerSelectors omogućuje korištenje bilo koji ili nijedna predikati, ali se također može koristiti za filtriranje API-ja prema osnovnom paketu, bilješci klase i bilješkama metode.

PathSelectors pruža dodatno filtriranje s predikatima, koji skeniraju putove zahtjeva naše aplikacije. Možemo koristiti bilo koji (), ništa (), regularni izraz (), ili mrav().

U primjeru u nastavku, naložit ćemo Swaggeru da uključi samo kontrolere iz određenog paketa, s određenim stazama, koristeći mrav() predikat:

@Bean public Docket api () {return new Docket (DocumentationType.SWAGGER_2) .select () .apis (RequestHandlerSelectors.basePackage ("com.baeldung.web.controller")). Paths (PathSelectors.ant ("/ foos / * ")) .build (); }

9.2. Prilagođene informacije

Swagger također nudi neke zadane vrijednosti u svom odgovoru, koje možemo prilagoditi, poput "Api dokumentacija", "Izrađena kontaktnom e-poštom" i "Apache 2.0".

Da bismo promijenili ove vrijednosti, možemo koristiti apiInfo (ApiInfo apiInfo) metoda - ApiInfo klasa koja sadrži prilagođene informacije o API-ju:

@Bean public Docket api () {return new Docket (DocumentationType.SWAGGER_2) .select () .apis (RequestHandlerSelectors.basePackage ("com.example.controller")). Staze (PathSelectors.ant ("/ foos / *") ) .build () .apiInfo (apiInfo ()); } private ApiInfo apiInfo () {return new ApiInfo ("My REST API", "Some custom description of API.", "API TOS", "Uvjeti pružanja usluge", novi kontakt ("John Doe", "www.example"). com "," [zaštićena e-poštom] ")," Licenca API-ja "," URL API licence ", Collections.emptyList ()); }

9.3. Poruke odgovora prilagođenih metoda

Swagger dopušta globalno nadjačavajuće poruke odgovora HTTP metoda kroz EtiketaS globalResponseMessage ()metoda.

Prvo, moramo uputiti Swaggera da ne koristi zadane poruke odgovora. Pretpostavimo da želimo nadjačati 500 i 403 poruke odgovora za sve DOBITI metode.

Da bi se to postiglo, mora se dodati neki kôd u EtiketaBlok inicijalizacije (izvorni kôd je isključen radi jasnosti):

.useDefaultResponseMessages (false) .globalResponseMessage (RequestMethod.GET, newArrayList (new ResponseMessageBuilder () .code (500) .message ("500 message") .responseModel (new ModelRef ("Error")) .build (), new RespoildMes ) .code (403) .message ("Forbidden!") .build ()));

10. Swagger UI s OAuth-osiguranim API-jem

Korisničko sučelje Swagger nudi niz vrlo korisnih značajki koje smo ovdje do sada dobro pokrili. Ali većinu njih zapravo ne možemo koristiti ako je naš API zaštićen i nije dostupan.

Pogledajmo kako Swaggeru možemo dopustiti pristup API-ju zaštićenom OAuth-om pomoću tipa odobrenja Autorizacijskog koda u ovom primjeru.

Konfigurirat ćemo Swagger za pristup našem zaštićenom API-ju pomoću Shema sigurnosti i SecurityContext podrška:

@Bean public Docket api () {return new Docket (DocumentationType.SWAGGER_2) .select () .apis (RequestHandlerSelectors.any ()) .paths (PathSelectors.any ()) .build () .securitySchemes (Arrays.asList (securityScheme) ())) .securityContexts (Arrays.asList (securityContext ())); }

10.1. Konfiguracija sigurnosti

Definirat ćemo a Konfiguracija sigurnosti bean u našoj Swagger konfiguraciji i postavite neke zadane postavke:

@Bean public SecurityConfiguration security () {return SecurityConfigurationBuilder.builder () .clientId (CLIENT_ID) .clientSecret (CLIENT_SECRET) .scopeSeparator ("") .useBasicAuthenticationWithAccessCodeGrant (true) .build }

10.2. Shema sigurnosti

Dalje ćemo definirati naš Shema sigurnosti; ovo se koristi za opisivanje kako je naš API osiguran (osnovna provjera autentičnosti, OAuth2, ...).

U našem slučaju ovdje ćemo definirati shemu OAuth koja se koristi za zaštitu našeg poslužitelja resursa:

private SecurityScheme securityScheme () {GrantType grantType = new AuthorizationCodeGrantBuilder () .tokenEndpoint (new TokenEndpoint (AUTH_SERVER + "/ token", "oauthtoken") .tokenRequestEndpoint (new TokenRequestEndpoint (CL) izgraditi(); SecurityScheme oauth = novi OAuthBuilder (). Name ("spring_oauth") .grantTypes (Arrays.asList (grantType)) .scopes (Arrays.asList (scopes ())) .build (); povratak oauth; }

Imajte na umu da smo koristili tip odobrenja autorizacijskog koda, za koji moramo navesti krajnju točku tokena i URL autorizacije našeg OAuth2 poslužitelja za autorizaciju.

Evo i opsega koje smo trebali definirati:

private AuthorizationScope [] scopes () {AuthorizationScope [] scopes = {new AuthorizationScope ("read", "za operacije čitanja"), new AuthorizationScope ("write", "for операции pisanja"), new AuthorizationScope ("foo", " Pristup foo API ")}; povratni opsezi; }

Oni se sinkroniziraju s opsezima koje smo zapravo definirali u našoj aplikaciji za / foos API.

10.3. SecurityContext

Konačno, moramo definirati a SecurityContext za naš primjer API-ja:

private SecurityContext securityContext () {return SecurityContext.builder () .securityReferences (Arrays.asList (new SecurityReference ("spring_oauth", scopes ()))) .forPaths (PathSelectors.regex ("/ foos. *")) .build ( ); }

Imajte na umu kako je ime koje smo ovdje koristili u referenci - proljetni_aut - sinkronizira se s imenom koje smo prethodno koristili u Shema sigurnosti.

10.4. Test

Sad kad smo sve postavili i spremni za rad, pogledajmo naš Swagger UI i pokušajmo pristupiti Foo API-ju.

Korisničkom sučelju Swagger možemo pristupiti lokalno:

//localhost:8082/spring-security-oauth-resource/swagger-ui.html

Kao što vidimo, novi gumb Autoriziraj sada postoji zbog naših sigurnosnih konfiguracija:

Kada kliknemo gumb Autoriziraj, vidjet ćemo sljedeći skočni prozor za autorizaciju našeg korisničkog sučelja Swagger za pristup zaštićenom API-ju:

Imajte na umu da:

  • CLIENT_ID i CLIENT_SECRET već možemo vidjeti, kao što smo ih prethodno konfigurirali (ali ih i dalje možemo promijeniti).
  • Sada možemo odabrati opsege koji su nam potrebni.

Evo kako je označen zaštićeni API:

I sada, napokon, možemo postići naš API!

Naravno, gotovo se podrazumijeva da moramo biti oprezni kako eksponiramo Swagger UI izvana, sada kada je ova sigurnosna konfiguracija aktivna.

11. Zaključak

U ovom smo članku postavili Swagger 2 za generiranje dokumentacije za Spring REST API. Također smo istražili načine vizualizacije i prilagodbe Swaggerovih rezultata. I na kraju, pogledali smo jednostavnu OAuth konfiguraciju za Swaggera.

The puna provedba ovog vodiča možete pronaći u projektu GitHub. Da biste vidjeli postavke u projektu pokretanja, pogledajte ovaj GitHub modul.

Za odjeljak OAuth kôd je dostupan u našem spremištu spring-security-oauth.

A ako ste student REST-a s proljećem, idite na lekciju 1 iz modula 7 i dublje uđite u postavljanje Swaggera s oprugom i opružnim čizmama.

Dno sigurnosti

Upravo sam najavio novi tečaj Learn Spring Security, uključujući puni materijal usredotočen na novi OAuth2 stog u Spring Security 5:

>> PROVJERITE TEČAJ OSTALO dno

Upravo sam najavio novo Uči proljeće tečaj, usredotočen na osnove Spring 5 i Spring Boot 2:

>> PROVJERITE TEČAJ