我一直试图在Web浏览器中连接到IoT MQTT,因此我正在生成签名的URL并与Paho连接。但是,即使我使用附加了AWSIoTFullAccess策略的IAM角色生成了签名URL(因此应该可以访问所有资源上的所有IoT操作!),但每次连接(使用Paho)时,我都会收到403错误或wscat)。这是我用来生成签名URL的代码:
@APP.route(VERSION_PREFIX + 'signedurl', methods=['GET'])
def get_signed_url():
session = STS.assume_role(RoleArn=IAM_ROLE_ARN,
RoleSessionName=str(uuid.uuid4()))['Credentials']
endpt = os.getenv('REALTIME_WSS_ENDPT')
t = datetime.datetime.utcnow()
amzdate = t.strftime('%Y%m%dT%H%M%SZ')
datestamp = t.strftime('%Y%m%d') # Date w/o time, used in credential scope
method = 'GET'
protocol = 'wss'
uri = '/mqtt'
service = 'iotdevicegateway'
algorithm = 'AWS-HMAC-SHA256'
credential_scope = f"{datestamp}/us-west-2/{service}/aws4_request"
canonical_query = "X-Amz-Algorithm=" + algorithm
canonical_query += "&X-Amz-Credential=" + urllib.parse.quote_plus(session['AccessKeyId'] + '/' + credential_scope, safe='')
canonical_query += "&X-Amz-Date=" + amzdate
canonical_query += "&X-Amz-Expires=86400"
canonical_query += "&X-Amz-SignedHeaders=host"
canonical_headers = "host:" + endpt
payload_hash = hashlib.sha256(('').encode('utf-8')).hexdigest()
canonical_request = f"{method}\n{uri}\n{canonical_query}\n{canonical_headers}\nhost\n{payload_hash}"
string_to_sign = f"{algorithm}\n{amzdate}\n{credential_scope}\n{hashlib.sha256(canonical_request.encode('utf-8')).hexdigest()}"
signing_key = get_signature_key(session['SecretAccessKey'], datestamp, 'us-west-2', service)
signature = hmac.new(signing_key, (string_to_sign).encode('utf-8'), hashlib.sha256).hexdigest()
canonical_query += "&X-Amz-Signature=" + signature
canonical_query += "&X-Amz-Security-Token=" + urllib.parse.quote_plus(session['SessionToken'], safe='')
return make_response(f"{protocol}://{endpt}{uri}?{canonical_query}")
我尽可能完全遵循WSS上的MQTT示例,并且我担任的角色具有所有IoT权限。我在这里做什么错了?