开始使用

本章节包含一个通过通用 REST API 获取应用程序中用户信息的示例。

首先,按照 扩展组件安装 章节添加 REST API 组件。

获取访问 token

如需访问受保护的资源,客户端必须提供有效的访问 token。OAuth 2.1 规范提供了从认证服务获取访问 token 的几种方式。称为授权类型。在本示例中,我们将使用 客户端凭证授权,这种类型适合需要保密的客户端,例如后端集成。

方案是,在 Jmix 应用程序中,我们必须注册这个客户端(客户端表示一个需要访问 Jmix REST API 的外部应用程序),定义客户端的 id 和秘钥,将来我们会使用这些凭证在特定的 HTTP 请求中获取访问 token。

负责分发 token 功能,以及支持所有 OAuth 2.1 和 OpenID Connect 1.0 协议的功能都已经在认证服务扩展组件中提供。这个扩展组件(io.jmix.authserver:jmix-authserver-starter)会在安装 REST API 组件时自动引入。认证服务扩展组件基于 Spring Authorization Server 构建。

注册客户端的最简单方式就是添加标准的 Spring 认证服务配置:

# The client id is my-client
spring.security.oauth2.authorizationserver.client.myclient.registration.client-id=my-client
# The client secret (password) is my-secret
spring.security.oauth2.authorizationserver.client.myclient.registration.client-secret={noop}my-secret
# Enable Client Credential grant for the my-client
spring.security.oauth2.authorizationserver.client.myclient.registration.authorization-grant-types=client_credentials
# Client credentials must be passed in the Authorization header using the HTTP Basic authentication scheme
spring.security.oauth2.authorizationserver.client.myclient.registration.client-authentication_methods=client_secret_basic
# Use opaque tokens instead of JWT
spring.security.oauth2.authorizationserver.client.myclient.token.access-token-format=reference

下一组应用程序属性是 Jmix 特有的,用来定义哪些资源角色和行级角色必须分配给发出的 token。本示例中,我们将分配两个资源角色:

  • rest-minimal(REST: minimal access) - 启用 REST API 端点访问。

  • user-management(用户管理)- 支持使用 REST API 操作 User 实体。

# my-client is the client id we configured previously
jmix.authserver.client.myclient.client-id = my-client
jmix.authserver.client.myclient.resource-roles = user-management, rest-minimal

user-management 角色定义如下:

@ResourceRole(name = "User management", code = UserManagementRole.CODE, scope = "API") (1)
public interface UserManagementRole {

    String CODE = "user-management";

    @EntityAttributePolicy(entityClass = User.class, attributes = "*", action = EntityAttributePolicyAction.MODIFY)
    @EntityPolicy(entityClass = User.class, actions = EntityPolicyAction.ALL)
    void user();
}
1 API 权限范围(scope)表示这个角色用于 REST API 请求。

完成属性定义后,应该可以获取访问 token 了。本示例中,我们将使用 curl 命令行工具与 REST API 交互。

curl -X POST http://localhost:8080/oauth2/token \
   --basic --user my-client:my-secret \
   -H "Content-Type: application/x-www-form-urlencoded" \
   -d "grant_type=client_credentials"
如果是 Windows 系统,需要删除 \ 符号,将命令写成一行。

结果类似如下:

HTTP/1.1 200
{
  "access_token":"hKhgNyGMTqaKd6prH-GoHF8zFVTSr9tKKyE3OnMoafRO4FT4Xq_cewHr28cIRITaRmF0olRXpVTyFdxcOPTAl8Vc7xopHrdNuXNXwEeBn7NSiEMvQXW5zO0dwMn_H8FQ",
  "token_type":"Bearer",
  "expires_in":299
}

access_token 属性值是用户 token,可作为请求头中的 Authorization 参数使用进行后续其他请求。Token 作为临时凭证,授予你访问应用程序的权限。

获取实体列表

使用 access token 就可以继续使用通用 REST API 接口获取用户列表(将 <access_token> 替换成上一步获取到的 token 值)。这里,我们通过 API 获取应用程序中当前所有的用户:

curl -X GET http://localhost:8080/rest/entities/User \
    -H "Authorization: Bearer <access_token>"

响应中包含应用程序中所有的用户:

HTTP/1.1 200
[
  {
    "_entityName": "User",
    "_instanceName": "[admin]",
    "id": "60885987-1b61-4247-94c7-dff348347f93",
    "version": 1,
    "active": true,
    "username": "admin"
  }
]