我正在尝试从Lambda调用一个由计时器定期触发的突变。这就是我在做的
const params = {
AccountId: "XXXXXXX",
RoleArn: "arn:aws:iam::XXXX:role/appsync_lamda_role", // tried removing this too
IdentityPoolId: "ap-southeast-1:xxxx-xxxx-xxx-xxxx-xxx",
LoginId: "demo_access" // tried with and without this
};
AWS.config.update({
region: "ap-southeast-1",
credentials: new AWS.CognitoIdentityCredentials(params)
});
现在,我打电话
AWS.config.credentials.get(err => {
const signer = new AWS.Signers.V4(httpRequest, "appsync", true);
signer.addAuthorization(AWS.config.credentials, AWS.util.date.getDate());
const options = {
method: httpRequest.method,
body: httpRequest.body,
headers: httpRequest.headers
};
fetch(uri.href, options)
.then(res => res.json())
.then(json => {
console.log(`JSON Response = ${JSON.stringify(json, null, 2)}`);
callback(null, event);
})
.catch(err => {
console.error(`FETCH ERROR: ${JSON.stringify(err, null, 2)}`);
callback(err);
});
});
执行此操作时,我从APPSYNC收到一个错误,称为“错误”:[ { “ errorType”:“ UnauthorizedException”, “ message”:“无法解析JWT令牌。” } 我已经获得了调用GraphQL和编辑信任关系的角色
{
"Effect": "Allow",
"Principal": {
"Federated": "cognito-identity.amazonaws.com"
},
"Action": "sts:AssumeRoleWithWebIdentity"
}
我在这里想念的是什么?请帮忙。
当我查看生成的标头时,没有看到JWT令牌,但是看到了会话令牌 像
'User-Agent': 'aws-sdk-nodejs/2.275.1 linux/v8.10.0 exec-env/AWS_Lambda_nodejs8.10',
host: 'xxxxx.appsync-api.ap-southeast-1.amazonaws.com',
'Content-Type': 'application/json',
'X-Amz-Date': '20181213T080156Z',
'x-amz-security-token': 'xxxxxx//////////xxxxxEOix8u062xxxxxynf4Q08FxxxLZxV+xx/xxx/xxx/xxxxx=',
Authorization: 'AWS4-HMAC-SHA256 Credential=xxxxxxxxx/20181213/ap-southeast-1/appsync/aws4_request, SignedHeaders=host;x-amz-date;x-amz-security-token, Signature=xxxxxxxxxxxxxxxxxxxxxxx' }
预先感谢
答案 0 :(得分:3)
AWS AppSync支持通过IAM和Cognito用户池进行授权。它们可能会造成混淆,并且以我的经验,AWS文档和框架无法解决这种混乱。
IAM身份验证是所有主要AWS终端节点使用的身份验证。您可以使用正确的IAM身份验证和权限来创建DynamoDB表。通过使用密钥将某些主机,路径,参数和标头签名,将IAM请求转换为签名,从而发出IAM请求(通常是通过SDK或boto)。您的Authorization标头以AWS4-HMAC-SHA256开头,因此看起来您将IAM授权与v4签名一起使用。
Cognito用户池身份验证使用JWT令牌进行授权。在通过Cognito服务器进行身份验证之后,您将获得访问令牌和身份令牌,它们可用于调用诸如AWS Appsync之类的资源。 如果您将Cognito用户池与Cognito身份池连接,则可以使用这些访问令牌 检索IAM令牌。如果这样做,则可以使用这些令牌来签署IAM身份验证请求。
您似乎已使用Cognito用户池身份验证配置了AWS AppSync API,但您正在使用IAM身份验证来调用它。您可以使用JWT身份验证开始调用它,也可以将AWS AppSync API切换为使用IAM身份验证。选择哪种身份验证方法会影响如何执行细粒度访问控制(在IAM策略中还是在GraphQL模式中)。在docs中详细了解它。
答案 1 :(得分:2)
您可以尝试以下方法:
import 'babel-polyfill';
import URL from 'url';
import fetch from 'node-fetch';
import { CognitoIdentityServiceProvider } from 'aws-sdk';
const cognitoIdentityServiceProvider = new CognitoIdentityServiceProvider({ apiVersion: '2016-04-18' });
const initiateAuth = async ({ clientId, username, password }) => cognitoIdentityServiceProvider.initiateAuth({
AuthFlow: 'USER_PASSWORD_AUTH',
ClientId: clientId,
AuthParameters: {
USERNAME: username,
PASSWORD: password,
},
})
.promise();
export const handler = async (event, context, callback) => {
const clientId = 'YOUR_COGNITO_CLIENT_ID';
const endPoint = 'YOUR_GRAPHQL_END_POINT_URL';
const username = 'COGNITO_USERNAME';
const password = 'COGNITO_PASSWORD';
const { AuthenticationResult } = await initiateAuth({
clientId,
username,
password,
});
const accessToken = AuthenticationResult && AuthenticationResult.AccessToken;
const postBody = {
query: `mutation AddUser($userId: ID!, $userDetails: UserInput!) {
addUser(userId: $userId, userDetails: $userDetails) {
userId
name
}`,
variables: {
userId: 'userId',
userDetails: { name: 'name' },
},
};
const uri = await URL.parse(endPoint);
const options = {
method: 'POST',
body: JSON.stringify(postBody),
headers: {
host: uri.host,
'Content-Type': 'application/json',
Authorization: accessToken,
},
};
const response = await fetch(uri.href, options);
const { data } = await response.json();
const result = data && data.addUser;
callback(null, result);
};
确保您的Cognito用户池具有USER_PASSWORD_AUTH
身份验证流。