"无法验证客户端的秘密哈希…"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不支持具有客户端机密的应用。
行为是否符合预期有待确认。目前,解决问题。
一个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 .