首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >使用Cognito & API网关和Lambda (Python)的无密码身份验证流

使用Cognito & API网关和Lambda (Python)的无密码身份验证流
EN

Stack Overflow用户
提问于 2020-09-12 14:24:09
回答 2查看 1.8K关注 0票数 0

我一直试图使用AWS认知和API网关& Lambda (Python)实现无密码身份验证。

我遵循了以下文章: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,并创建了API端点:

代码语言:javascript
复制
/sign-up 
/initiate-auth (aka initiate login)
/respond-to-auth-challenge (aka (verify login)

当调用initiateAuth时,我收到以下响应:调用InitiateAuth操作时发生错误(NotAuthorizedException):不正确的用户名或密码。“

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

我就是这么称呼科尼图的:

代码语言:javascript
复制
res = cognito.initiate_auth(
        ClientId=client_id,
        AuthFlow="CUSTOM_AUTH",
        AuthParameters={
            "USERNAME": email,
            "PASSWORD": random_password  
            }
        )

这可能是我错过的小东西,但我想不出是什么。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2020-12-01 05:35:35

我面临着同样的错误,我认为错误信息是误导性的。当您没有正确地响应在创建-8月-挑战λ,您将得到这个错误。所以确保所有的东西都在你的灯笼里。

票数 1
EN

Stack Overflow用户

发布于 2021-01-04 22:14:30

您的客户端代码看起来不错,我的代码中有ClientId参数,但是如果您的代码没有引发异常,那么它应该是可以的。除非您在创建应用程序客户端时检查了Generate client secret选项。如果是这样的话,那么您必须在SECRET_HASH中传入AuthParameters,如下所示:

代码语言:javascript
复制
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.                                                          
    },
) 

接下来,重复检查以下内容:

App clients > * > Auth Flows Configuration下,是否为客户端启用了ALLOW_CUSTOM_AUTH选项?

App integration > App client settings > * > Enabled Identity Providers下,您的用户池是否被选中?

如果您有正确的认知设置,而您的代码仍然不能工作,那么可能是lambda代码。您可能知道这一点,但是对于没有密码的自定义auth,您需要使用3个lambda触发器:Define Auth ChallengeCreate Auth ChallengeVerify Auth Challenge

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

可以将

  1. DefineAuthChallenge_Authentication:
    • Technically,issueTokens设置为True在这里返回令牌,而无需遍历steps.

的其余部分

代码语言:javascript
复制
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

  1. CreateAuthChallenge_Authentication:

代码语言:javascript
复制
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

那么你的客户必须对挑战做出回应:

代码语言:javascript
复制
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.                                                 
    }                                                                                                                   
)    

  1. VerifyAuthChallengeResponse_Authentication:

代码语言:javascript
复制
def lambda_handler(event, context):
    if event['triggerSource'] == 'VerifyAuthChallengeResponse_Authentication':
        if event['request']['challengeAnswer'] == event['request']['privateChallengeParameters']['answer']:
            event['response']['answerCorrect'] = True
    return event

  1. DefineAuthChallenge_Authentication:
    • event['response']['issueTokens']设置为True以返回令牌(步骤1中显示的代码),或发出另一个挑战以保持重复步骤1-3.

最后,确保您的用户池也启用了大小写不敏感选项。而且,如果用户处于FORCE_CHANGE_PASSWORD状态,我也无法准确地回忆起FORCE_CHANGE_PASSWORD流是否工作。如果用户处于该状态,则尝试使用sdk设置永久密码,将状态设置为CONFIRMED

票数 5
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/63861311

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档