AWS Cognito身份验证的主密钥实施

时间:2018-04-20 14:25:21

标签: amazon-web-services amazon-cognito

以下是使用Cognito进行身份验证的步骤:

  1. 浏览器要求访问受限制的页面。
  2. 加载页面上的JavaScript在网页页面上查找id_token。如果找不到,浏览器将被重定向到Cognito的登录页面,用户需要输入用户名和密码。
  3. 用户通过身份验证后,浏览器会重定向回原始限制页面,并在网址中显示id_token
  4. 受限制页面上的JavaScript使用此id_token来调用API网关。
  5. 现在,我有一个不同的场景。假设存在安全连接,并且使用该连接访问受限页面的任何人都不需要进行身份验证。换句话说,他们的身份被假定,并且不会要求他们自己进行身份验证。相反,它们将作为一个特定用户被带到受限页面(每个安全连接将代表一个固定的特定用户)。为简单起见,您可以假设安全连接由IP标识。在这种情况下,上述步骤将更改为:

    1. 浏览器要求访问受限制的页面。
    2. 加载页面上的JavaScript在网页页面上查找id_token。如果找不到,则会调用服务器上的某些API。
    3. 使用传入请求的IP地址,调用的API将识别用户并为其返回id_token,而不要求任何密码。
    4. 受限制页面上的JavaScript使用此id_token来调用API网关。
    5. 这里的关键要求是我正在寻找一种并行实现这两者的方法。我的意思是每个用户应该能够在没有密码的情况下从安全连接访问受限制的页面,并且能够使用密码从非安全连接访问受限制的页面。换句话说,在第二个场景中调用的API应该能够在不知道密码的情况下为用户返回id_token。或者也许使用主密钥密码。

      所以这是我的问题。我有什么办法可以在不知道密码的情况下返回某个用户的id_token吗?

      P.S。我知道IP对于这种实现来说不够安全。这只是简化问题的一种手段。请不要担心提供实际安全手段以验证连接的真实性的可行性。

1 个答案:

答案 0 :(得分:0)

我自己找到了答案。它被称为CUSTOM_AUTH流。您需要采取多个步骤来实现此目的:

首先,转到Cognito控制台,然后单击您的用户池。转到triggers页面并为Define Auth Challenge引入lambda函数。这个lambda函数最简单的代码如下所示:

exports.handler = (event, context, callback) => {
    event.response.challengeName = "";
    event.response.issueTokens = true;
    event.response.failAuthentication = false;
    callback(null, event);
};

第二个也是最后一个,创建lambda函数来验证您的用户:

const AWS = require('aws-sdk');
exports.handler = (event, context, callback) => {
    const cognitoidentityserviceprovider = new AWS.CognitoIdentityServiceProvider();
    var params = {
      AuthFlow: 'CUSTOM_AUTH',
      ClientId: 'XXXXXXXXXXXX', /* required */
      UserPoolId: 'XXXXXXXXXX', /* required */
      AuthParameters: {
        'USERNAME': 'XXXXXXXXXX', //Username / Email
      },
    };
    cognitoidentityserviceprovider.adminInitiateAuth(params, function(err, data) {
        if (err) {
            console.log(err, err.stack); // an error occurred
            callback(null, err);
        }
        else {
            console.log(data);           // successful response
            callback(null, data);
        }
    });
};

正如您所看到的,代码不需要密码,它会返回您需要的所有标记(id_token,access_token和refresh_token等)。