本教程来自baeldung,主要展示通过JHipster自动生成有安全验证的微服务应用,整个过程无需编写一行Java代码,包括Angular前端和微服务后端。以下是主要步骤翻译,更详细截图对照原文:
在本教程中,我们将探索JHipster的用户帐户和授权服务 - 简称UAA - 以及如何使用它来保护完全成熟的基于JHispter的微服务应用程序。更好的是,所有这些都可以在不编写任何代码的情况下实现!
JHipster的UAA是一个微服务,它在我们的应用程序中独立于其他服务构建,部署和运行。它用作:
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:<font><i>//localhost:9999/</i></font><font> External: http:</font><font><i>//192.168.99.1:9999/</i></font><font> 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! ---------------------------------------------------------- </font>
关键信息是:Connected to the JHipster Registry config server!,这表明UAA能够自行注册,并可供其他微服务和网关发现。
2. 测试UAA服务
由于生成的UAA服务本身没有UI,因此我们必须使用直接API调用来测试它是否按预期工作。
在将其与其他部分或我们的系统一起使用之前,我们必须确保有两个功能: OAuth2令牌生成和帐户检索。
首先,让我们使用简单的 curl命令从UAA的OAuth端点获取一个新令牌:
$ curl -X POST --data / <font>"username=user&password=user&grant_type=password&scope=openid"</font><font> / http:</font><font><i>//web_app:changeit@localhost:9999/oauth/token</i></font><font> </font>
在这里,我们使用 密码授权 流程,使用两对凭证。在这种流程中,我们使用基本的HTTP身份验证发送客户端凭据,我们直接在URL中进行编码。最终用户凭据使用标准用户名和密码参数作为正文的一部分发送。我们还使用名为“user”的用户帐户,默认情况下,该帐户 在测试配置文件中可用。
假设我们已正确提供所有详细信息,我们将获得包含访问令牌和刷新令牌的答案:
{ <font>"access_token"</font><font> : </font><font>"eyJh...(token omitted)"</font><font>, </font><font>"token_type"</font><font> : </font><font>"bearer"</font><font>, </font><font>"refresh_token"</font><font> : </font><font>"eyJ...(token omitted)"</font><font>, </font><font>"expires_in"</font><font> : 299, </font><font>"scope"</font><font> : </font><font>"openid"</font><font>, </font><font>"iat"</font><font> : 1539650162, </font><font>"jti"</font><font> : </font><font>"8066ab12-6e5e-4330-82d5-f51df16cd70f"</font><font> } </font>
我们现在可以使用返回的 access_token来访问帐户资源获取相关帐户的信息,该 帐户资源在UAA服务中可用:
$ curl -H <font>"Authorization: Bearer eyJh...(access token omitted)"</font><font> / http:</font><font><i>//localhost:9999/api/account</i></font><font> { </font><font>"id"</font><font> : 4, </font><font>"login"</font><font> : </font><font>"user"</font><font>, </font><font>"firstName"</font><font> : </font><font>"User"</font><font>, </font><font>"lastName"</font><font> : </font><font>"User"</font><font>, </font><font>"email"</font><font> : </font><font>"user@localhost"</font><font>, </font><font>"imageUrl"</font><font> : </font><font>""</font><font>, </font><font>"activated"</font><font> : <b>true</b>, </font><font>"langKey"</font><font> : </font><font>"en"</font><font>, </font><font>"createdBy"</font><font> : </font><font>"system"</font><font>, </font><font>"createdDate"</font><font> : </font><font>"2018-10-14T17:07:01.336Z"</font><font>, </font><font>"lastModifiedBy"</font><font> : </font><font>"system"</font><font>, </font><font>"lastModifiedDate"</font><font> : <b>null</b>, </font><font>"authorities"</font><font> : [ </font><font>"ROLE_USER"</font><font> ] } </font>
请注意,我们必须在访问令牌到期之前发出此命令。默认情况下,UAA服务发出的令牌有效期为五分钟,这对于生产来说是一个明智的价值。
我们可以通过编辑与我们运行应用程序的配置文件相对应的application-<profile>.yml 文件,修改其中的uaa.web-client-configuration.access-token-validity-in-seconds 更改有效令牌的生命周期。这个文件位于 UAA项目的src/main/resources/config目录下。
3. 生成启用UAA的网关
现在我们确信我们的UAA服务和服务注册表正在运行,让我们创建一个与之互动的生态系统。最后,我们将添加:
让我们从网关开始,因为它将是与UAA协商进行身份验证的服务。它将托管我们的前端应用程序并将API请求路由到其他微服务。我们将在新创建的目录中使用JHipster命令行工具:
$ mkdir gateway $ cd gateway $ jhipster
和以前一样,我们必须回答几个问题才能生成项目。重要的是以下内容:
一旦JHipster生成了所有工件,我们就可以使用提供的Maven包装器脚本构建和运行网关:
$ ./mwnw ... many messages omitted ---------------------------------------------------------- Application 'gateway' is running! Access URLs: Local: http:<font><i>//localhost:8080/</i></font><font> External: http:</font><font><i>//192.168.99.1:8080/</i></font><font> 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! ---------------------------------------------------------- </font>
将浏览器指向 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完成项目的生成,我们就可以继续构建它:
$ mvnw ... many, many messages omitted ---------------------------------------------------------- Application 'quotes' is running! Access URLs: Local: http:<font><i>//localhost:8081/</i></font><font> External: http:</font><font><i>//192.168.99.1:8081/</i></font><font> 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 </font>
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 <b>import</b>-jdl quotes.jh
注意:在导入期间,JHipster会在对master.xml文件应用更改时抱怨冲突 。在这种情况下,我们可以选择 overwrite 覆盖选项。
我们现在可以使用mvnw再次构建和运行我们的微服务 。 一旦启动,我们就可以验证网关是否选择了访问网关视图的新路由 ,可从“ 管理”菜单中获取。这一次,我们可以看到“/ quotes / **”路由有一个条目, 表明后端已准备好供UI使用。
6.添加报价UI
最后,让我们在网关项目中生成CRUD UI,我们将用它来访问我们的报价。我们将使用“quotes”微服务项目中的相同JDL文件来生成UI组件,我们将使用JHipster的import-jdl命令导入它:
$ jhipster <b>import</b>-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进行练习:
7.后续步骤
到目前为止,我们构建的应用程序按预期工作,为进一步开发提供了坚实的基础。我们绝对还需要编写一些(或很多)自定义代码,具体取决于我们要求的复杂程度。一些可能需要一些工作的领域是:
即使有这些评论,使用像JHispter这样的工具在开发新应用程序时也会有很大帮助。它将带来坚实的基础,并且随着系统和开发人员的发展,我们的代码库可以保持良好的一致性。
本文中提供的项目的完整代码可以在我们的 GitHub存储库中找到