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

Cannot access client with URL-like client_id #1845

Closed
roosemberth opened this issue May 7, 2020 · 2 comments
Closed

Cannot access client with URL-like client_id #1845

roosemberth opened this issue May 7, 2020 · 2 comments

Comments

@roosemberth
Copy link

When creating an ORY Hydra OAuth2Client whose client_id ressembles an URL, such client cannot be retrieved from ORY Hydra:

Normal creation and retrieval of a client:

$ ID="$RANDOM"

$ curl -vvv "https://localhost:4445/clients" -d '{"client_id": "'"$ID"'", "client_name": "Example test client", "scope": "foo bar baz", "token_endpoint_auth_method": null, "grant_types": ["authorization_code", "refresh_token", "client_credentials"], "redirect_uris": ["https://example.com/authorize/back"], "secret": "secret"}'
[...]
> POST /clients HTTP/1.1
> Host: localhost:4445
> User-Agent: curl/7.58.0
> Accept: */*
> Content-Length: 275
> Content-Type: application/x-www-form-urlencoded
>
* upload completely sent off: 275 out of 275 bytes
< HTTP/1.1 201 Created
< Server: nginx/1.14.0 (Ubuntu)
< Date: Thu, 07 May 2020 02:33:04 GMT
< Content-Type: application/json
< Content-Length: 605
< Connection: keep-alive
< Location: /clients/25457
<
* Connection #0 to host localhost left intact
{"client_id":"25457","client_name":"Example test client","client_secret":"XATdSgBjTnqG","redirect_uris":["https://example.com/authorize/back"],"grant_types":["authorization_code","refresh_token","client_credentials"],"response_types":null,"scope":"foo bar baz","audience":null,"owner":"","policy_uri":"","allowed_cors_origins":null,"tos_uri":"","client_uri":"","logo_uri":"","contacts":null,"client_secret_expires_at":0,"subject_type":"public","token_endpoint_auth_method":"client_secret_basic","userinfo_signed_response_alg":"none","created_at":"2020-05-07T02:33:04Z","updated_at":"2020-05-07T02:33:04Z"}

$ curl -vvv "https://localhost:4445/clients/$ID"
[...]
> GET /clients/25457 HTTP/1.1
> Host: localhost:4445
> User-Agent: curl/7.58.0
> Accept: */*
>
< HTTP/1.1 200 OK
< Server: nginx/1.14.0 (Ubuntu)
< Date: Thu, 07 May 2020 02:33:24 GMT
< Content-Type: application/json
< Content-Length: 566
< Connection: keep-alive
<
* Connection #0 to host localhost left intact
{"client_id":"25457","client_name":"Example test client","redirect_uris":["https://example.com/authorize/back"],"grant_types":["authorization_code","refresh_token","client_credentials"],"response_types":[],"scope":"foo bar baz","audience":[],"owner":"","policy_uri":"","allowed_cors_origins":[],"tos_uri":"","client_uri":"","logo_uri":"","contacts":[],"client_secret_expires_at":0,"subject_type":"public","token_endpoint_auth_method":"client_secret_basic","userinfo_signed_response_alg":"none","created_at":"2020-05-07T02:33:04Z","updated_at":"2020-05-07T02:33:04Z"}

Creating and retrieving a client with client_id matching an URL pattern:

$ ID="https://foo.example.com/$RANDOM"

$ curl -vvv "https://localhost:4445/clients" -d '{"client_id": "'"$ID"'", "client_name": "Example test client", "scope": "foo bar baz", "token_endpoint_auth_method": null, "grant_types": ["authorization_code", "refresh_token", "client_credentials"], "redirect_uris": ["https://example.com/authorize/back"], "secret": "secret"}'
[...]
> POST /clients HTTP/1.1
> Host: localhost:4445
> User-Agent: curl/7.58.0
> Accept: */*
> Content-Length: 299
> Content-Type: application/x-www-form-urlencoded
>
* upload completely sent off: 299 out of 299 bytes
< HTTP/1.1 201 Created
< Server: nginx/1.14.0 (Ubuntu)
< Date: Thu, 07 May 2020 02:35:10 GMT
< Content-Type: application/json
< Content-Length: 629
< Connection: keep-alive
< Location: /clients/https://foo.example.com/17416
<
* Connection #0 to host localhost left intact
{"client_id":"https://foo.example.com/17416","client_name":"Example test client","client_secret":"CK1ODHhV0QGi","redirect_uris":["https://example.com/authorize/back"],"grant_types":["authorization_code","refresh_token","client_credentials"],"response_types":null,"scope":"foo bar baz","audience":null,"owner":"","policy_uri":"","allowed_cors_origins":null,"tos_uri":"","client_uri":"","logo_uri":"","contacts":null,"client_secret_expires_at":0,"subject_type":"public","token_endpoint_auth_method":"client_secret_basic","userinfo_signed_response_alg":"none","created_at":"2020-05-07T02:35:11Z","updated_at":"2020-05-07T02:35:11Z"}

$ curl -vvv "https://localhost:4445/clients/$ID"
[...]
> GET /clients/https://foo.example.com/17416 HTTP/1.1
> Host: localhost:4445
> User-Agent: curl/7.58.0
> Accept: */*
>
< HTTP/1.1 404 Not Found
< Server: nginx/1.14.0 (Ubuntu)
< Date: Thu, 07 May 2020 02:35:16 GMT
< Content-Type: text/plain; charset=utf-8
< Content-Length: 118
< Connection: keep-alive
<
* Connection #0 to host localhost left intact
{"error": "Error 404 - The requested route does not exist. Make sure you are using the right path, domain, and port."}

However, when listing all the clients in the server, a client with the specified client_id exits:

$ curl -vvv "https://localhost:4445/clients" | jq '.[]|select(.client_id == "'"$ID"'")'
[...]
> GET /clients HTTP/1.1
> Host: localhost:4445
> User-Agent: curl/7.58.0
> Accept: */*
>
{ [5 bytes data]
< HTTP/1.1 200 OK
< Server: nginx/1.14.0 (Ubuntu)
< Date: Thu, 07 May 2020 02:40:37 GMT
< Content-Type: application/json
< Transfer-Encoding: chunked
< Connection: keep-alive
< Link: </clients?limit=100&offset=0>; rel="first",</clients?limit=100&offset=-100>; rel="prev"
<
{ [15714 bytes data]
100 15686    0 15686    0     0  1021k      0 --:--:-- --:--:-- --:--:-- 1021k
* Connection #0 to host localhost left intact
{
  "client_id": "https://foo.example.com/17416",
  "client_name": "Example test client",
  "redirect_uris": [
    "https://example.com/authorize/back"
  ],
  "grant_types": [
    "authorization_code",
    "refresh_token",
    "client_credentials"
  ],
  "response_types": [],
  "scope": "foo bar baz",
  "audience": [],
  "owner": "",
  "policy_uri": "",
  "allowed_cors_origins": [],
  "tos_uri": "",
  "client_uri": "",
  "logo_uri": "",
  "contacts": [],
  "client_secret_expires_at": 0,
  "subject_type": "public",
  "token_endpoint_auth_method": "client_secret_basic",
  "userinfo_signed_response_alg": "none",
  "created_at": "2020-05-07T02:35:11Z",
  "updated_at": "2020-05-07T02:35:11Z"
}

Expected behavior

Retrieving an OAuth2Client with URL-like client_id should behave the same way as if the client_id was a random string.

Environment

  • Version: v1.0.8
  • Environment: Ubuntu 18.04.4 LTS (Bionic Beaver)
@florv
Copy link

florv commented May 7, 2020

In the above comment, GET /clients/https://foo.example.com/17416 should have been GET /clients/https:%2F%2Ffoo.example.com%2F17416 but this would still not have worked as expected.

The issue appears to stem from httprouter which incorrectly splits the path components after percent-decoding instead of first splitting the components and then decoding them.

The relevant httprouter issues are julienschmidt/httprouter#208 and julienschmidt/httprouter#226.

@aeneasr
Copy link
Member

aeneasr commented May 9, 2020

Interesting, that's typically the problem with having RESTful interfaces - you can't use URLs as primary identifiers. I fear this is a no-fix for us - you have other URLs such as website which can be used for storing the URL and that don't cause issue. It's also not very usual to use an URL as the primary identifier because URLs change over time and have a hard time with uniqueness (case sensitive or case insensitive URLs? only the domain case insensitive? or the path? both?).

@aeneasr aeneasr closed this as completed May 9, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants