Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

custom authorizer headers #169

Closed
zacharis278 opened this issue Dec 12, 2017 · 28 comments
Closed

custom authorizer headers #169

zacharis278 opened this issue Dec 12, 2017 · 28 comments
Labels
closing-soon This issue will automatically close in 4 days unless further comments are made. guidance Question that needs advice or information.

Comments

@zacharis278
Copy link

I'm attempting to use a custom authorizer for browser clients and haven't had much luck getting it to work. Turns out on further inspection I'm not seeing any of the custom authorization headers getting sent when attempting to connect.

Am I missing something?

client setup:

this.client = awsIoT.device({
      debug: true,
      protocol: 'wss-custom-auth',
      host: 'xxxxxxxxxxx.iot.us-west-2.amazonaws.com',
      customAuthHeaders: {
        'X-Amz-CustomAuthorizer-Name': 'test-authorizer',
        'X-Amz-CustomAuthorizer-Signature': 'xxxxxxxxxxxxxxxxx',
        'TestAuthorizerToken': 'xxxxxxxxxxx'
      }
    });
@liuszeng
Copy link
Contributor

Hi @zacharis278 ,

Thank you very much for using AWS IoT Device SDK for Node.js.

I have forwarded this issue to the corresponding internal team for better support/investigation. In the meantime, can you also share the logs when you were experiencing the issue?

Thanks,
Liusu

@zacharis278
Copy link
Author

zacharis278 commented Dec 12, 2017

As is tradition it takes opening an issue before I find the underlying problem 😉 . I had not realized the browser implantation of websockets do not support adding additional headers to the request. As a result 'wss-custom-auth' will not work as implemented.

Is there any way to use a custom authorizer with browser clients?

@liuszeng
Copy link
Contributor

Hi @zacharis278 ,

Thank you very much for providing the information. Please bear with me while I am going through the code.

I was looking at the package.json file for the browser sample and found this line suspicious:
https://github.com/aws/aws-iot-device-sdk-js/blob/master/browser/package.json#L12

Are you using this browser sample in the SDK? Can you update the version of the device SDK and try again?

Thanks,
Liusu

@zacharis278
Copy link
Author

zacharis278 commented Dec 12, 2017

Yeah on further investigation my problem may be a wider one than something that can be addressed in this SDK alone. The websocket implantation in the web browser itself does not support adding headers. (Chrome, Firefox, etc) Yet, the custom authorizer setup in here needs to send a 'X-Amz-CustomAuthorizer-Name' header in order to identify what authorizer to use.

So, my broader question. Is it in any way possible to use a custom authorizer if your client device is a browser?

@liuszeng
Copy link
Contributor

liuszeng commented Dec 13, 2017

Hi @zacharis278 ,

I was able to duplicate your issue in Firefox on my side using browserify and the latest version of SDK with custom authorizer support. It seems that the required headers for custom authorization in the outgoing request are still missing even if it is configured in the SDK client:
image

Unfortunately, using custom authorizer with AWS IoT requires extra headers to be in the handshake request, including authorizer name, token and signature. Unless there is a way have the browser include these headers in the outbound request, missing them would make this request an unauthorized one, resulting in a 403 HTTP response.

I have added an internal tracker for further investigation of this issue. Sorry for the inconvenience it has caused.

Thanks,
Liusu

@danilotorrisi
Copy link

danilotorrisi commented Jan 12, 2018

Hi everybody,
the problem is indeed related to the WebSocket browser implementation. From what I understand, the WebSocket browser implementation does not accept custom HTTP headers via the option parameters.

@mlfarrell
Copy link

mlfarrell commented Jan 18, 2018

I just stumbled onto this today. Does that mean you can't do custom iot auth in the browser at all (ie chrome)?? That is what I've been working towards for a day now. Are we forced to use cognito?

@fengsongAWS
Copy link
Contributor

Hi @mlfarrell ,
As mentioned by @liuszeng , unless there is a way to include those headers, the custom auth will not work in browser envrionment. Yes, for now, the SDK does not wrap web headers into the handshake request. And as usual, cognito is the recommended way to communicate with iot service cloud.

@mlfarrell
Copy link

Put me on the list of people who definitely need custom auth in a browser and are requesting it. I've heard (albeit I'm not a websockets expert) that there is a way to embed the info in the URL itself. Once it is possible, please add some kind of custom auth support to the SDK in the browser.

@vit21ik
Copy link

vit21ik commented Mar 27, 2018

This code is correct but it doesn't work in browser because browser websocket client doesn't support custom headers.
This client works on nodejs.

@waynerobinson
Copy link

This is definitely something that we also require and I've just lost multiple days to this issue.

If you don't plan on supporting wss-custom-auth in this library, you might want to at least mention that this authentication mode doesn't work for browser in the README somewhere.

@AWSSteveHa
Copy link
Contributor

Hi @waynerobinson,
I apologize for your difficulties with this. We are investigating how to overcome this limitation so we can enable custom auth support in the browser. You also raise a good point that there should be mention of this issue in the README. I'll make sure we address that.
Thank you.

@cookejames
Copy link

Thankfully I came across this before I started trying to implement our custom authoriser for the browser. We would really like to ditch cognito as the only reason we have it is for IoT support and a custom authoriser would make the flow of using it much simpler (we can just use the same JWT and most of the same code as our lambda custom authoriser).

@mooyoul
Copy link

mooyoul commented May 8, 2018

We had this issue too.

since that issue is caused by limitation of browser-side websocket implementation, we've migrated our custom authorizer to pre-signed url with temporary credential which is came from STS service. the temporary credential can be issued with STS.assumeRole in lambda (Trusted Relationship was configured. policy can be limited by providing policy document when calling STS.assumeRole like custom authorizer does)

@webmaxru
Copy link

Hi! If anybody uses Node-RED: I added a Custom Authorizer to the AWS IoT node: https://www.npmjs.com/package/node-red-contrib-aws-iot-custom-auth

@mlfarrell
Copy link

Gonna add in my two cents and unsub. I solved this for myself by returning a STS temporary credential (a role that has IOT access) back to the client through a token-protected web API (I implemented the API via api gateway + lambda + custom authorizers). I then used the temporary STS creds to initialize iot with no problems. This should hold anyone over until the above is resolved.

@mlfarrell
Copy link

lol I just read mooyoul's comment

@ultrafez
Copy link

I'm going to join this issue by chiming in that I'm experiencing the same problem - I've been investigating custom auth and found that this limitation isn't described in the docs. Is there an update on this issue? It's been open for over 6 months now.

@rrrhys
Copy link

rrrhys commented Nov 14, 2018

React Native:
To send the headers in the connect request, please try
npm install --save git+https://github.com/rrrhys/websocket-stream.git

I've modified websocket-stream to pass through headers when supplied in the options (for a React Native project).

@ultrafez
Copy link

@rrrhys, the problem described in this GitHub issue is related to using this npm package in the browser - the root cause is that the WebSocket API implemented by browsers doesn't support adding custom headers, even thought the websocket protocol itself does support custom headers.

The fix required from the AWS team is a way of indicating that the developer wants to use a custom authorizer via parameters in the URL, rather than by adding custom headers, as the URL is the only way of adding extra information to the websocket connection request.

An effective workaround has been described in mooyoul's comment and mlfarrell's comment which I too am using. This has also meant that I was able to use the smaller mqtt.js for my application rather than the heavier aws-iot-device-sdk since I offloaded generation of the presigned URL to a lambda rather than calculating the MQTT connection URL in the browser.

@AWSSteveHa, there still isn't any mention of this limitation in the README - can this be updated to avoid other people wasting time on this issue until it's addressed?

@rrrhys
Copy link

rrrhys commented Nov 21, 2018 via email

@AWSSteveHa
Copy link
Contributor

@ultrafez thank you for the reminder of mention of this limitation in the README. My apologies to anyone who spent time unnecessarily on this. The README is now updated.

@aniket91
Copy link

It's sad to see this does not work in browser environments. There is no support in Java SDK as well. Is there a way we can get this to work in React Native environment? Has anyone tried it? Thanks.

@eagene
Copy link

eagene commented Feb 11, 2019

@ultrafez Can you explain what you're doing? I'm using cognito in the browser already for authentication and so can get temporary credentials, but I thought I needed to then generate a signed url in the browser in any case to connect to iot. Is that not the case? Or do you generate the presigned url in a lambda, return it to the browser, and then use the mqtt library?

BTW: I've managed to get this to work using my permanent login credentials (as a test), but am still getting auth errors using the temporary credentials -- although I've followed the documentation for adding permissions.

Thanks.

@jmklix jmklix added closing-soon This issue will automatically close in 4 days unless further comments are made. guidance Question that needs advice or information. labels Aug 13, 2020
@ghost
Copy link

ghost commented Aug 14, 2020

For those who suggest using temporary sts credentials ( @mooyoul , @mlfarrell ), one of the possible benefits of the custom authorizer is that it gives you a place to generate custom IOT Core policy to attach to identities. I'm struggling to work out where / how are you attaching the IOT Core policy to your temporary credentials? Are you attaching the policy in a lambda that is called manually? If so, what happens when something goes badly wrong and a whole heap of requests come in at once - blowing the 15 transactions per second quota on AttachPolicy?

@stijndepestel
Copy link
Contributor

stijndepestel commented Oct 23, 2020

Hi,

I've been running into the same issues with custom authentication headers and websockets in browsers, however I have noticed, the custom authentication is also supported using the querystring of the connection URI.

If I change line L137 of device/index.js which creates the connection URI to read the following:
return 'wss://' + hostName + path + "?x-amz-customauthorizer-name=authorizer-name&token=allow";
my authentication lambda gets triggered.

Obviously, this should be passed on using the options. Can I create a PR for this fix or is this solution not optimal?

Edit: created PR

@bretambrose
Copy link
Contributor

Support for custom auth via query params has been added via #383.

@github-actions
Copy link

github-actions bot commented Jul 9, 2021

⚠️COMMENT VISIBILITY WARNING⚠️

Comments on closed issues are hard for our team to see.
If you need more assistance, please either tag a team member or open a new issue that references this one.
If you wish to keep having a conversation with other community members under this issue feel free to do so.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
closing-soon This issue will automatically close in 4 days unless further comments are made. guidance Question that needs advice or information.
Projects
None yet
Development

No branches or pull requests