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

Unable to validate JWT via external service #377

Open
patrickmedina opened this issue May 17, 2021 · 4 comments · May be fixed by #378
Open

Unable to validate JWT via external service #377

patrickmedina opened this issue May 17, 2021 · 4 comments · May be fixed by #378
Assignees
Labels

Comments

@patrickmedina
Copy link

Summary and context

The external JWT validator service successfully receives the POST request and returns 200 OK but RIG always returns "Invalid Signature".

How to reproduce

When I run RIG with these settings:

  • External service is running on port 3000 on host machine and is accessible from docker containers.

  • External service immediately returns 200 OK for testing and doesn't actually validates the JWT.

  • RIG Config values:

SUBSCRIPTION_CHECK=http://host.docker.internal:3000

..and set up clients and services like this:

  • Initiate Websocket connection:

$ wscat -c ws://localhost:4000/_rig/v1/connection/ws

  • Subscription request:

$ curl -X PUT -H "Content-Type: application/json" -d '{"subscriptions":[{"eventType":"position","oneOf":[{"userType":"admin"}]}]}' -H "Authorization: Bearer jwt_token" "http://localhost:4000/_rig/v1/connection/ws/0B7ilUe9imppbOep5E9Gw_KD8ZR7Jal4HK2ZyG0cZXO2VBwxAxT8ZIUGA_YORriC7I3nppuaNfv48PQzbtQ=/subscriptions"

..I see the following error and/or log output:

  • Subscription response:

cannot accept subscription request: invalid authorization header: could not decode JWT: Invalid signature

  • JWT service received request from RIG:

{
method: 'POST',
url: '/',
header: {
authorization: 'Bearer jwt_token',
host: 'host.docker.internal:3000',
'user-agent': 'hackney/1.16.0',
'content-type': 'application/json',
'content-length': '75'
}
}

  • RIG logs:

rig-dev | 16:15:06.145 module=Phoenix.Logger request_id=Fn_mwLBz4wK9hIAAAABB [debug] Processing with RigInboundGatewayWeb.V1.SubscriptionController.set_subscriptions/2
rig-dev | Parameters: [UNFETCHED]
rig-dev | Pipelines: [:api]
rig-dev | 16:15:06.145 module=Plug.Logger request_id=Fn_mwLBz4wK9hIAAAABB [debug] PUT /_rig/v1/connection/ws/0B7ilUe9imppbOep5E9Gw_KD8ZR7Jal4HK2ZyG0cZXO2VBwxAxT8ZIUGA_YORriC7I3nppuaNfv48PQzbtQ=/subscriptions
rig-dev | 16:15:06.149 module=RigInboundGatewayWeb.V1.SubscriptionController request_id=Fn_mwLBz4wK9hIAAAABB [warn] failed to associate to session: ["%RIG.JWT.DecodeError{cause: "Invalid signature"}"]

..but I really expected this:

  • Successful subscription:

{"subscriptions":[{"eventType":"position","oneOf":[{"userType":"admin"}]....

Versions (please complete the following information):**

  • Host OS: Docker on MacOS[MacBook Pro (16-inch, 2019)]
  • Frontend: curl
  • RIG version as shown on startup: Reactive Interaction Gateway 3.0.0-alpha.1 [[email protected], ERTS 11.1.8, OTP 23]
@patrickmedina
Copy link
Author

Better to implement JWKS validation as alternative to external JWT validation service. I think JWKS hooks for Joken can be used for this.

kevinbader added a commit that referenced this issue May 23, 2021
Fixes #377.

- For subscription requests, JWTs that can't be validated are now
ignored. This allows to validate JWTs in an external service as
configurable via the SUBMISSION_CHECK and SUBSCRIPTION_CHECK environment
variables (which was the intention all along).

- Response code changed: when connecting and subscribing at the same
time, RIG replies with 403 (instead of 400) when not authorized to do
so.

- Ill-formed JWTs no longer cause subscription requests to fail.

- Fixed SUBMISSION_CHECK=jwt_validation - it failed the check anytime,
regardless of whether the JWT was valid.
@kevinbader
Copy link
Contributor

@patrickmedina should be fixed with #378 - can you confirm?

@patrickmedina
Copy link
Author

@kevinbader Thank you for the fix. It is now working for manual subscriptions, it is now validating against the configured external service via SUBSCRIPTION_CHECK envvar.

Can we have this work as well on automatic subscriptions via JWT claims? This will be a great help as well to reduce the API calls and rely on the JWT claims for the subscriptions on initial connection.

Currently when passing JWT during websocket connection, it still checks for internal JWT configuration instead of validating against an external service.

Request:

wscat -c ws://localhost:4000/_rig/v1/connection/ws\?jwt\=<jwt>

or

wscat -c ws://localhost:4000/_rig/v1/connection/ws -H "Authorization: Bearer <jwt>"

RIG Logs:

rig-dev    | 06:56:40.202 module=RigInboundGatewayWeb.V1.Websocket [debug] Closing WebSocket connection (#PID<0.3013.0>, reason=:remote)
rig-dev    | 06:56:53.361 module=RigInboundGatewayWeb.ConnectionInit [debug] new WS connection (pid=#PID<0.3347.0>, params=%RIG.AuthorizationCheck.Request{auth_info: %{auth_header: "Bearer <jwt>", auth_tokens: [{"bearer", "<jwt>"}]}, body: nil, content_type: "application/json; charset=utf-8", query_params: ""})
rig-dev    | 06:56:53.361 module=RigInboundGatewayWeb.ConnectionInit [warn] Cannot accept WS connection #PID<0.3347.0>: could not parse subscriptions: could not decode JWT: Invalid signature
rig-dev    | 06:56:53.361 module=RigInboundGatewayWeb.V1.Websocket [warn] websocket error: "could not parse subscriptions: could not decode JWT: Invalid signature"
rig-dev    | 06:56:53.362 module=RigInboundGatewayWeb.V1.Websocket [debug] Closing WebSocket connection (#PID<0.3347.0>, reason=:stop)

@kevinbader
Copy link
Contributor

kevinbader commented May 24, 2021

Ah, I see. I need to redesign this a bit to only allow invalid JWTs in case SUBSCRIPTION_CHECK isn't set to jwt_validation and generally make this more consistent. It'll take me a few days to do it though.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants