無需Java程式碼透過JHipster生成有安全驗證的微服務應用

banq發表於2018-12-25

本教程來自baeldung,主要展示透過JHipster自動生成有安全驗證的微服務應用,整個過程無需編寫一行Java程式碼,包括Angular前端和微服務後端。以下是主要步驟翻譯,更詳細截圖對照原文:
在本教程中,我們將探索JHipster的使用者帳戶和授權服務  - 簡稱UAA - 以及如何使用它來保護完全成熟的基於JHispter的微服務應用程式。更好的是,所有這些都可以在不編寫任何程式碼的情況下實現!

JHipster的UAA是一個微服務,它在我們的應用程式中獨立於其他服務構建,部署和執行。它用作:
  • OAuth2授權伺服器,基於Spring Boot的實現
  • 身份管理伺服器,公開使用者帳戶CRUD API

JHipster UAA還支援典型的登入功能,如自我註冊和“記住我”。當然,它與其他JHipster服務完全整合。

在開始任何開發之前,需要一個正在執行的JHipster Registry註冊中心,註冊服務允許我們建立的不同服務來查詢和相互通訊。

1.生成新的JHipster UAA服務
使用JHipster命令列實用程式生成我們的UAA服務:

$ mkdir uaa
$ cd uaa
$ jhipster


這提示我們回答一些問題進行定製,第一個問題是我們想要生成哪種型別的應用程式。使用箭頭鍵,我們將選擇“JHipster UAA(用於微服務OAuth2身份驗證)”選項。
接下來是應用程式名稱,伺服器埠和服務發現的輸入。在大多數情況下,預設答案都很好。
應用程式的基本名稱會影響了許多生成的工件,我們選擇了“uaa”(小寫) 

回答完這些問題之後,JHipster將建立所有專案檔案並安裝npm包依賴項(在這種情況下並不真正使用)。我們現在可以使用本地Maven指令碼來構建和執行我們的UAA服務:

$ ./mvnw
... build messages omitted
2018-10-14 14:07:17.995  INFO 18052 --- [  restartedMain] com.baeldung.jhipster.uaa.UaaApp         :
----------------------------------------------------------
        Application 'uaa' is running! Access URLs:
        Local:          http://localhost:9999/
        External:       http://192.168.99.1:9999/
        Profile(s):     [dev, swagger]
----------------------------------------------------------
2018-10-14 14:07:18.000  INFO 18052 --- [  restartedMain] com.baeldung.jhipster.uaa.UaaApp         :
----------------------------------------------------------
        Config Server:  Connected to the JHipster Registry config server!
----------------------------------------------------------


關鍵資訊是:Connected to the JHipster Registry config server!,這表明UAA能夠自行註冊,並可供其他微服務和閘道器發現。

2. 測試UAA服務
由於生成的UAA服務本身沒有UI,因此我們必須使用直接API呼叫來測試它是否按預期工作。
在將其與其他部分或我們的系統一起使用之前,我們必須確保有兩個功能: OAuth2令牌生成和帳戶檢索。
首先,讓我們使用簡單的  curl命令從UAA的OAuth端點獲取一個新令牌:

$ curl -X POST --data \
 "username=user&password=user&grant_type=password&scope=openid" \
 http://web_app:changeit@localhost:9999/oauth/token


在這裡,我們使用  密碼授權 流程,使用兩對憑證。在這種流程中,我們使用基本的HTTP身份驗證傳送客戶端憑據,我們直接在URL中進行編碼。終端使用者憑據使用標準使用者名稱和密碼引數作為正文的一部分傳送。我們還使用名為“user”的使用者帳戶,預設情況下,該帳戶  在測試配置檔案中可用。
假設我們已正確提供所有詳細資訊,我們將獲得包含訪問令牌和重新整理令牌的答案:

{
  "access_token" : "eyJh...(token omitted)",
  "token_type" : "bearer",
  "refresh_token" : "eyJ...(token omitted)",
  "expires_in" : 299,
  "scope" : "openid",
  "iat" : 1539650162,
  "jti" : "8066ab12-6e5e-4330-82d5-f51df16cd70f"
}


我們現在可以使用返回的  access_token來訪問帳戶資源獲取相關帳戶的資訊,該  帳戶資源在UAA服務中可用:

$ curl -H "Authorization: Bearer eyJh...(access token omitted)" \ 
 http://localhost:9999/api/account
{
  "id" : 4,
  "login" : "user",
  "firstName" : "User",
  "lastName" : "User",
  "email" : "user@localhost",
  "imageUrl" : "",
  "activated" : true,
  "langKey" : "en",
  "createdBy" : "system",
  "createdDate" : "2018-10-14T17:07:01.336Z",
  "lastModifiedBy" : "system",
  "lastModifiedDate" : null,
  "authorities" : [ "ROLE_USER" ]
}


請注意,我們必須在訪問令牌到期之前發出此命令。預設情況下,UAA服務發出的令牌有效期為五分鐘,這對於生產來說是一個明智的價值。
我們可以透過編輯與我們執行應用程式的配置檔案相對應的application-<profile>.yml 檔案,修改其中的uaa.web-client-configuration.access-token-validity-in-seconds 更改有效令牌的生命週期。這個檔案位於 UAA專案的src/main/resources/config目錄下。

3. 生成啟用UAA的閘道器
現在我們確信我們的UAA服務和服務登錄檔正在執行,讓我們建立一個與之互動的生態系統。最後,我們將新增:

  • 基於Angular的前端
  • 一個微服務後端
  • 一個支援這兩者的API閘道器

讓我們從閘道器開始,因為它將是與UAA協商進行身份驗證的服務。它將託管我們的前端應用程式並將API請求路由到其他微服務。我們將在新建立的目錄中使用JHipster命令列工具:

$ mkdir gateway
$ cd gateway
$ jhipster


和以前一樣,我們必須回答幾個問題才能生成專案。重要的是以下內容:
  • 應用型別:  必須是“Microservices gateway/微服務閘道器”
  • 申請名稱:這次我們將使用“gateway/閘道器”
  • 服務發現:選擇“JHipster registry /JHipster登錄檔”
  • 身份驗證型別: 我們必須在此處選擇“Authentication with JHipster UAA server/使用JHipster UAA伺服器進行身份驗證”選項
  • UI框架:  讓我們選擇“Angular 6”

一旦JHipster生成了所有工件,我們就可以使用提供的Maven包裝器指令碼構建和執行閘道器:

$ ./mwnw
... many messages omitted
----------------------------------------------------------
        Application 'gateway' is running! Access URLs:
        Local:          http://localhost:8080/
        External:       http://192.168.99.1:8080/
        Profile(s):     [dev, swagger]
----------------------------------------------------------
2018-10-15 23:46:43.011  INFO 21668 --- [  restartedMain] c.baeldung.jhipster.gateway.GatewayApp   :
----------------------------------------------------------
        Config Server:  Connected to the JHipster Registry config server!
----------------------------------------------------------


將瀏覽器指向http://localhost:8080來訪問我們的應用程式,它應顯示預設生成的主頁。

讓我們繼續登入我們的應用程式,導航到  Account> Login選單項。我們將使用admin / admin 作為憑據,JHipster預設自動建立。一切順利,歡迎頁面將顯示確認登入成功的訊息:you are logged as use "admin"!

回顧一下l流程: 首先,閘道器將我們的憑據傳送到UAA的OAuth2令牌端點,該端點驗證它們並生成包含訪問和重新整理JWT令牌的響應。然後閘道器獲取這些令牌並將其作為cookie傳送回瀏覽器。

接下來,  訪問/ uaa / api / account API的Angular前端,閘道器再次轉發給UAA。在此過程中,閘道器獲取包含訪問令牌的cookie,並使用其值為請求新增授權頭。
如果需要,我們可以透過檢查UAA和Gateway的日誌來詳細瞭解所有這些流程。我們還可以透過將org.apache.http.wire記錄器級別設定為DEBUG來獲取完整的路由步驟級資料  。

4.生成支援UAA的微服務
現在我們的應用程式環境已經啟動並執行,現在是時候新增一個簡單的微服務了。我們將建立一個“quotes”微服務,它將公開一個完整的REST API,允許我們建立,查詢,修改和刪除一組股票報價。每個報價只有三個屬性:

  • 報價的交易程式碼
  • 它的價格,和
  • 最後一筆交易的時間戳

回到我們的終端並使用JHipster的命令列工具來生成我們的專案:

$ mkdir quotes
$ cd quotes
$ jhipster


這次,我們將要求JHipster生成一個微服務應用程式,我們將其稱為“quotes”。問題類似於我們之前回答的問題。我們可以保留其中大多數的預設值,除了這三個:
  • 服務發現:  選擇“JHipster Registry”,因為我們已經在我們的架構中使用它
  • UAA應用程式的路徑:由於我們將所有專案目錄儲存在同一資料夾下,這將是../uaa (當然,除非我們已經更改了它)
  • 身份驗證型別:選擇“JHipster UAA伺服器”

一旦JHipster完成專案的生成,我們就可以繼續構建它:

$ mvnw
... many, many messages omitted
----------------------------------------------------------
        Application 'quotes' is running! Access URLs:
        Local:          http://localhost:8081/
        External:       http://192.168.99.1:8081/
        Profile(s):     [dev, swagger]
----------------------------------------------------------
2018-10-19 00:16:05.581  INFO 16092 --- [  restartedMain] com.baeldung.jhipster.quotes.QuotesApp   :
----------------------------------------------------------
        Config Server:  Connected to the JHipster Registry config server!
----------------------------------------------------------
... more messages omitted


5. 新增報價資源
讓我們使用JHipster的工具向專案新增一個實體。這次我們將使用  import-jdl命令,這將使我們免於單獨提供所有細節的繁瑣且容易出錯的過程。有關JDL格式的其他資訊,請參閱完整的JDL參考
接下來,我們建立一個名為quotes.jh的文字檔案,  其中包含我們的  Quote 實體定義,以及一些程式碼生成指令:

entity Quote {
  symbol String required unique,
  price BigDecimal required,
  lastTrade ZonedDateTime required
}
dto Quote with mapstruct
paginate Quote with pagination
service Quote with serviceImpl
microservice Quote with quotes
filter Quote
clientRootFolder Quote with quotes


我們現在可以將此實體定義匯入到我們的專案中:

$ jhipster import-jdl quotes.jh


注意:在匯入期間,JHipster會在對master.xml檔案應用更改時抱怨衝突  。在這種情況下,我們可以選擇 overwrite  覆蓋選項。

我們現在可以使用mvnw再次構建和執行我們的微服務  。 一旦啟動,我們就可以驗證閘道器是否選擇了訪問閘道器檢視的新路由  ,可從“  管理”選單中獲取。這一次,我們可以看到“/ q​​uotes / **”路由有一個條目, 表明後端已準備好供UI使用。

6.新增報價UI
最後,讓我們在閘道器專案中生成CRUD UI,我們將用它來訪問我們的報價。我們將使用“quotes”微服務專案中的相同JDL檔案來生成UI元件,我們將使用JHipster的import-jdl命令匯入它:

$ jhipster import-jdl ../jhipster-quotes/quotes.jh
...messages omitted
? Overwrite webpack\webpack.dev.js? <b>y</b>
... messages omitted
Congratulations, JHipster execution is complete!


在匯入期間,JHipster將提示幾次針對衝突檔案應採取的操作。在我們的例子中,我們可以簡單地覆蓋現有資源,因為我們還沒有進行任何自定義。

現在我們可以重新啟動閘道器,看看我們已經完成了什麼。讓我們將瀏覽器指向http://localhost:8080的閘道器,確保我們重新整理其內容。“ 實體”選單現在應該具有報價資源的新條目 .單擊此選單選項將顯示報價列表螢幕. 該列表是空的 - 我們尚未新增任何報價!讓我們嘗試透過單擊此螢幕右上角的“建立新引用按鈕”來新增一個,這將我們帶到建立/編輯表單.
作為管理員,我們還可以訪問API選單項,它將我們帶到標準的Swagger API Developer Portal。在此螢幕中,我們可以選擇一個可用的API進行練習:
  • default: Gateway: 顯示可用的路由
  • uaa:帳戶和使用者API
  • quotes: 報價API


7.後續步驟
到目前為止,我們構建的應用程式按預期工作,為進一步開發提供了堅實的基礎。我們絕對還需要編寫一些(或很多)自定義程式碼,具體取決於我們要求的複雜程度。一些可能需要一些工作的領域是:

  • UI外觀定製:由於前端應用程式的結構化方式,這通常很容易 - 我們可以透過簡單地使用CSS並新增一些影像來實現很長的路要走
  • 使用者儲存庫更改:某些組織已經擁有某種內部使用者儲存庫(例如LDAP目錄) - 這將需要對UAA進行更改,但不錯的部分是我們只需要更改一次
  • 對實體的細粒度授權: 生成的實體後端使用的標準安全模型沒有任何型別的例項級和/或欄位級安全性  - 開發人員可以在適當的級別新增這些限制(API或服務,視情況而定)

即使有這些評論,使用像JHispter這樣的工具在開發新應用程式時也會有很大幫助。它將帶來堅實的基礎,並且隨著系統和開發人員的發展,我們的程式碼庫可以保持良好的一致性。

本文中提供的專案的完整程式碼可以在我們的GitHub儲存庫中找到

相關文章