NASA-IMPACT / veda-auth-central

Standard based security solution tailored for VEDA comprehensive user authentication, centralized user profile management, and intelligent authorization decisions.
Apache License 2.0
3 stars 4 forks source link

Receiving failures from /identity-management/authorize #60

Open alukach opened 2 weeks ago

alukach commented 2 weeks ago

When attempting to login from Grafana (https://d1z1g2cnqbz2id.cloudfront.net/login), we are seeing a 500 error on the /identity-management/authorize endpoint:

▶ curl 'http://18.191.42.248:8081/api/v1/identity-management/authorize?client_id=veda-n78pbpiu8msdjjxkvlmb-10000000&redirect_uri=https%3A%2F%2Fd1z1g2cnqbz2id.cloudfront.net%2Flogin%2Fgeneric_oauth&response_type=code&scope=user%3Aemail&state=LDh1iNYlJcSujbgfFakT2iwhB6PIhgBidrFBmYNTBMw%3D' \
  -H 'Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8' \
  -H 'Accept-Language: en-US,en' \
  -H 'Cache-Control: no-cache' \
  -H 'Connection: keep-alive' \
  -H 'Pragma: no-cache' \
  -H 'Sec-GPC: 1' \
  -H 'Upgrade-Insecure-Requests: 1' \
  -H 'User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/123.0.0.0 Safari/537.36' \
  --insecure --verbose
*   Trying 18.191.42.248:8081...
* Connected to 18.191.42.248 (18.191.42.248) port 8081 (#0)
> GET /api/v1/identity-management/authorize?client_id=veda-n78pbpiu8msdjjxkvlmb-10000000&redirect_uri=https%3A%2F%2Fd1z1g2cnqbz2id.cloudfront.net%2Flogin%2Fgeneric_oauth&response_type=code&scope=user%3Aemail&state=LDh1iNYlJcSujbgfFakT2iwhB6PIhgBidrFBmYNTBMw%3D HTTP/1.1
> Host: 18.191.42.248:8081
> Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8
> Accept-Language: en-US,en
> Cache-Control: no-cache
> Connection: keep-alive
> Pragma: no-cache
> Sec-GPC: 1
> Upgrade-Insecure-Requests: 1
> User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/123.0.0.0 Safari/537.36
>
< HTTP/1.1 500
< Vary: Origin
< Vary: Access-Control-Request-Method
< Vary: Access-Control-Request-Headers
< Content-Type: text/html;charset=UTF-8
< Content-Length: 25
< Date: Wed, 19 Jun 2024 18:06:34 GMT
< Connection: close
<
* Closing connection 0
Unexpected error occurred%

Relates to https://github.com/NASA-IMPACT/veda-backend/issues/373

alukach commented 2 weeks ago

@lahirujayathilake Our expected redirect is: https://d1z1g2cnqbz2id.cloudfront.net/login/generic_oauth

lahirujayathilake commented 2 weeks ago

@alukach, This is expected because we haven't configured the redirect URIs. I'll configure 'https://d1z1g2cnqbz2id.cloudfront.net/login/generic_oauth' as a redirect URL

lahirujayathilake commented 2 weeks ago

@alukach could you please retry this?

Note - These admin-related functionalities will be exposed through the Admin Portal (in the next PI)

alukach commented 2 weeks ago

@lahirujayathilake Yes. Same issue. You can also give it a try by clicking "Sign in with VEDA Auth Central"

alukach commented 2 weeks ago

As an aside, I think we should mark it as a bug that the server throws a 500 rather than a 400 response indicating the bad redirect.

Invalid redirect URL If the redirect URL provided is invalid, the authorization server will not redirect to it. Instead, it may display a message to the user describing the problem instead.

https://www.oauth.com/oauth2-servers/server-side-apps/possible-errors/

lahirujayathilake commented 1 week ago

@alukach, this should be the flow,

  1. Get OIDC Configurations Endpoint: GET /api/v1/identity-management/.well-known/openid-configuration This endpoint provides the OpenID Connect (OIDC) configuration, which includes the authorization_endpoint

eg. https://github.com/NASA-IMPACT/veda-auth-central/blob/e08499fdb28f4d806dfe185bb809be2500b075fe/veda-app-samples/veda-react-app/src/api/auth.js#L55-L60

  1. Redirect the User to the Authorization Endpoint The user is redirected to the authorization_endpoint to log in Example: "authorization_endpoint": "https://auth.veda.usecustos.org/realms/10000000/protocol/openid-connect/auth"

  2. Callback URL with Authorization Code After the user logs in, the authorization server redirects the user back to the application using a callback URL provided by the application. (https://d1z1g2cnqbz2id.cloudfront.net/login/generic_oauth)

https://github.com/NASA-IMPACT/veda-auth-central/blob/e08499fdb28f4d806dfe185bb809be2500b075fe/veda-app-samples/veda-react-app/src/api/auth.js#L14

https://github.com/NASA-IMPACT/veda-auth-central/blob/e08499fdb28f4d806dfe185bb809be2500b075fe/veda-app-samples/veda-react-app/src/pages/callback/CallbackPage.jsx#L5C11-L18

  1. Exchange Authorization Code for Access Token Endpoint: POST /api/v1/identity-management/token
alukach commented 1 week ago

@lahirujayathilake thanks. I don't believe that Grafana supports using the .well-known/openid-configuration endpoint for automatic configuration (https://github.com/grafana/grafana/issues/27443), so we'll need to manually configure the service with the values returned from that endpoint.

I can confirm that instead using https://auth.veda.usecustos.org/realms/10000000/protocol/openid-connect/auth as the authorization endpoint does indeed avoid the 500 response. However, the user is redirected back to Grafana with an error:

image

Reviewing the 302 response from usecustos.org, we can see that the following query parameters are provided:

image

By default, Grafana requests the user:email scope. It seems that is not currently supported by our auth backend. Can the backend be updated to support the user:email scope?

curl ```sh ▶ curl https://auth.veda.usecustos.org/auth/realms/10000000/protocol/openid-connect/auth\?client_id\=veda-n78pbpiu8msdjjxkvlmb-10000000\&redirect_uri\=https%3A%2F%2Fd1z1g2cnqbz2id.cloudfront.net%2Flogin%2Fgeneric_oauth\&response_type\=code\&scope\=user%3Aemail\&state\=x9WO_7ABuPCo__pzkR2Blg6FQskxXDhapInPSxVczQA%3D --verbose * Trying 3.135.47.237:443... * Connected to auth.veda.usecustos.org (3.135.47.237) port 443 (#0) * ALPN: offers h2,http/1.1 * (304) (OUT), TLS handshake, Client hello (1): * CAfile: /etc/ssl/cert.pem * CApath: none * (304) (IN), TLS handshake, Server hello (2): * TLSv1.2 (IN), TLS handshake, Certificate (11): * TLSv1.2 (IN), TLS handshake, Server key exchange (12): * TLSv1.2 (IN), TLS handshake, Server finished (14): * TLSv1.2 (OUT), TLS handshake, Client key exchange (16): * TLSv1.2 (OUT), TLS change cipher, Change cipher spec (1): * TLSv1.2 (OUT), TLS handshake, Finished (20): * TLSv1.2 (IN), TLS change cipher, Change cipher spec (1): * TLSv1.2 (IN), TLS handshake, Finished (20): * SSL connection using TLSv1.2 / ECDHE-RSA-AES128-GCM-SHA256 * ALPN: server accepted h2 * Server certificate: * subject: CN=auth.veda.usecustos.org * start date: Apr 1 00:00:00 2024 GMT * expire date: May 1 23:59:59 2025 GMT * subjectAltName: host "auth.veda.usecustos.org" matched cert's "auth.veda.usecustos.org" * issuer: C=US; O=Amazon; CN=Amazon RSA 2048 M02 * SSL certificate verify ok. * using HTTP/2 * h2 [:method: GET] * h2 [:scheme: https] * h2 [:authority: auth.veda.usecustos.org] * h2 [:path: /auth/realms/10000000/protocol/openid-connect/auth?client_id=veda-n78pbpiu8msdjjxkvlmb-10000000&redirect_uri=https%3A%2F%2Fd1z1g2cnqbz2id.cloudfront.net%2Flogin%2Fgeneric_oauth&response_type=code&scope=user%3Aemail&state=x9WO_7ABuPCo__pzkR2Blg6FQskxXDhapInPSxVczQA%3D] * h2 [user-agent: curl/8.1.2] * h2 [accept: */*] * Using Stream ID: 1 (easy handle 0x120014200) > GET /auth/realms/10000000/protocol/openid-connect/auth?client_id=veda-n78pbpiu8msdjjxkvlmb-10000000&redirect_uri=https%3A%2F%2Fd1z1g2cnqbz2id.cloudfront.net%2Flogin%2Fgeneric_oauth&response_type=code&scope=user%3Aemail&state=x9WO_7ABuPCo__pzkR2Blg6FQskxXDhapInPSxVczQA%3D HTTP/2 > Host: auth.veda.usecustos.org > User-Agent: curl/8.1.2 > Accept: */* > < HTTP/2 302 < date: Thu, 20 Jun 2024 02:04:56 GMT < content-length: 0 < location: https://d1z1g2cnqbz2id.cloudfront.net/login/generic_oauth?error=invalid_scope&error_description=Invalid+scopes%3A+user%3Aemail&state=x9WO_7ABuPCo__pzkR2Blg6FQskxXDhapInPSxVczQA%3D < referrer-policy: no-referrer < strict-transport-security: max-age=31536000; includeSubDomains < x-xss-protection: 1; mode=block < x-content-type-options: nosniff < * Connection #0 to host auth.veda.usecustos.org left intact ```

Additionally, If we're using the the authorization_endpoint provided by .well-known/openid-configuration, shouldn't we also make use of the the endpoints specified in token_endpoint and userinfo_endpoint?

Out of curiousity, if we're making some/all of the requests to auth.veda.usecustos.org, what are the intended use-cases for the identity-management/{authorize,token,user} endpoints that are present on the VEDA Auth Central docs?

@smohiudd We will need to update our auth secrets to either one of the following based on the answer to the above question. (and then, of course, redeploy)

{
  "client_id": "veda-n78pbpiu8msdjjxkvlmb-10000000",
  "client_secret": "...REDACTED...",
  "auth_url": "https://auth.veda.usecustos.org/auth/realms/10000000/protocol/openid-connect/auth",
  "token_url": "http://3.147.103.56:8081/api/v1/identity-management/token",
  "api_url": "http://3.147.103.56:8081/api/v1/identity-management/user"
}
{
  "client_id": "veda-n78pbpiu8msdjjxkvlmb-10000000",
  "client_secret": "...REDACTED...",
  "auth_url": "https://auth.veda.usecustos.org/auth/realms/10000000/protocol/openid-connect/auth",
  "token_url": "https://auth.veda.usecustos.org/auth/realms/10000000/protocol/openid-connect/token",
  "api_url": "https://auth.veda.usecustos.org/auth/realms/10000000/protocol/openid-connect/userinfo"
}

An aside, if we are indeed using the auth.veda.usecustos.org service for token exchange, #58 is a much lower priority.

lahirujayathilake commented 1 week ago

@alukach, thanks for raising these important concerns!

First, the issue with the /authorize endpoint has been fixed, and you can now integrate Grafana. We've updated the React sample to use the /authorize endpoint, which you can find here: https://github.com/NASA-IMPACT/veda-auth-central/blob/b8e5341a706ed27feec4dd4c3d337e45a28f55d9/veda-app-samples/veda-react-app/src/api/auth.js#L58.

In addition, we provide a /.well-known/openid-configuration endpoint. This is a crucial component for OpenID Connect (OIDC) clients, as it dynamically provides essential information about our veda-auth-central, including the correct endpoints for authorization (authorization_endpoint), token exchange (token_endpoint), and user information retrieval (userinfo_endpoint).

While not strictly mandatory, providing this discovery endpoint is considered best practice for OIDC implementations. It ensures better compatibility with a wider range of clients and simplifies the integration process. By adhering to this standard, we also future-proof our authentication provider, making it more adaptable to potential changes in OIDC specifications. The convenience endpoints (/authorize, /token, /user) are available for clients that may not be fully OIDC-compliant or require a simpler integration. https://openid.net/specs/openid-connect-discovery-1_0.html

smohiudd commented 1 week ago

@lahirujayathilake I tried with the following endpoints:

http://18.191.42.248:8081/api/v1/identity-management/authorize http://18.191.42.248:8081/api/v1/identity-management/token http://18.191.42.248:8081/api/v1/identity-management/user

and I'm getting the following error: Exception occurred while formulating login uri No matching redirect_uri is found for the Tenant with the Id: 10000000

However when I use:

https://auth.veda.usecustos.org/auth/realms/10000000/protocol/openid-connect/auth https://auth.veda.usecustos.org/auth/realms/10000000/protocol/openid-connect/token https://auth.veda.usecustos.org/auth/realms/10000000/protocol/openid-connect/userinfo

it works fine:

image

Also do you have some test users that we can try out?

lahirujayathilake commented 1 week ago

@smohiudd, could you please share the authorize request so I can verify that this redirect_uri has been configured? Once this is working fine, you can just log in with one of your accounts (Google, Microsoft, FB, etc.).

alukach commented 1 week ago

@smohiudd Great, I can confirm that we can now access the KeyCloak login screen 🎉

@lahirujayathilake

The convenience endpoints (/authorize, /token, /user) are available for clients that may not be fully OIDC-compliant or require a simpler integration.

Thanks for this information. So these endpoints simply pass data through to the endpoints that are referenced in the openid-configuration endpoints?

could you please share the authorize request so I can verify that this redirect_uri has been configured?

The failing authorize request is the same as shown in the first comment of this thread ( https://github.com/NASA-IMPACT/veda-auth-central/issues/60#issue-2362888695), however the response is slightly different now:

▶ curl 'http://18.191.42.248:8081/api/v1/identity-management/authorize?client_id=veda-n78pbpiu8msdjjxkvlmb-10000000&redirect_uri=https%3A%2F%2Fd1z1g2cnqbz2id.cloudfront.net%2Flogin%2Fgeneric_oauth&response_type=code&scope=user%3Aemail&state=LDh1iNYlJcSujbgfFakT2iwhB6PIhgBidrFBmYNTBMw%3D' \
  -H 'Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8' \
  -H 'Accept-Language: en-US,en' \
  -H 'Cache-Control: no-cache' \
  -H 'Connection: keep-alive' \
  -H 'Pragma: no-cache' \
  -H 'Sec-GPC: 1' \
  -H 'Upgrade-Insecure-Requests: 1' \
  -H 'User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/123.0.0.0 Safari/537.36' \
  --insecure --verbose
*   Trying 18.191.42.248:8081...
* Connected to 18.191.42.248 (18.191.42.248) port 8081 (#0)
> GET /api/v1/identity-management/authorize?client_id=veda-n78pbpiu8msdjjxkvlmb-10000000&redirect_uri=https%3A%2F%2Fd1z1g2cnqbz2id.cloudfront.net%2Flogin%2Fgeneric_oauth&response_type=code&scope=user%3Aemail&state=LDh1iNYlJcSujbgfFakT2iwhB6PIhgBidrFBmYNTBMw%3D HTTP/1.1
> Host: 18.191.42.248:8081
> Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8
> Accept-Language: en-US,en
> Cache-Control: no-cache
> Connection: keep-alive
> Pragma: no-cache
> Sec-GPC: 1
> Upgrade-Insecure-Requests: 1
> User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/123.0.0.0 Safari/537.36
>
< HTTP/1.1 500
< Vary: Origin
< Vary: Access-Control-Request-Method
< Vary: Access-Control-Request-Headers
< Content-Type: text/html;charset=UTF-8
< Content-Length: 117
< Date: Mon, 24 Jun 2024 05:10:39 GMT
< Connection: close
<
* Closing connection 0
Exception occurred while formulating login uri No matching redirect_uri is found for the Tenant with the Id: 10000000%

i.e. a redirect_uri value of https://d1z1g2cnqbz2id.cloudfront.net/login/generic_oauth

you can just log in with one of your accounts (Google, Microsoft, FB, etc.).

I can confirm that this works 🎉 (at least when using the auth.veda.usecustos.org auth endpoint). Keycloak sends me back to Grafana via a 302 with a location header set to https://d1z1g2cnqbz2id.cloudfront.net/login/generic_oauth?state=yGnrrQMVRZkr1d-u8MiwAimor2BBdm2FI5nb-OEw7_A%3D&session_state=f15a95de...6bd728cfdd5a&code=2d911a6a...6670c7c4b846.

However, we're not fully out of the weeds just yet. We're still seeing a failure when Grafana attempts to exchange the auth code for an auth token:

image

The auth code -> auth token exchange happens server-side, so it's hard to say what exactly goes wrong without checking the server logs. I'm not sure that it's a VEDA Auth Central issue, it's very possible that Grafana is misconfigured. @smohiudd: we should check the Grafana server logs tomorrow to see what's going on.


TLDR:

alukach commented 1 week ago

@smohiudd & @alukach to investigate why the auth code -> auth token exchange fails on Grafana.

To keep things documented:

On the server, using the auth.veda.usecustos.org auth endpoint, we see:

▶ curl -X POST "https://auth.veda.usecustos.org/auth/realms/10000000/protocol/openid-connect/token" \
     -H "Content-Type: application/x-www-form-urlencoded" \
     -d "client_id=veda-n78pbpiu8msdjjxkvlmb-10000000" \
     -d "client_secret=..." \
     -d "grant_type=authorization_code" \
     -d "code=a2f46b46-...-6670c7c4b846" \
     -d "redirect_uri=https://d1z1g2cnqbz2id.cloudfront.net/login/generic_oauth"

{"error":"unauthorized_client","error_description":"Invalid client or Invalid client credentials"}%

(the same response occurs if we submit the client ID/secret via basic auth).

Attempting a similar request with the 18.191.42.248:8081 authorize endpoint, we see:

▶ curl -X 'POST' \
  'http://18.191.42.248:8081/api/v1/identity-management/token' \
  -H 'accept: */*' \
  -H 'Content-Type: application/json' \
  -d '{
  "code": "a2f46b46-...-6670c7c4b846",
  "redirect_uri": "https://d1z1g2cnqbz2id.cloudfront.net/login/generic_oauth",
  "grant_type": "authorization_code",
  "client_id": "veda-n78pbpiu8msdjjxkvlmb-10000000",
  "client_secret": "..."
}'
Unauthorized: Invalid token: Token not found%

(the same response occurs if we submit the client ID/secret via basic auth).