הגדרת Swagger 2 עם REST API של Spring

למעלה אבטחה

הרגע הכרזתי על הקורס החדש ללמוד Spring Spring Security, כולל החומר המלא שהתמקד בערמת OAuth2 החדשה ב- Spring Security 5:

>> בדוק את הקורס REST למעלה

רק הכרזתי על החדש למד אביב קורס, המתמקד ביסודות האביב 5 ומגף האביב 2:

>> בדוק את הקורס

1. סקירה כללית

כיום, רכיבי חזית ורכב מפרידים לעתים קרובות יישום אינטרנט. בדרך כלל אנו חושפים ממשקי API כרכיב אחורי עבור רכיבי חזית או שילובי אפליקציות של צד שלישי.

בתרחיש כזה, חיוני שיהיו מפרטים מתאימים עבור ממשקי ה- API האחורי. יחד עם זאת, תיעוד ה- API צריך להיות אינפורמטיבי, קריא וקל לביצוע.

יתר על כן, תיעוד הפניה אמור לתאר בו זמנית כל שינוי ב- API. ביצוע זה באופן ידני הוא תרגיל מייגע, ולכן אוטומציה של התהליך הייתה בלתי נמנעת.

במדריך זה נבחן Swagger 2 לשירות אינטרנט של Spring REST, באמצעות יישום Springfox של מפרט Swagger 2.

אם אינך מכיר את Swagger, בקר בדף האינטרנט שלו למידע נוסף לפני שתמשיך בהדרכה זו.

2. פרויקט יעד

יצירת שירות ה- REST בו נשתמש אינה בגדר מאמר זה. אם כבר יש לך פרויקט מתאים, השתמש בו. אם לא, קישורים אלה הם מקום טוב להתחיל בו:

  • בניית REST API עם מאמר Spring 4 ו- Java Config
  • בניית שירות אינטרנט RESTful

3. הוספת התלות של Maven

כאמור לעיל, נשתמש ביישום Springfox של מפרט Swagger. ניתן למצוא את הגרסה האחרונה ב- Maven Central.

כדי להוסיף אותו לפרויקט Maven שלנו, אנו זקוקים לתלות ב- pom.xml קוֹבֶץ:

 io.springfox springfox-swagger2 2.9.2 

3.1. תלות במגף האביב

לפרויקטים מבוססי Spring Boot, זה מספיק כדי להוסיף סינגל springfox-boot-starter תלות:

 io.springfox springfox-boot-starter 3.0.0 

4. שילוב סוואגר 2 בפרויקט

4.1. תצורת Java

התצורה של Swagger מתרכזת בעיקר סביב תָוִית אפונה:

@Configuration מחלקה ציבורית SpringFoxConfig {@Bean Docket API API) (החזר Docket חדש (DocumentationType.SWAGGER_2). בחר () .apis (RequestHandlerSelectors.any ()). Paths (PathSelectors.any ()) .build (); }}

לאחר הגדרת ה- תָוִית שעועית, שלה בחר() השיטה מחזירה מופע של ApiSelectorBuilder, המספק דרך לשלוט בנקודות הקצה שנחשפו על ידי סוואגר.

אנו יכולים להגדיר פרדיקטים לבחירה RequestHandlers בעזרת RequestHandlerSelectors ו PathSelectors. באמצעות כל() עבור שניהם יהפוך תיעוד לכל ה- API שלנו לזמין באמצעות Swagger.

4.2. תצורה ללא מגף קפיץ

בפרויקטים פשוטים של אביב, עלינו לאפשר את Swagger 2 במפורש. לשם כך, עלינו להשתמש ב- @ EnableSwagger2WebMvc בשיעור התצורה שלנו:

@Configuration @ EnableSwagger2WebMvc מחלקה ציבורית SpringFoxConfig {}

בנוסף, ללא Spring Boot, אין לנו את המותרות של תצורה אוטומטית של מטפלי המשאבים שלנו.

ממשק המשתמש של Swagger מוסיף מערך משאבים שעלינו להגדיר כחלק ממעמד שמתארך WebMvcConfigurerAdapter ומבואר עם @EnableWebMvc:

@ ביטול הריק הציבורי addResourceHandlers (הרישום ResourceHandlerRegistry) {registry.addResourceHandler ("swagger-ui.html") .addResourceLocations ("classpath: / META-INF / resources /"); registry.addResourceHandler ("/ webjars / **") .addResourceLocations ("classpath: / META-INF / resources / webjars /"); }

4.3. אימות

כדי לוודא ש- Springfox עובד, אנו יכולים לבקר בכתובת אתר זו בדפדפן שלנו:

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

התוצאה היא תגובת JSON עם מספר רב של זוגות ערכי מפתח, שאינה ניתנת לקריאה אנושית. למרבה המזל, סוואגר מספק ממשק המשתמש של Swagger למטרה זו.

5. ממשק המשתמש של Swagger

ממשק המשתמש של Swagger הוא פתרון מובנה שהופך את האינטראקציה של המשתמשים עם תיעוד ה- API שנוצר על ידי Swagger הרבה יותר קלה.

5.1. הפעלת ממשק המשתמש Swagger של Springfox

כדי להשתמש בממשק המשתמש של Swagger, עלינו להוסיף תלות נוספת ב- Maven:

 io.springfox springfox-swagger-ui 2.9.2 

כעת אנו יכולים לבדוק זאת בדפדפן שלנו על ידי ביקור ב:

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

במקרה שלנו, אגב, כתובת האתר המדויקת תהיה:

// localhost: 8080 / אביב-ביטחון-מנוחה / api / swagger-ui /

התוצאה צריכה להראות בערך ככה:

5.2. חקר תיעוד סוואגר

בתוך התגובה של סוואגר היא רשימת כל הבקרים מוגדר ביישום שלנו. לחיצה על אחת מהן תפרט את שיטות ה- HTTP החוקיות (לִמְחוֹק, לקבל, רֹאשׁ, אפשרויות, תיקון, הודעה, לָשִׂים).

הרחבת כל שיטה מספקת נתונים שימושיים נוספים, כגון מצב תגובה, סוג תוכן ורשימת פרמטרים. אפשר גם לנסות כל שיטה באמצעות ממשק המשתמש.

היכולת של סוואגר להיות מסונכרנת עם בסיס הקוד שלנו היא מכריעה. כדי להדגים זאת, אנו יכולים להוסיף בקר חדש ליישום שלנו:

@RestController מחלקה ציבורית CustomController {@RequestMapping (value = "/ custom", method = RequestMethod.POST) ציבורי מחרוזת מותאם אישית () {להחזיר "custom"; }}

עכשיו אם נרענן את תיעוד Swagger, נראה בקר מותאם אישית ברשימת הבקרים. כידוע, יש רק שיטה אחת (הודעה) מוצג בתגובתו של סוואגר.

6. נתוני האביב REST

Springfox מספקת תמיכה ב- Spring Data REST באמצעות שלה springfox-data-rest סִפְרִיָה.

Spring Boot יטפל בתצורה האוטומטית אם הוא יגלה את קפיץ-אתחול-המתנע-נתונים-מנוחה על מסלול הכיתה.

עכשיו בואו ניצור ישות בשם מִשׁתַמֵשׁ:

משתמש בכיתה ציבורית @Entity {@Id פרטי מזהה ארוך; פרטי מחרוזת firstName; גיל פרטי פרטי; דוא"ל מחרוזת פרטי; // גטרים וקובעים}

ואז ניצור את UserRepository להוסיף פעולות CRUD על מִשׁתַמֵשׁ יֵשׁוּת:

ממשק ציבורי @ מאגר UserRepository מרחיב את CrudRepository {}

אחרון, נייבא את SpringDataRestConfiguration כיתה ל SpringFoxConfig מעמד:

@ EnableSwagger2WebMvc @ Import (SpringDataRestConfiguration.class) מחלקה ציבורית SpringFoxConfig {// ...}

הערה: השתמשנו ב- @ EnableSwagger2WebMvc ביאור כדי לאפשר לסוואגר, מכיוון שהוא החליף את @ EnableSwagger2 ביאור בגרסה 3 של הספריות.

בואו נתחיל מחדש את היישום כדי ליצור את המפרט עבור ממשקי ה- API של REST של Spring Data:

אנו יכולים לראות כי ספרינגפוקס ייצרה את המפרט עבור מִשׁתַמֵשׁ ישות עם שיטות HTTP כמו לקבל, POST, PUT, PATCH, ו לִמְחוֹק.

7. אימות שעועית

ספרינגפוקס תומכת גם בהערות אימות השעועית באמצעותה ספרינג-פוקס-מאמת שעועית סִפְרִיָה.

ראשית, נוסיף את התלות של Maven שלנו pom.xml:

 io.springfox springfox-bean-validators 2.9.2 

שוב, אם אנו משתמשים באביב אתחול, איננו צריכים לספק את התלות הנ"ל במפורש.

לאחר מכן, בואו נוסיף כמה הערות אימות כמו @לא ריק ו @Min אל ה מִשׁתַמֵשׁ יֵשׁוּת:

משתמש בכיתה ציבורית @Entity {// ... @NotNull (message = "השם הפרטי לא יכול להיות ריק") פרטי מחרוזת שם פרטי; @Min (value = 15, message = "גיל לא צריך להיות פחות מ 15") @Max (value = 65, message = "גיל לא צריך להיות גדול מ 65") גילאי פרטי פרטי; }

לבסוף, נייבא את BeanValidatorPluginsConfiguration כיתה ל SpringFoxConfig מעמד:

@ EnableSwagger2 @ Import (BeanValidatorPluginsConfiguration.class) מחלקה ציבורית SpringFoxConfig {// ...}

בואו נסתכל על השינויים במפרט ה- API:

כאן אנו יכולים לראות כי ה- מִשׁתַמֵשׁ למודל יש * נדרש על שם פרטי. וגם ה מִינִימוּם ו מַקסִימוּם ערכים מוגדרים עבור גיל.

8. תוסף

על מנת להוסיף תכונות ספציפיות למפרטי ה- API, אנו יכולים ליצור תוסף Springfox. תוסף יכול להציע תכונות שונות, החל מהעשרת הדגמים והמאפיינים ועד לרישומי ה- API המותאמים אישית ולברירות המחדל.

Springfox תומכת ביצירת התוספים באמצעות מודול ה- spi שלה. מודול ה- spi מספק כמה ממשקים כמו ה- ModelBuilderPlugin, ModelPropertyBuilderPlugin, ו ApiListingBuilderPlugin המשמשים כקרקע להרחבה ליישום תוסף מותאם אישית.

כדי להדגים את היכולות, בואו ניצור תוסף להעשרת ה- אימייל הקניין של מִשׁתַמֵשׁ דֶגֶם. נשתמש ב- ModelPropertyBuilderPlugin ממשק וקבע את הערכים של תבנית ו דוגמא.

ראשית, בואו ניצור את EmailAnnotationPlugin בכיתה ולדרוס את תומך שיטה המאפשרת כל סוג תיעוד, כגון Swagger 1.2 ו- Swagger 2:

@Component @Order (Validators.BEAN_VALIDATOR_PLUGIN_ORDER) מחלקה ציבורית EmailAnnotationPlugin מיישם את ModelPropertyBuilderPlugin {@Override תומכים בוליאניים ציבוריים (תיחום DocumentationType) {return true; }}

ואז נעקוף את להגיש מועמדות שיטת ה- ModelPropertyBuilderPlugin להגדרת הערכים של מאפייני הבונה:

@ ביטול חלל ציבורי להחיל (הקשר ModelPropertyContext) {דוא"ל אופציונלי = annotationFromBean (הקשר, Email.class); אם (email.isPresent ()) {context.getSpecificationBuilder (). facetBuilder (StringElementFacetBuilder.class) .pattern (email.get (). regexp ()); context.getSpecificationBuilder (). דוגמה ("[מוגן באמצעות דוא"ל]"); }}

אז, מפרטי ה- API יציגו את תבנית ו דוגמא ערכי הנכס המוערים עם @אימייל ביאור.

לאחר מכן נוסיף את @אימייל ביאור ל מִשׁתַמֵשׁ יֵשׁוּת:

משתמש בכיתה ציבורית @Entity {// ... @Email (regexp = ". * @. * \ .. *", message = "הדוא"ל צריך להיות תקף") דוא"ל מחרוזת פרטי; }

אחרון, נאפשר את EmailAnnotationPlugin בתוך ה SpringFoxConfig בכיתה על ידי רישום כשעועית:

@Import ({BeanValidatorPluginsConfiguration.class}) מחלקה ציבורית SpringFoxConfig {// ... @Bean public EmailAnnotationPlugin emailPlugin () {להחזיר EmailAnnotationPlugin חדש (); }}

בואו נבדוק את EmailAnnotationPlugin בִּפְעוּלָה:

אנו יכולים לראות את הערך של ה- תבנית הוא אותו regex (. * @. * \ .. *) מה- אימייל הקניין של מִשׁתַמֵשׁ יֵשׁוּת.

באופן דומה, הערך של דוגמא ([מוגן באמצעות דוא"ל]) זהה, כהגדרתו ב- להגיש מועמדות שיטת ה- EmailAnnotationPlugin.

9. תצורה מתקדמת

ה תָוִית ניתן להגדיר את שעועית היישום שלנו כדי לתת לנו שליטה רבה יותר בתהליך יצירת תיעוד ה- API.

9.1. סינון API לתגובת סוואגר

לא תמיד רצוי לחשוף את התיעוד עבור כל ה- API. אנו יכולים להגביל את תגובתו של סוואגר על ידי העברת פרמטרים ל apis () ו נתיבים () שיטות של תָוִית מעמד.

כפי שנראה לעיל, RequestHandlerSelectors מאפשר שימוש ב- כל אוֹ אף אחד predicates אך ניתן להשתמש בהם גם לסינון ה- API לפי חבילת הבסיס, הערת המחלקה והערות השיטה.

PathSelectors מספק סינון נוסף עם פרדיקטים, הסורקים את נתיבי הבקשה של היישום שלנו. אנחנו יכולים להשתמש כל(), אף אחד(), regex (), או נְמָלָה().

בדוגמה שלהלן, אנו ננחה את סוואגר לכלול רק בקרים מחבילה מסוימת, עם נתיבים ספציפיים, באמצעות ה- נְמָלָה() לְבַסֵס:

@Bean API של Docket ציבורי () {החזר Docket חדש (DocumentationType.SWAGGER_2). בחר () .apis (RequestHandlerSelectors.basePackage ("com.baeldung.web.controller")). Paths (PathSelectors.ant ("/ foos / * ")) .build (); }

9.2. מידע מותאם אישית

Swagger מספק גם כמה ערכי ברירת מחדל בתגובתו, אותם אנו יכולים להתאים אישית, כגון "תיעוד Api", "נוצר על ידי דואר אלקטרוני ליצירת קשר" ו- "Apache 2.0".

כדי לשנות ערכים אלה, אנו יכולים להשתמש ב- apiInfo (ApiInfo apiInfo) שיטה - ApiInfo מחלקה המכילה מידע מותאם אישית על ה- API:

@Bean Docket API ממשק () {החזר Docket חדש (DocumentationType.SWAGGER_2). בחר () .apis (RequestHandlerSelectors.basePackage ("com.example.controller")) .paths (PathSelectors.ant ("/ foos / *") ) .build () .apiInfo (apiInfo ()); } פרטי ApiInfo apiInfo () {להחזיר ApiInfo חדש ("ה- REST API שלי", "תיאור מותאם אישית כלשהו של API.", "API TOS", "תנאי שירות", איש קשר חדש ("John Doe", "www.example). com "," [email protected] ")," רישיון API "," URL לרישיון API ", Collections.emptyList ()); }

9.3. הודעות תגובה על שיטות מותאמות אישית

סוואגר מאפשר הודעות תגובה עולמיות של שיטות HTTP דרך תָוִיתשל globalResponseMessage ()שיטה.

ראשית, עלינו להורות לסוואגר לא להשתמש בהודעות תגובה המוגדרות כברירת מחדל. נניח שאנחנו רוצים לעקוף 500 ו 403 הודעות תגובה לכולם לקבל שיטות.

כדי להשיג זאת, יש להוסיף קוד כלשהו ל- תָוִיתחסימת האתחול (הקוד המקורי אינו נכלל לשם הבהרה):

.useDefaultResponseMessages (false) .globalResponseMessage (RequestMethod.GET, newArrayList (new ResponseMessageBuilder (). code (500) .message ("500 message") .responseModel (ModelRef new ("Error)).. ) .code (403) .message ("אסור!") .build ()));

10. החלף ממשק משתמש עם ממשק API מאובטח של OAuth

ממשק המשתמש של Swagger מספק מספר תכונות שימושיות מאוד שכבר כיסינו היטב עד כה. אך איננו יכולים להשתמש ברוב אלה באמת אם ה- API שלנו מאובטח ואינו נגיש.

בואו נראה כיצד נוכל לאפשר לסוואגר גישה ל- API מאובטח OAuth באמצעות סוג המענק של קוד ההרשאה בדוגמה זו.

נגדיר את Swagger לגישה ל- API המאובטח שלנו באמצעות ה- מערכת אבטחה ו אבטחה הקשר תמיכה:

@Bean API של Docket ציבורי () {החזר Docket חדש (DocumentationType.SWAGGER_2). בחר () .apis (RequestHandlerSelectors.any ()). Paths (PathSelectors.any ()) .build () .securitySchemes (Arrays.asList (securityScheme) ())) .securityContexts (Arrays.asList (securityContext ())); }

10.1. תצורת האבטחה

נגדיר א תצורת אבטחה שעועית בתצורת Swagger שלנו והגדר כמה ברירות מחדל:

@Bean SecurityConfiguration אבטחה ציבורית () {להחזיר SecurityConfigurationBuilder.builder () .clientId (CLIENT_ID) .clientSecret (CLIENT_SECRET) .scopeSeparator ("") .useBasicAuthenticationWithAccessCodeGrant (true) .build (); }

10.2. מערכת אבטחה

לאחר מכן נגדיר את שלנו מערכת אבטחה; זה משמש לתיאור האופן שבו מאובטח ה- API שלנו (אימות בסיסי, OAuth2, ...).

במקרה שלנו כאן, נגדיר ערכת OAuth המשמשת לאבטחת שרת המשאבים שלנו:

פרטית SecurityScheme securityScheme () {GrantType grantType = new AuthorizationCodeGrantBuilder () .tokenEndpoint (TokenEndpoint חדש (AUTH_SERVER + "/ אסימון", "oauthtoken")) .tokenRequestEndpoint (TokenRequestEndpoint חדש (AUTH_SERVER + ") / author_. לִבנוֹת(); SecurityScheme oauth = OAuthBuilder חדש (). שם ("spring_oauth") .grantTypes (Arrays.asList (grantType)) .scopes (Arrays.asList (scopes ())) .build (); להחזיר oauth; }

שים לב שהשתמשנו בסוג המענק של קוד ההרשאה, שעבורו עלינו לספק נקודת קצה אסימונית ואת כתובת ה- URL של ההרשאה של שרת ההרשאה OAuth2 שלנו.

והנה היקפים שאנחנו צריכים להגדיר:

פרטי AuthorizationScope [] scopes () {AuthorizationScope [] scopes = {new AuthorizationScope ("read", "for read operations"), AuthorizationScope חדש ("write", "for פעולות כתיבה"), AuthorizationScope חדש ("foo", " גישה ל- foo API ")}; טווחי החזרה; }

אלה מסתנכרנים עם היקפים שהגדרנו בפועל ביישום שלנו, עבור / foos ממשק API.

10.3. אבטחה הקשר

לבסוף, עלינו להגדיר א אבטחה הקשר לדוגמא API שלנו:

פרטי SecurityContext securityContext () {return SecurityContext.builder () .securityReferences (Arrays.asList (SecurityReference חדש ("spring_oauth", scopes ()))). forPaths (PathSelectors.regex ("/ foos. *")) .build (build) ); }

שימו לב איך השם שהשתמשנו כאן בהפניה - אביב_אוות - מסתנכרן עם השם שהשתמשנו בו בעבר ב- מערכת אבטחה.

10.4. מִבְחָן

כעת, לאחר שהכל מוגדר ומוכן לדרך, בואו נסתכל על ממשק המשתמש של Swagger וננסה לגשת ל- Foo API.

אנו יכולים לגשת לממשק המשתמש של Swagger באופן מקומי:

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

כפי שאנו רואים, לחצן הרשאה חדש קיים כעת עקב תצורות האבטחה שלנו:

כאשר אנו לוחצים על כפתור ההרשאה, אנו יכולים לראות את החלון הקופץ הבא כדי לאשר את ממשק המשתמש של Swagger לגשת לממשק ה- API המאובטח:

ציין זאת:

  • אנו כבר יכולים לראות את CLIENT_ID ו- CLIENT_SECRET, שכן הגדרנו אותם קודם לכן (אך עדיין נוכל לשנות אותם).
  • כעת אנו יכולים לבחור את ההיקפים הדרושים לנו.

כך מסומן ה- API המאובטח:

ועכשיו, סוף סוף, אנו יכולים להכות את ה- API שלנו!

כמובן, כמעט מובן מאליו שעלינו להיזהר כיצד אנו חושפים את ממשק המשתמש של Swagger באופן חיצוני, כעת כאשר תצורת האבטחה הזו פעילה.

11. מסקנה

במאמר זה, הגדרנו את Swagger 2 כדי ליצור תיעוד עבור ממשק API של REST של Spring. בדקנו גם דרכים לדמיין ולהתאים אישית את הפלט של סוואגר. ולבסוף, הסתכלנו על תצורת OAuth פשוטה עבור סוואגר.

ה יישום מלא של מדריך זה ניתן למצוא בפרויקט GitHub. כדי לראות את ההתקנה בפרויקט אתחול, עיין במודול GitHub זה.

עבור החלק OAuth, הקוד זמין במאגר האביב-אבטחה-oauth שלנו.

ואם אתה סטודנט של REST With Spring, עבור לשיעור 1 ממודול 7 לצלילה עמוקה להגדרת Swagger עם Spring and Spring Boot.

תחתית אבטחה

הרגע הכרזתי על הקורס החדש ללמוד Spring Spring Security, כולל החומר המלא שהתמקד בערמת OAuth2 החדשה ב- Spring Security 5:

>> בדוק את הקורס REST תחתון

רק הכרזתי על החדש למד אביב קורס, המתמקד ביסודות האביב 5 ומגף האביב 2:

>> בדוק את הקורס