当前位置: 首页 > 知识库问答 >
问题:

使用Cognito的无密码身份验证流

赫连正初
2023-03-14

我一直在尝试使用AWS Cognito实现无密码身份验证

我关注了这些文章:https://medium.com/digicred/password-less-authentication-in-cognito-cafa016d4db7 https://medium.com/@pjatocheseminario/passwordless-api-using-cognito-and-serverless-framework-7fa952191352

我已经配置了Cognito(接受CUSTOM_AUTH),添加了Lambdas,并创建了APIendpoint:

/sign-up 
/initiate-auth (aka initiate login)
/respond-to-auth-challenge (aka (verify login)

当调用启动Auth时,我收到以下响应:调用启动Auth操作时发生错误(NotAuthorizedExc0019):不正确的用户名或密码。"

我使用的CUSTOM_AUTH不需要密码,用户名肯定是正确的,因为它实际上启动了身份验证流,我收到了一个代码,但是因为boto3没有响应会话,我不能继续身份验证。

这就是我对Cognito的称呼:

res = cognito.initiate_auth(
        ClientId=client_id,
        AuthFlow="CUSTOM_AUTH",
        AuthParameters={
            "USERNAME": email,
            "PASSWORD": random_password  
            }
        )

我可能遗漏了一些小东西,但我不知道是什么。

共有2个答案

屠嘉勋
2023-03-14

我也面临同样的错误,我认为错误信息是误导性的。当您在CreateAuth Challenge lambda中没有正确响应时,将出现此错误。所以要确保你的lambda里一切正常。

史昊焱
2023-03-14

你的客户端代码看起来不错,我的代码中有ClientId参数,但是如果你的代码没有引发异常,那么应该没问题。除非在创建应用客户端时选中了生成客户端秘密选项。如果是这种情况,那么您必须在AuthParameters中传递SECRET_HASH,如下所示:

import hmac
import hashlib
import base64

def get_secret_hash(email, client_id, client_secret):                                                                   
     """                                                                                                                 
     A keyed-hash message authentication code (HMAC) calculated using                                                    
     the secret key of a user pool client and username plus the client                                                   
     ID in the message.                                                                                                  
     """                                                                                                                 
     message = email + client_id                                                                                         
     client_secret = str.encode(client_secret)                                                                           
     dig = hmac.new(client_secret, msg=message.encode('UTF-8'), digestmod=hashlib.sha256).digest()                       
     return base64.b64encode(dig).decode()
                                                                                                                 
client.admin_initiate_auth(                                                                                  
    UserPoolId=COGNITO_USER_POOL_ID,                                                                                    
    ClientId=CLIENT_ID,                                                                                                 
    AuthFlow='CUSTOM_AUTH',                                                                                             
    AuthParameters={                                                                                                    
        'USERNAME': email,                                                                                              
        'SECRET_HASH': get_secret_hash(email, CLIENT_ID, CLIENT_SECRET) # Omit if secret key option is disabled.                                                          
    },
) 

接下来,再次检查以下各项:

应用程序客户端下

应用程序集成下

如果您的Cognito设置正确,并且您的代码仍然不工作,那么它可能是lambda代码。您可能知道这一点,但是对于无密码的自定义身份验证,您需要使用3个lambda触发器:定义身份验证挑战、创建身份验证挑战和验证身份验证挑战。

自定义验证lambdas事件按以下顺序触发:

  • DefineAuthChallenge\u身份验证:
def lambda_handler(event, context):
    if event['triggerSource'] == 'DefineAuthChallenge_Authentication':
        event['response']['challengeName'] = 'CUSTOM_CHALLENGE'
        event['response']['issueTokens'] = False
        event['response']['failAuthentication'] = False

        if event['request']['session']:  # Needed for step 4.
            # If all of the challenges are answered, issue tokens.
            event['response']['issueTokens'] = all(
                answered_challenge['challengeResult'] for answered_challenge in event['request']['session'])
    return event
def lambda_handler(event, context):
    if event['triggerSource'] == 'CreateAuthChallenge_Authentication':
        if event['request']['challengeName'] == 'CUSTOM_CHALLENGE':
            event['response']['privateChallengeParameters'] = {}
            event['response']['privateChallengeParameters']['answer'] = 'YOUR CHALLENGE ANSWER HERE'
            event['response']['challengeMetadata'] = 'AUTHENTICATE_AS_CHALLENGE'
    return event

然后,您的客户必须响应挑战:

client.respond_to_auth_challenge(                                                                            
    ClientId=CLIENT_ID,                                                                                                 
    ChallengeName='CUSTOM_CHALLENGE',                                                                                   
    Session=session,                                                                                                    
    ChallengeResponses={                                                                                                
        'USERNAME': email,                                                                                              
        'ANSWER': 'Extra Protection!',                                                                                  
        'SECRET_HASH': get_secret_hash(email, CLIENT_ID, CLIENT_SECRET)  # Omit if secret key option is disabled.                                                 
    }                                                                                                                   
)    
def lambda_handler(event, context):
    if event['triggerSource'] == 'VerifyAuthChallengeResponse_Authentication':
        if event['request']['challengeAnswer'] == event['request']['privateChallengeParameters']['answer']:
            event['response']['answerCorrect'] = True
    return event
  • 事件设置为True以返回令牌(步骤1中显示的代码),或者发出另一个挑战以继续重复步骤1-3。

最后,请确保是否也为您的用户池启用了不区分大小写选项。此外,如果用户处于FORCE_CHANGE_PASSWORD状态,我不能确切地回忆起CUSTOM_AUTH流是否工作。如果用户处于该状态,则尝试使用sdk设置永久密码,将状态设置为CONFIRMED

 类似资料:
  • 我试图建立一个认证系统与Laravel 4与Facebook登录。我正在使用Laravel 4的madewith love/laravel-oAuth2包。 当然,当用户登录Facebook时,没有密码可以添加到我的数据库中。但是,我正在尝试检查数据库中是否已经有用户id,以确定是否应该创建一个新实体,或者只是登录当前实体。我想使用Auth命令来实现这一点。我有一张叫做“粉丝”的桌子。 这就是我正

  • 我正在使用生成用户密码的强哈希值。我想登录用户,但不想通过网络以明文形式发送密码,如何检查密码是否正确(没有往返),因为它是加盐的? 我有一个客户端/服务器场景。客户端是台式计算机上的应用程序(不是网站,也不是超文本传输协议服务器)。 我怎样才能做到这一点?我只是走了这么远:我正在客户端上生成salt散列,从中形成一个mcf并将其发送到我的服务器。将mcf保存到数据库。我没有发送密码,只发送了实际

  • 我正在尝试在 Swift 中创建一个 iOS 应用程序,该应用程序使用 AWS Lambda 使用以下身份验证服务 - https://github.com/danilop/LambdAuth 它使用适用于 iOS 的 AWS 移动开发工具包与迪纳摩数据库和 Lambda 进行通信 - http://docs.aws.amazon.com/mobile/sdkforios/developergui

  • 创建密钥对并通过ssh-copy-id将公钥发送到服务器后,我仍然无法在没有密码的情况下登录 ssh-v user@host的输出 调试1:在/home/pumba/.ssh/known_hosts:1中找到密钥 debug1:在134217728块后重新密钥 调试1:SSH2_MSG_NEWKEYS已发送 debug1:应为SSH2_MSG_NewKeys debug1:在134217728块后

  • 我正在尝试使用Shiro对我正在构建的JSF Web应用程序进行身份验证和授权。不幸的是,我仍然有一些困难缠绕我的头如何把所有的东西放在一起。 我已经成功地(100%使用shiro.ini文件)将身份验证配置回存储测试凭据集的JDBC领域。当凭据以明文形式存储时,它对我来说非常有效。 我的最终目标是统一MySQL数据库中的现有凭证集。密码存储为SHA-256盐哈希。我花了一整天的时间阅读可用的文档

  • 我的代码在这里:代码重新发布是因为我想问一个更直接的问题。如何在未经身份验证的用户和经过身份验证的用户之间切换?我的未经验证的文件似乎已缓存,我使用了以下方法: 在我剩下的api代码之前,它仍然不能工作。谢谢你的帮助 注意:我知道它不起作用,因为我在切换配置/凭据提供程序后立即使用lambda进行调用,并且只有授权用户才能调用此方法。 编辑@behrooziAWS答案: API代码: 完整错误:B