aws4 icon indicating copy to clipboard operation
aws4 copied to clipboard

Some services require the X-Amz-Security-Token not be in the canonical string for signed querystring requests

Open txase opened this issue 9 years ago • 5 comments

The session token must be added after signing.

txase avatar Aug 09 '16 03:08 txase

Ugh, apparently this is service-specific. See the note here: http://docs.aws.amazon.com/general/latest/gr/sigv4-add-signature-to-request.html.

When you add the X-Amz-Security-Token parameter to the query string, some services require that
you include this parameter in the canonical (signed) request. For other services, you add this parameter
at the end, after you calculate the signature. For details, see the API reference documentation for that
service.

Maybe this should be an option that can be set? Or, I suppose, users could just append it on after the fact for services that shouldn't have it included in the signing...

txase avatar Aug 09 '16 03:08 txase

@txase which service did you see this with?

(in any case, you're right – you can just add it after signing)

mhart avatar Aug 09 '16 13:08 mhart

IoT, while generating a url to connect to a websocket.

On Tuesday, August 9, 2016, Michael Hart [email protected] wrote:

@txase https://github.com/txase which service did you see this with?

(in any case, you're right – you can just add it after signing)

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/mhart/aws4/issues/30#issuecomment-238549591, or mute the thread https://github.com/notifications/unsubscribe-auth/AA6vhFfR5x9Iw8i3J6jiY-mrvHGGjOoeks5qeH4ogaJpZM4JfsF3 .

txase avatar Aug 09 '16 13:08 txase

Working example:

import aws4 from 'aws4'
import mqtt from 'mqtt'
const AWS_IOT_ENDPOINT = 'YOUR_ENDPOINT_ID.iot.us-east-1.amazonaws.com'

function signRequest ({ region, accessKeyId, secretAccessKey }) {
  return aws4.sign({
    host: AWS_IOT_ENDPOINT,
    path: '/mqtt',
    service: 'iotdevicegateway',
    region,
    signQuery: true
  }, {
    accessKeyId,
    secretAccessKey
  })
}

export function getClient ({ region, accessKeyId, secretAccessKey, sessionToken }) {
  // NOTE: IoT does not expect X-Amz-Security-Token to be included in the signature, but it must be added in the path
  const { path } = signRequest({ region, accessKeyId, secretAccessKey })

  const client = mqtt.connect(`wss://${AWS_IOT_ENDPOINT}${path}&X-Amz-Security-Token=${encodeURIComponent(sessionToken)}`)

  return client
}
const client = getClient({ region, accessKeyId, secretAccessKey, sessionToken })

client.on('connect', function () {
  client.subscribe('my-topic')

  window.setInterval(() => {
    client.publish('my-topic', 'Hello mqtt')
  }, 1000)
})

client.on('message', function (topic, message) {
  console.log(message.toString())
})

brettstack avatar Apr 14 '17 02:04 brettstack

@brettstack great! thanks for that example.

I think in this case I'll just add a check specifically for iot and not include the security token in the signature (but still add it to the query)

Are there any other services that do this?

mhart avatar Apr 14 '17 03:04 mhart