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

Open
Zacharis278 opened this issue Dec 12, 2017 · 24 comments

Comments

@Zacharis278
Copy link

commented Dec 12, 2017

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

This comment has been minimized.

Copy link
Contributor

commented Dec 12, 2017

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

This comment has been minimized.

Copy link
Author

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

This comment has been minimized.

Copy link
Contributor

commented Dec 12, 2017

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

This comment has been minimized.

Copy link
Author

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

This comment has been minimized.

Copy link
Contributor

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

This comment has been minimized.

Copy link

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

This comment has been minimized.

Copy link

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

This comment has been minimized.

Copy link
Contributor

commented Jan 18, 2018

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

This comment has been minimized.

Copy link

commented Jan 18, 2018

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

This comment has been minimized.

Copy link

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

This comment has been minimized.

Copy link

commented Apr 29, 2018

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

This comment has been minimized.

Copy link
Contributor

commented Apr 30, 2018

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

This comment has been minimized.

Copy link

commented May 2, 2018

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

This comment has been minimized.

Copy link

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

This comment has been minimized.

Copy link

commented May 10, 2018

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

This comment has been minimized.

Copy link

commented May 10, 2018

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

This comment has been minimized.

Copy link

commented May 10, 2018

lol I just read mooyoul's comment

@ultrafez

This comment has been minimized.

Copy link

commented Aug 22, 2018

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

This comment has been minimized.

Copy link

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

This comment has been minimized.

Copy link

commented Nov 21, 2018

@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

This comment has been minimized.

Copy link

commented Nov 21, 2018

@AWSSteveHa

This comment has been minimized.

Copy link
Contributor

commented Nov 27, 2018

@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

This comment has been minimized.

Copy link

commented Feb 11, 2019

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

This comment has been minimized.

Copy link

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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
You can’t perform that action at this time.