Membina Perkhidmatan Mikro JHipster yang Dijamin UAA Asas

1. Gambaran keseluruhan

Dalam artikel sebelumnya, kami telah membahas asas-asas JHipster dan cara menggunakannya untuk menghasilkan aplikasi berasaskan perkhidmatan mikro.

Dalam tutorial ini, kami akan meneroka perkhidmatan Akaun Pengguna dan Kebenaran JHipster - UAA secara ringkas - dan cara menggunakannya untuk mendapatkan aplikasi perkhidmatan mikro berasaskan JHispter yang lengkap. Lebih baik lagi, semua ini dapat dicapai tanpa menulis satu baris kod !

2. Ciri Teras UAA

Ciri penting dari aplikasi yang kami bina dalam artikel kami sebelumnya adalah bahawa akaun pengguna merupakan bahagian yang tidak terpisahkan dari mereka. Sekarang, ini baik-baik saja apabila kita mempunyai satu aplikasi, tetapi bagaimana jika kita ingin berkongsi akaun pengguna antara beberapa aplikasi yang dihasilkan oleh JHipster? Di sinilah UAA JHipster masuk.

JHipster's UAA adalah perkhidmatan mikro yang dibina, digunakan, dan dijalankan secara bebas daripada perkhidmatan lain dalam aplikasi kami . Ia berfungsi sebagai:

  • Pelayan Pengesahan OAuth2, berdasarkan pelaksanaan Spring Boot
  • Pelayan Pengurusan Identiti, mendedahkan CRUD API akaun pengguna

JHipster UAA juga menyokong ciri log masuk khas seperti pendaftaran diri dan "ingat saya". Dan tentu saja, ia sepenuhnya berintegrasi dengan perkhidmatan JHipster lain.

3. Persediaan Persekitaran Pembangunan

Sebelum memulakan sesuatu pembangunan, kita mesti memastikan persekitaran kita mempunyai semua prasyaratnya. Selain semua alat yang dijelaskan dalam artikel Intro To JHipster kami, kami memerlukan JHipster Registry yang sedang berjalan. Sama seperti ringkasan ringkas, perkhidmatan pendaftaran membenarkan pelbagai perkhidmatan yang akan kami buat untuk mencari dan bercakap antara satu sama lain.

Prosedur lengkap untuk membuat dan menjalankan pendaftaran dijelaskan dalam bahagian 4.1 dari JHipster kami dengan artikel Senibina Mikro Layanan sehingga kami tidak akan mengulanginya di sini. Gambar Docker juga tersedia dan boleh digunakan sebagai alternatif.

4. Menjana Perkhidmatan JHipster UAA Baru

Mari jana perkhidmatan UAA kami menggunakan utiliti baris arahan JHipster:

$ mkdir uaa $ cd uaa $ jhipster 

Soalan pertama yang harus kita jawab adalah jenis aplikasi yang ingin kita hasilkan. Dengan menggunakan kekunci anak panah, kami akan memilih pilihan "JHipster UAA (untuk pengesahan microservice OAuth2)":

Seterusnya, kami akan diminta untuk beberapa pertanyaan mengenai perincian khusus mengenai perkhidmatan yang dihasilkan, seperti nama aplikasi, port pelayan dan penemuan perkhidmatan:

Sebahagian besarnya, jawapan lalai adalah baik. Mengenai nama asas aplikasi, yang mempengaruhi banyak artifak yang dihasilkan , kami telah memilih "uaa" (huruf kecil) - nama yang masuk akal. Kita boleh bermain dengan nilai-nilai lain jika kita mahu, tetapi ia tidak akan mengubah ciri utama projek yang dihasilkan.

Setelah menjawab soalan-soalan ini, JHipster akan membuat semua fail projek dan memasang pergantungan pakej npm (yang tidak benar-benar digunakan dalam kes ini).

Kami sekarang boleh menggunakan skrip Maven tempatan untuk membina dan menjalankan perkhidmatan UAA kami:

$ ./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: //localhost:9999/ External: //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! ---------------------------------------------------------- 

Mesej utama yang perlu diberi perhatian di sini adalah yang menyatakan bahawa UAA dihubungkan ke JHipster Registry. Mesej ini menunjukkan bahawa UAA dapat mendaftar sendiri dan akan dapat ditemui oleh perkhidmatan mikro dan gerbang lain.

5. Menguji Perkhidmatan UAA

Oleh kerana perkhidmatan UAA yang dihasilkan tidak mempunyai UI dengan sendirinya, kita mesti menggunakan panggilan API langsung untuk menguji apakah ia berfungsi seperti yang diharapkan.

Terdapat dua fungsi yang mesti kita pastikan berfungsi sebelum menggunakannya dengan bahagian lain atau sistem kita: penjanaan token OAuth2 dan pengambilan akaun.

Mula-mula, mari dapatkan token baru dari titik akhir OAuth UAA kami , menggunakan arahan ikal sederhana :

$ curl -X POST --data \ "username=user&password=user&grant_type=password&scope=openid" \ //web_app:[email protected]:9999/oauth/token 

Di sini, kami telah menggunakan aliran pemberian kata laluan , menggunakan dua pasang kelayakan. Dalam aliran seperti ini, kami menghantar kelayakan pelanggan menggunakan pengesahan HTTP asas, yang kami kodkan secara langsung di URL.

Kredensial pengguna akhir dihantar sebagai bahagian badan, menggunakan parameter nama pengguna dan kata laluan standard. Kami juga menggunakan akaun pengguna bernama "pengguna" , yang tersedia secara lalai dalam profil ujian.

Dengan andaian kami telah memberikan semua butiran dengan betul, kami akan mendapat jawapan yang mengandungi token akses dan token penyegaran:

{ "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" }

Kami sekarang dapat menggunakan access_token yang dikembalikan untuk mendapatkan maklumat untuk akaun yang berkaitan dengan menggunakan sumber akaun , yang tersedia di perkhidmatan UAA:

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

Harap maklum bahawa kami mesti mengeluarkan perintah ini sebelum token akses tamat . Secara lalai, perkhidmatan UAA mengeluarkan token yang sah selama lima minit, yang merupakan nilai masuk akal untuk pengeluaran.

Kami dengan mudah dapat mengubah jangka hayat token yang sah dengan mengedit fail aplikasi .yml yang sesuai dengan profil tempat kami menjalankan aplikasi dan menetapkan kunci uaa.web-client-config.access-token-validity-in-seconds . Fail tetapan berada di direktori src / main / resources / config projek UAA kami.

6. Generating the UAA-Enabled Gateway

Now that we're confident our UAA service and service registry are working, let's create an ecosystem for these to interact with. By the end, we'll have added:

  • An Angular-based front-end
  • A microservice back-end
  • An API Gateway that fronts both of these

Let's actually begin with the gateway, as it will be the service that will negotiate with UAA for authentication. It's going to host our front-end application and route API requests to other microservices.

Once again, we'll use the JHipster command-line tool inside a newly created directory:

$ mkdir gateway $ cd gateway $ jhipster

As before, we have to answer a few questions in order to generate the project. The important ones are the following:

  • Application type: must be “Microservices gateway”
  • Application name: We'll use “gateway” this time
  • Service discovery: Select “JHipster registry”
  • Authentication type:We must select the “Authentication with JHipster UAA server” option here
  • UI Framework: Let's pick “Angular 6”

Once JHipster generates all its artifacts, we can build and run the gateway with the provided Maven wrapper script:

$ ./mwnw ... many messages omitted ---------------------------------------------------------- Application 'gateway' is running! Access URLs: Local: //localhost:8080/ External: //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! ---------------------------------------------------------- 

With the above message, we can access our application by pointing our browser to //localhost:8080, which should display the default generated homepage:

Let's go ahead and log into our application, by navigating to the Account > Login menu item. We'll use admin/admin as credentials, which JHipster creates automatically by default. All going well, the welcome page will display a message confirming a successful logon:

Let's recap what happened to get us here: First, the gateway sent our credentials to UAA's OAuth2 token endpoint, which validated them and generated a response containing an access and a refresh JWT token. The gateway then took those tokens and sent them back to the browser as cookies.

Next, the Angular front-end called the /uaa/api/account API, which once again the gateway forwarded to UAA. In this process, the gateway takes the cookie containing the access token and use its value to add an authorization header to the request.

If needed, we can see all this flow in great detail by checking both UAA and Gateway's logs. We can also get full wire-level data by setting the org.apache.http.wire logger level to DEBUG.

7. Generating a UAA-Enabled Microservice

Now that our application environment is up and running, it's time to add a simple microservice to it. We'll create a “quotes” microservice, which will expose a full REST API that allows us to create, query, modify, and delete a set of stock quotes. Each quote will have only three properties:

  • The quote's trade symbol
  • Its price, and
  • The last trade's timestamp

Let's go back to our terminal and use JHipster's command-line tool to generate our project:

$ mkdir quotes $ cd quotes $ jhipster 

This time, we'll ask JHipster to generate a Microservice application, which we'll call “quotes”. The questions are similar to the ones we've answered before. We can keep the defaults for most of them, except for these three:

  • Service Discovery: Select “JHipster Registry” since we're already using it in our architecture
  • Path to the UAA application: Since we're keeping all projects directories under the same folder, this will be ../uaa (unless we've changed it, of course)
  • Authentication Type: Select “JHipster UAA server”

Here's what a typical sequence of answers will look like in our case:

Once JHipster finishes generating the project, we can go ahead and build it:

$ mvnw ... many, many messages omitted ---------------------------------------------------------- Application 'quotes' is running! Access URLs: Local: //localhost:8081/ External: //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 

The message “Connected to the JHipster Registry config server!” is what we're looking for here. Its presence tells us that the microservice registered itself with the registry and, because of this, the gateway will be able to route requests to our “quotes” resource and display it on a nice UI, once we've created it. Since we're using a microservice architecture, we split this task into two parts:

  • Create the “quotes” resource back-end service
  • Create the “quotes” UI in the front-end (part of the gateway project)

7.1. Adding the Quotes Resource

First, we need to make sure the that the quotes microservice application is stopped — we can hit CTRL-C on the same console window that we previously used to run it.

Now, let's add an entity to the project using JHipster's tool. This time we'll use the import-jdl command, which will save us from the tedious and error-prone process of supplying all details individually. For additional information about the JDL format, please refer to the full JDL reference.

Next, we create a text file called quotes.jh containing our Quote entity definition, along with some code generation directives:

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 

We can now import this entity definition to our project:

$ jhipster import-jdl quotes.jh 

Note: during the import, JHipster will complain about a conflict while applying changes to the master.xml file. We can safely choose the overwrite option in this case.

We can now build and run our microservice again using mvnw. Once it's up, we can verify that the gateway picks up the new route accessing the Gateway view, available from the Administration menu. This time, we can see that there's an entry for the “/quotes/**” route, whichshows that the backend is ready to be used by the UI.

7.2. Adding the Quotes UI

Finally, let's generate the CRUD UI in the gateway project that we'll use to access our quotes. We'll use the same JDL file from the “quotes” microservice project to generate the UI components, and we'll import it using JHipster's import-jdl command:

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

During the import, JHipster will prompt a few times for the action it should take regarding conflicting files. In our case, we can simply overwrite existing resources, since we haven't done any customization.

Now we can restart the gateway and see what we've accomplished. Let's point our browser to the gateway at //localhost:8080, making sure we refresh its contents. The Entities menu should now have a new entry for the Quotes resource:

Clicking on this menu option brings up the Quotes listing screen:

As expected, the listing is empty — we haven't added any quotes yet! Let's try to add one by clicking the “Create New Quote Button” on the top right of this screen, which brings us to the create/edit form:

We can see that the generated form has all expected features:

  • Required fields are marked with a red indicator, which turns green once filled
  • Date/Time and numeric fields use native components to help with data entry
  • We can cancel this activity, which will leave data unchanged, or save our new or modified entity

After filling this form and hitting Save, we'll see the results on the listing screen. We can now see the new Quotes instancein the data grid:

As an admin, we also have access to the API menu item, which takes us to the standard Swagger API Developer Portal. In this screen, we can select one of the available APIs to exercise:

  • default: Gateway's own API that displays available routes
  • uaa: Account and User APIs
  • quotes: Quotes API

8. Next Steps

The application we've built so far works as expected and provides a solid base for further development. We'll most definitely also need to write some (or a lot of) custom code, depending on the complexity of our requirements. Some areas that are likely to need some work are:

  • UI look and feel customization: This is usually quite easy due to the way the front-end application is structured — we can go a long way simply by fiddling with CSS and adding some images
  • User repository changes: Some organizations already have some sort of internal user repository (e.g. an LDAP directory) — this will require changes on the UAA, but the nice part is that we only need to change it once
  • Finer grained authorization on entities:The standard security model used by the generated entity back-end does not have any kind of instance-level and/or field-level security — it's up to the developer to add those restrictions at the appropriate level (API or service, depending on the case)

Walaupun dengan ucapan tersebut, menggunakan alat seperti JHispter dapat banyak membantu ketika mengembangkan aplikasi baru. Ini akan membawa asas yang kukuh dan dapat mengekalkan tahap konsistensi yang baik dalam pangkalan kod kami kerana sistem - dan pembangun - berkembang.

9. Kesimpulannya

Dalam artikel ini, kami telah menunjukkan cara menggunakan JHispter untuk membuat aplikasi yang berfungsi berdasarkan seni bina perkhidmatan mikro dan pelayan UAA JHipster. Kami mencapainya tanpa menulis satu baris kod Java , yang cukup mengagumkan.

Seperti biasa, kod penuh untuk projek yang disajikan dalam artikel ini terdapat di repositori GitHub kami.