JWT 身份验证在 Hyperledger Composer 中失败
JWT Authentication fails in Hyperledger Composer
我一直在关注 Caroline's blog 以设置多用户 composer rest 服务器。所以,我有两台服务器即。管理服务器和用户服务器。
如教程一所述:
- 在没有身份验证和单用户模式的情况下启动管理服务器。我用管理员卡启动了这个服务器。
- 在多用户模式下使用护照 JWT 身份验证启动了用户服务器。我也用管理员卡启动了这个服务器。
- 创建了一个用户参与者并从管理服务器为用户生成了一张卡片。
- 在这一步中,我尝试与用户服务器 (#2) 交换 JWT 令牌,我也能够获得该令牌。
- 使用 JWT 令牌 Ping 用户服务器。这导致 "Error: Authorization Required".
我已关注 Chris Ganga's 博客以实现 JWT。我的 COMPOSER_PROVIDERS 是:
COMPOSER_PROVIDERS='{
"jwt": {
"provider": "jwt",
"module": "/home/composer/node_modules/custom-jwt.js",
"secretOrKey": "somesecretkey",
"authScheme": "saml",
"successRedirect": "/",
"failureRedirect":"/"
}
}'
我是第一次从 Java 服务交换 JWT 令牌。为了创建不记名令牌,我编写了以下代码:
public static String getBearerToken(String username, String id) throws UnsupportedEncodingException {
return Jwts.builder()
.claim("timestamp", System.currentTimeMillis())
.claim("username", username)
.claim("id", id)
.signWith(
SignatureAlgorithm.HS256,
"somesecretkey".getBytes("UTF-8")
).compact();
}
有了这个,我就能拿到令牌了。接下来,我使用此令牌将卡导入用户服务器上的钱包:
RestTemplate restTemplate = new RestTemplate();
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.MULTIPART_FORM_DATA);
headers.set("X-Access-Token",getAccess_token(participantEmail));
headers.set("x-api-key", userServerKey);
LinkedMultiValueMap<String, Object> params = new LinkedMultiValueMap<>();
params.add("card", new FileSystemResource(card));
params.add("name", participantEmail);
HttpEntity<LinkedMultiValueMap<String, Object>> requestEntity = new HttpEntity<>(params, headers);
UriComponentsBuilder builder = UriComponentsBuilder.fromHttpUrl(CARD_IMPORT_URL);
ResponseEntity<String> responseEntity = restTemplate.exchange(builder.build().encode().toUri(),
HttpMethod.POST, requestEntity, String.class);
但是,这会导致:
Unhandled error for request POST /api/Wallet/import: Error: Authorization Required
发现 1
通常,当我们第一次使用 auth bearer 交换 JWT 时,会在 mongo 中创建一个名为 "test" 的数据库。该数据库包含三个集合:accessToken、user 和 userIdentity。但是,就我而言,当我交换令牌时,没有在 mongo 中创建数据库。关于如何调试它有什么建议吗?
注意:
整个设置工作得非常好,直到我决定从头开始修剪并重新启动网络。
这里的问题是我在所有主机上为 mongodb 容器使用相同的名称。由于所有容器都连接到 swarm 网络,因此有 8 个 mongodb 容器同名,这是一个非常愚蠢的错误。当 composer-rest-server 的 docker 容器试图连接到 mongodb 容器时,它导致了一个问题。此连接在 COMPOSER_DATASOURCES 变量中定义。在所有主机上为每个 mongo 容器使用不同的名称解决了这个问题。
我一直在关注 Caroline's blog 以设置多用户 composer rest 服务器。所以,我有两台服务器即。管理服务器和用户服务器。
如教程一所述:
- 在没有身份验证和单用户模式的情况下启动管理服务器。我用管理员卡启动了这个服务器。
- 在多用户模式下使用护照 JWT 身份验证启动了用户服务器。我也用管理员卡启动了这个服务器。
- 创建了一个用户参与者并从管理服务器为用户生成了一张卡片。
- 在这一步中,我尝试与用户服务器 (#2) 交换 JWT 令牌,我也能够获得该令牌。
- 使用 JWT 令牌 Ping 用户服务器。这导致 "Error: Authorization Required".
我已关注 Chris Ganga's 博客以实现 JWT。我的 COMPOSER_PROVIDERS 是:
COMPOSER_PROVIDERS='{
"jwt": {
"provider": "jwt",
"module": "/home/composer/node_modules/custom-jwt.js",
"secretOrKey": "somesecretkey",
"authScheme": "saml",
"successRedirect": "/",
"failureRedirect":"/"
}
}'
我是第一次从 Java 服务交换 JWT 令牌。为了创建不记名令牌,我编写了以下代码:
public static String getBearerToken(String username, String id) throws UnsupportedEncodingException {
return Jwts.builder()
.claim("timestamp", System.currentTimeMillis())
.claim("username", username)
.claim("id", id)
.signWith(
SignatureAlgorithm.HS256,
"somesecretkey".getBytes("UTF-8")
).compact();
}
有了这个,我就能拿到令牌了。接下来,我使用此令牌将卡导入用户服务器上的钱包:
RestTemplate restTemplate = new RestTemplate();
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.MULTIPART_FORM_DATA);
headers.set("X-Access-Token",getAccess_token(participantEmail));
headers.set("x-api-key", userServerKey);
LinkedMultiValueMap<String, Object> params = new LinkedMultiValueMap<>();
params.add("card", new FileSystemResource(card));
params.add("name", participantEmail);
HttpEntity<LinkedMultiValueMap<String, Object>> requestEntity = new HttpEntity<>(params, headers);
UriComponentsBuilder builder = UriComponentsBuilder.fromHttpUrl(CARD_IMPORT_URL);
ResponseEntity<String> responseEntity = restTemplate.exchange(builder.build().encode().toUri(),
HttpMethod.POST, requestEntity, String.class);
但是,这会导致:
Unhandled error for request POST /api/Wallet/import: Error: Authorization Required
发现 1 通常,当我们第一次使用 auth bearer 交换 JWT 时,会在 mongo 中创建一个名为 "test" 的数据库。该数据库包含三个集合:accessToken、user 和 userIdentity。但是,就我而言,当我交换令牌时,没有在 mongo 中创建数据库。关于如何调试它有什么建议吗?
注意: 整个设置工作得非常好,直到我决定从头开始修剪并重新启动网络。
这里的问题是我在所有主机上为 mongodb 容器使用相同的名称。由于所有容器都连接到 swarm 网络,因此有 8 个 mongodb 容器同名,这是一个非常愚蠢的错误。当 composer-rest-server 的 docker 容器试图连接到 mongodb 容器时,它导致了一个问题。此连接在 COMPOSER_DATASOURCES 变量中定义。在所有主机上为每个 mongo 容器使用不同的名称解决了这个问题。