Skip to content

身份验证和授权

本节介绍 MindSphere 平台中有关身份验证和授权的最重要内容。本简介旨在帮助您在使用 MindSphere API 时能够快速启动和运行。 阅读本简介后,您将能够执行以下操作:

  • 通过 Cloud Foundry 应用调用 MindSphere API。
  • 通过前端应用调用 MindSphere API(例如通过 JavaScript 调用 AJAX)。
  • 根据应用特定范围保护应用的安全。

简介

所有 MindSphere 端点都受到安全保护,只有身份验证成功后才能与之连接。之后,您将通过本简介中描述的不同方法获取一个令牌。 该令牌将包含允许您执行哪些操作等信息,例如,允许您使用哪些 API。

获取通过您的应用调用 MindSphere API 的令牌

如果要通过您的应用调用 MindSphere API,需要有一个有效的令牌。

先决条件

在MindSphere中运行应用程序

您的应用程序需要一个有效的令牌来调用MindSphere api。如果有登录用户通过 launchpad 或通过直接调用应用 URL 访问您的应用,则会有一个 令牌(bearer 类型的令牌)以消息头的形式传递到应用请求中。

两种通过应用调用 MindSphere API 的方法:

  • 使用 gateway.{region}.{mindsphere-domain}/api/... 从后端(例如 Cloud Foundry)调用 API。
  • 从前端调用 API,类似于 {webAppHost}/api/...

从后端调用 API

从后端调用 MindSphere API 时,每个请求都需要发送一个 authorization 消息头。因此,您需要将该请求中的请求头信息提取到后端,然后在您的 MindSphere API 请求中使用 authorization 消息头。

Java

以下 Java 代码段打印出所有可用消息头并返回令牌。

private String extractToken(HttpServletRequest request) {
 Enumeration<String> headerNames = request.getHeaderNames();
 while (headerNames.hasMoreElements()) {
 String header = headerNames.nextElement();
 LOGGER.info("header " + header + " " + request.getHeader(header));
 }
 return request.getHeader("authorization");
}

令牌日志

生产代码中不输出任何类似令牌的机密日志!

当发送请求调用 重要 Urls部分列出的MindSphere APIs时,将令牌加入authorization 消息头。

Node.js

可以在 Node.js 中执行类似的操作。下面的简单示例使用 expressjssuperagent 进行 API 调用 - 将第 7 行中的 {region} 替换为您自己的区域。 以下Node.js代码段使用 expressjssuperagent 进行API调用 - 第7行包含占位符 region and MindSphere domain.

var request = require("superagent");
...

app.get('my-route', function (req, res) {
 authHeader = req.get("authorization");
 request
 .get('https://gateway.{region}.{mindsphere-domain}/api/identitymanagement/v3/Users?attributes=meta,name,userName,active')
 .set('Authorization', authHeader)
 .set('Accept', 'application/json')
 .then(function(data) {
 res.json({
 resources:data.body.resources
 });
 }).catch(err => {
 console.error(err.message, err.status);
 res.status(err.status).json({ message:'Failed to fetch users.'});
 });
});

...

从前端调用 API

从前端调用 API时,不再发送 authorization 消息头,而是重新使用设置为 cookie 的 sessionid,并发送由 MindSphere 网关作为cookie提供(例如 x-xsrf-token:e4edcb6c-bd1c-46c1-863c-421235c522a3)的消息头:

x-xsrf-token:{XSRF-TOKEN}

下面显示的是一个使用 Fetch API 的示例:

let myXRSFToken = ...

fetch('/api/identitymanagement/v3/Users', {
 credentials: 'include',
 headers: {
 "Content-Type": "application/json",
 "Accept": "application/json",
 "x-xsrf-token":myXRSFToken
 }
})
...

安全访问应用

开发者必须警惕任何不受信任或未经授权的用户访问您的应用。MindSphere使用角色,范围和令牌为每个注册的应用程序提供安全概念。有关此内容的更多信息,请参见角色和范围部分。

示例

在本例中,我们利用 expressjs 和一个定制中间件保护应用程序(每个端点),拦截每个请求并验证请求令牌是否包含应用的特定范围。

var jwt = require('jsonwebtoken');
var path = require('path');
var includes = require('lodash/includes')

const express = require('express')
const app = express()

// Middleware for checking the scopes in the user token
app.use('/', function (req, res, next) {
 const authorizationHeader = authHeader = req.get("authorization");
 var scopes = [];

 if (authorizationHeader != null) {
 token = jwt.decode(authorizationHeader.replace("bearer ", ""), { complete:true, json:true })
 scopes = token.payload.scope;
 }

 console.log("scopes: ", scopes); // output all scopes

 if (includes(scopes, `${config.mdsp.appname}.${config.mdsp.scope}`)) {
 console.log("request with valid application token")
 next();
 } else {
 console.log("unauthorized request");
 res.status(403).send('no access!');
 }
});
...

令牌日志

生产代码中不输出任何类似令牌的机密日志!

信息

切记,本示例仅作说明之用,不用于生产用途。 视应用的复杂程度而定,您可能需要使用不同的框架和多个范围来保护端点。

令牌验证

我们还建议对应用所使用的所有令牌进行验证。RFC 7519 对 JWT 访问令牌的验证进行了定义。

信息

关于如何验证JWT访问令牌的具体细节,参考 RFC 7519 和相关 RFCs, 特别是 RFC 7515RFC 7518.

验证建议

以下章节给出了验证令牌的更多提示。

提示

有一些库可用于验证 JWTs, 例如 https://jwt.io.

有效载荷验证

用以下载荷声明验证访问令牌:

声明 条件
iss 必须是受信任的签发方名称。默认情况下,应用只能信任其应用提供者的签发方(即,只信任由应用提供者的 Provider IAM 系统所签发的访问令牌)。在开发租户和操作租户上,应用的签发方遵循以下方案:https://{tenantName}.piam.{region}.{mindsphere-domain}/oauth/
exp 应在当前日期/时间之后。开发人员可以留出几分钟的余地,以允许时钟偏移。
iat 应早于或等于当前日期/时间。开发人员可以留出几分钟的余地来允许时钟偏移。

MindSphere发行的令牌中不包含 nbf 声明。
scope 应与web应用程序或web API所期望的值匹配, 例如 api1.do.
aud 如果受众是在范围值中编码的,则此步骤是可选的。
应与web应用程序或web API所期望的值匹配,例如 api1.

签名验证

  1. 通过检查alg 声明的值来验证访问令牌是使用受信任的预期算法进行签发。 MindSphere不使用 alg = none签发JWT。 目前, MindSphere用 RS256签发所有令牌。
  2. 验证令牌头中 kid 声明使用 token issuer中的有效公钥。
  3. 验证公钥签名使用引用的算法和公钥。

    用于验证签名的公钥

    MindSphere操作员或开发人员租户颁发的令牌签名验证公钥位于: https://{tenant_name}.piam.{region}.{mindsphere_domain}/token_keys。 确保使用TLS从 受信任源 下载公钥。 更多信息请参考 OAuth Authorization Server documentation.

    用于创建和验证令牌签名的密钥对在MindSphere中定期更新。使用这些密钥的组件应该定期检查更新。

相关链接


Last update: March 22, 2023