提问者:小点点

无法在REFRESH_TOKEN_AUTH验证客户端的秘密哈希


"无法验证客户端的秘密哈希…"REFRESH_TOKEN_AUTH身份验证流。

{
    "Error": {
        "Code": "NotAuthorizedException",
        "Message": "Unable to verify secret hash for client 3tjdt39cq4lodrn60kjmsb****"
    },
    "ResponseMetadata": {
        "HTTPHeaders": {
            "connection": "keep-alive",
            "content-length": "114",
            "content-type": "application/x-amz-json-1.1",
            "date": "Tue, 29 Jan 2019 22:22:35 GMT",
            "x-amzn-errormessage": "Unable to verify secret hash for client 3tjdt39cq4lodrn60kjmsbv3jq",
            "x-amzn-errortype": "NotAuthorizedException:",
            "x-amzn-requestid": "610368ec-2414-11e9-9671-f11a8cac1e43"
        },
        "HTTPStatusCode": 400,
        "RequestId": "610368ec-2414-11e9-9671-f11a8cac1e43",
        "RetryAttempts": 0
    }
}

遵循AWS留档(如下文参考)。

对于REFRESH_TOKEN_AUTH/REFRESH_TOKEN:REFRESH_TOKEN(必填)、SECRET_HASH(如果应用客户端配置了客户端机密,则必填)、DEVICE_KEY

response = get_client().admin_initiate_auth(
    UserPoolId=USER_POOL_ID,
    ClientId=CLIENT_ID,
    AuthFlow='REFRESH_TOKEN_AUTH',
    AuthParameters={
        'REFRESH_TOKEN': refresh_token,
        'SECRET_HASH': get_secret_hash(username)
    }
)

它不会发生在具有相同秘密哈希值ADMIN_NO_SRP_AUTH身份验证流上。

response = get_client().admin_initiate_auth(
    UserPoolId=USER_POOL_ID,
    ClientId=CLIENT_ID,
    AuthFlow='ADMIN_NO_SRP_AUTH',
    AuthParameters={
        'USERNAME': username,
        'SECRET_HASH': get_secret_hash(username),
        'PASSWORD': password
    },
    ClientMetadata={
        'username': username,
        'password': password
    }
)

相同的秘密哈希适用于200。

{
    "AuthenticationResult": {
        "AccessToken": ...,
        "TokenType": "Bearer"
    },
    "ChallengeParameters": {},
    "ResponseMetadata": {
        "HTTPHeaders": {
            "connection": "keep-alive",
            "content-length": "3865",
            "content-type": "application/x-amz-json-1.1",
            "date": "Tue, 29 Jan 2019 22:25:33 GMT",
            "x-amzn-requestid": "cadf53cf-2414-11e9-bba9-4b60b3285418"
        },
        "HTTPStatusCode": 200,
        "RequestId": "cadf53cf-2414-11e9-bba9-4b60b3285418",
        "RetryAttempts": 0
    }
}

两者都使用相同的逻辑来生成秘密哈希。

def get_secret_hash(username):
    msg = username + CLIENT_ID
    digest = hmac.new(
        str(CLIENT_SECRET).encode('utf-8'),
        msg = str(msg).encode('utf-8'),
        digestmod=hashlib.sha256
    ).digest()
    hash = base64.b64encode(digest).decode()

    log_debug("secret hash for cognito UP is [{0}]".format(hash))
    return hash

值相同:

secret hash for cognito UP is [6kvmKb8almXpYKvfEbE9q4r1Iq/SuQvP8H**********].

>

  • 启用客户端机密的Cognito用户池。

    打印boto. Version 2.49.0

    AWSAmplify JavascriptJDK不支持Github中所述的客户端机密,但到目前为止在Boto3上没有找到报告。

    创建应用时,必须取消选中生成客户端机密框,因为JavaScriptSDK不支持具有客户端机密的应用。

    • AWSCognito原子令牌在秘密哈希中失败
    • 无法验证Amazon Cognito用户池中客户端的秘密哈希
    • Cognito Admin启动身份验证
    • Boto3admin_initiate_auth
    • AWSCognito用户池计算秘密哈希值

  • 共1个答案

    匿名用户

    行为是否符合预期有待确认。目前,解决问题。

    一个AWS人确定的原因和解决方法。

    当用户名中有“@”时,您会在REFRESH_TOKEN_AUTH调用时收到该错误。Cognito为它们生成一个UUID样式的用户名。您必须在刷新调用期间使用它。

    提供用于刷新令牌的示例代码。

    import boto3
    import hmac
    import hashlib
    import base64
    import time
    import jwt
    
    Region = "us-east-1"
    UserPoolId = "Your userpool ID"
    AppClientId = "yyyy"
    AppClientSecret = "zzzz"
    Username = "james@bond.com"
    Password = "shakennotstirred"
    
    Signature = hmac.new(AppClientSecret, Username+AppClientId,digestmod=hashlib.sha256)
    Hash = base64.b64encode(Signature.digest())
    
    Cognito = boto3.client("cognito-idp", region_name=Region)
    
    AuthResponse = Cognito.admin_initiate_auth(
        AuthFlow="ADMIN_NO_SRP_AUTH",
        ClientId=AppClientId,
        UserPoolId=UserPoolId,
        AuthParameters={"USERNAME":Username, "PASSWORD":Password, "SECRET_HASH":Hash})
    
    IdToken = AuthResponse["AuthenticationResult"]["IdToken"]
    RefreshToken = AuthResponse["AuthenticationResult"]["RefreshToken"]
    
    Decoded = jwt.decode(IdToken, verify=False)
    DecodedUsername = Decoded["cognito:username"]
    
    NewSignature = hmac.new(AppClientSecret, DecodedUsername+AppClientId, digestmod=hashlib.sha256) #!! Generate new signature and hash
    NewHash = base64.b64encode(NewSignature.digest())
    
    RefreshResponse = Cognito.admin_initiate_auth(
        AuthFlow="REFRESH_TOKEN_AUTH",
        ClientId=AppClientId,
        UserPoolId=UserPoolId,
        AuthParameters={"REFRESH_TOKEN":RefreshToken, "SECRET_HASH":NewHash}) #!! Use the new hash
    
    NewIdToken = RefreshResponse["AuthenticationResult"]["IdToken"]
    
    
    print("NewIdToken: "+NewIdToken)
    

    该示例使用Python2。安装所需的包。

    pip2 install cryptography -t .
    pip2 install PyJWT -t .