okta-auth-js
okta-auth-js copied to clipboard
Use well-known configuration to infer token issuer and authorization server endpoints
TLDR:
- It looks like the PKCE flow breaks when the base URL of well-known config is not the same as the issuer claim in the token
- The well-known config returns all the necessary information needed to authorize the client, get a token, and validate its issuer claim, so it could be used for this.
Long version:
I'm running into a problem with this SDK because my well-known config endpoint is not the same base as the issuer of my tokens. And because the SDK validates the issuer of the token against what is passed in as the issuer
parameter and uses this parameter to form the endpoint for the well-known request, it seems I cannot do both.
If the SDK is already requesting the well-known configuration in the PKCE flow, why not use the response to infer all of the other information needed about the authorization server? The configuration returns the issuer of the token, so that should be used to validate the token when it is received. Furthermore, the configuration returns the authorization_endpoint
and token_endpoint
, which could be used in place of the authUrl
and tokenUrl
SDK options.
In an ideal world, the issuer
would not be a required option for the Okta SDK, and instead I could just supply a wellKnownUrl
or something similar to get all the information needed to complete my auth flow.
@djfdev - Thanks for the report and solid explanation.
Internal ref: OKTA-300072
@djfdev We are investigating this issue and working on a better solution for url discovery. In the meantime, it may work for you to explicitly set the authorizeUrl
or tokenUrl
on the config:
https://github.com/okta/okta-auth-js#additional-options
Please let us know if this will function as a workaround. Thanks!
@aarongranick-okta that's what we are doing now, and it works but it is not an ideal solution.
We have what is perhaps a unique situation, in that we use a proxy to communicate with the Okta authorization server(s). So the base URL of the well-known config endpoint is not the same as the issuer of the token. For now, we provide the authorization server URL for the issuer
parameter, and our proxy URLs for the authUrl
and tokenUrl
parameters. Ideally we would just provide a single configuration parameter for the well-known config, from which the token issuer and other endpoints would be inferred.
@swiftone does OKTA-300072 also applies to implicit flow ?
@jberube - yes, the goal of that ticket is to rely on .well-known for endpoints unless specifically overridden, for all flows
@swiftone has there been any progress on this?
@swiftone I'm also interested to hear if there's been any movement on this issue - we are running into the same problem for a browser app currently using okta-react that previously only supported a direct connection to Okta authorisation servers, but which we would like to also enable support for AWS cognito acting as a proxy between them.
Unfortunately in this scenario the well-known config is hosted at a completely different domain to the issuer with the other flow urls, so we are leaning towards reworking our app with another library. This enhancement would instead resolve the problem, I think.
@zaeja Can you provide a little more detail on the "enhancement" you are looking for? If I understand correctly you are using a proxy, so the issuer
and authorizeUrl
that you would like the app to use for the network request will be different from the values returned from the .well-known
endpoint (and included in the token's claims).
Are you looking to skip or customize the validation logic here? https://github.com/okta/okta-auth-js/blob/master/lib/oidc/util/validateClaims.ts#L34
The original issue said: "In an ideal world, the issuer would not be a required option for the Okta SDK, and instead I could just supply a wellKnownUrl or something similar to get all the information needed to complete my auth flow."
I think a wellKnownUrl
option in this case would still return an issuer / authorizeUrl that is not behind the proxy. So I'd like to get into more detail on the specific enhancements we could do to support your case.
@djfdev The issuer returned from the .well-known
endpoint should match the HOST
header of the request. If you have a custom Okta domain setup and hit my.domain.com/.well-known/openid-configuration
it should return my.domain.com
as the issuer.
If you are seeing the issuer NOT matching the HOST header, there may be something misconfigured in your organization's settings. If this is the case, Okta support can help resolve this.
This isn't an okta proxy, its a company proxy. The issuer doesnt match because the issuer is still an okta domain; it has to match the actual issuer on the token that okta returns. We can't make the issuer match the proxy because the proxy isn't minting tokens.
@kyeotic Makes sense. I can think of a couple ways to solve this problem. One would be to intercept at the network layer to request from the proxy instead of the "original" URL. This could use some kind of map from original URL -> proxy URL.
This could be done with the current version using the httpRequestClient option.
Another way would be to bypass/customize the validation logic here. This would require some changes in the SDK.
I'm sure there are other ways to accomplish this. Do you have a specific idea of how you would like to see this scenario supported?
@aarongranick-okta
I'd like to avoid intercepting calls and modifying them, if possible. I'd like to see this solved by changing the validation logic so that the token issuer only had to match the issuer returned by the .well-known
endpoint. There shouldn't need to be a relationship between the host/domain of the .well-known
endpoint and its response contents.
Our .well-known
endpoint's response includes the correct okta issuer, which will match the token. This library doesn't like it, but there doesn't seem to be a good reason to override the .well-known
response with the assumption that it should match the .well-known
's host/domain.
The logic you linked is correct, I think it's just being provided with the wrong parameters. The iss
should come exclusively from the .well-known
response instead of being derived from other values.
Edit: btw @djfdev has moved on to greener pastures, I'm working the original story he raised this issue for.
@kyeotic Thanks, that makes sense. Currently the issuer from the token is compared with the configured issuer, but it can (should) be compared with the issuer returned from well-known. I have updated the notes on the internal issue. I'm hoping we can get a solution out to you quickly.
@aarongranick-okta I might be reading GitHub incorrectly, but it looks like that linked PR was approved and then closed without being merged. Are you still planning to handle this issue?
@kyeotic - you aren't reading github wrong, but our bot interacts with github oddly. The code from the PR was merged:
- you can see it on the list here: https://github.com/okta/okta-auth-js/commits/master
- and as this item in the master commit history: https://github.com/okta/okta-auth-js/commit/756a46079921130a256ac141ccbd7ac2a5716927
But the PR itself is just marked as "Closed". Our bot commits the code after our internal tests pass, and unfortunately it doesn't do a great job of marking the PR as merged. We have a task to improve that, but naturally fixes like this one take priority over that messaging.
This fix was included in 4.8.0 of okta-auth-js: https://github.com/okta/okta-auth-js/releases/tag/okta-auth-js-4.8.0
Hope that helps!
Awesome! I'm going to test this right now
@swiftone I can't figure out how to configure this correctly. There isn't a documented path to just provide the .well-known
endpoint directly, it appears to generate it based on the issuer
.
Lets say I have our well-known proxy at https://oauth-proxy.com/v1/qa/.well-known/openid-configuration
. It returns the following
{
"issuer":"https://company.oktapreview.com/oauth2/custom_auth_server_id",
"authorization_endpoint":"https://oauth-proxy.com/v1/qa/authorize",
"token_endpoint":"https:/oauth-proxy.com/v1/qa/token"
}
The authorization_endpoint
and token_endpoint
perform redirects to the correct custom auth server.
If I just provide issuer: https://oauth-proxy.com/v1/qa/
it tries to redirect to https://oauth-proxy.com.com/v1/qa/oauth2/v1/authorize
. Where did it get this value from?
If I manually set the authorizeUrl
and tokenUrl
on the config to the proxy values above it signs in, but then still fails with the same "issuer does not match" error, since its comparing the real https://company.oktapreview.com/oauth2/custom_auth_server_id
value against the proxy isssuer from the config.
@aarongranick-okta #646 does not appear to be functioning as intended
@swiftone @aarongranick-okta <friendly reminder that this is broken>
@swiftone @aarongranick-okta bump
@kyeotic - I've left Okta so I'm afraid I can't be very helpful. But, looking at the linked PR:
- As you say, you can't set the well-known endpoint, it is based off of the issuer given to auth-js
- the
validationOptions
should auto-populate based on the info from the well-known endpoint, or you can override those defaults with manual values - the validationOptions apply only to validating the issued tokens, not to generating them (so the authorize enpoint you mention is likewise based off of the passed issuer)
I suspect this is a disagreement about what calls your proxy is...proxying, and what calls Okta expects to be proxied. If you can describe a bit more which calls are proxied I assume the Okta staff can give you a better answer (or find what the code does not yet cover). If you would prefer to be detailed but non-public in your description, Okta has a support team that can be reached at [email protected] and they can work with the SDK team.
Hope that helps!
@swiftone Thank you, I will try to keep going with another maintainer.
@shuowu-okta @vijetmahabaleshwar-okta You've both responded to Swiftone's, are you able to direct this ticket to someone who can assist? It seems there has been a misunderstanding in implementing this feature.
As you say, you can't set the well-known endpoint, it is based off of the issuer given to auth-js
This entire isssue is about the ability to set the well-known endpoint. Our well-known endpoint does not have the same domain as our issuer, since the issuer is Okta and our well-known endpoint is a company proxy. Without the ability to set a well-known endpoint this issue remains unsolved.
@kyeotic Many apologies for this issue falling through a crack, I have confirmed this issue still exists and was not fixed by #646
We have re-prioritized this issue and are currently working on a proper fix. internal ref: OKTA-409981
@aarongranick-okta Has there been any progress on this?
@kyeotic It looks like this issue should have been fixed with https://github.com/okta/okta-auth-js/pull/858
You should be able to use your frontend proxy URL as the "issuer"
@aarongranick-okta - #858 Doesn't seem to have fixed this. In fact there is a test which says "will always use issuer from well-known openid-configuration" in this PR.
We are also not able to use the proxy by setting authUrl and tokenUrl as mentioned. We tried this with latest(5.8.0) version of okta-auth-js too. Can you help us with this?
Sorry for a late reply to pretty old issue.
I'd like to gather more information about using proxies with Okta and okta-auth-js
and would appreciate any feedback.
- What's the intention to use a proxy to communicate with the Okta authorization server(s), and for token endpoint? What problem can it solve?
- Can using a custom domain solve this issue?
- Does your Okta org use Identity Engine, and application uses Interaction Code flow?
@djfdev
@ashwini-desai
You can use authorizeUrl (not authUrl
) and tokenUrl in configuration options for latest okta-auth-js
versions. Does it work for you?
@kyeotic
-
authorization_endpoint
andtoken_endpoint
returned from.well-known/openid-configuration
are not currently used for overriding configuration inokta-auth-js
, but you can useauthorizeUrl
andtokenUrl
options. Is this sufficient or you want to rely on well-known response (maybe for dynamic configuration)? - You said "The authorization_endpoint and token_endpoint perform redirects to the correct custom auth server."
Does it mean your
https://oauth-proxy.com/v1/qa/authorize
would just redirect tohttps://company.oktapreview.com/oauth2/v1/authorize
with 302 status code, or really proxy responses?
- No, we need to use the response from well-known. I know they are not currently used, this was a request for a change to the library. FWIW, the change we are requesting is that this library use the configuration that it gets from the the endpoint that the oAuth spec says holds configuration. This change was agreed to. Are we back to discussing whether or not to do it?
- It redirects with a 302.
I'm facing the same issue. It looks like this library is not OIDC compliant, it doesn't use the values provided in the well-known document, but instead uses some pre-configured values in the code (i.e. in getOAuthUrls
). I don't quite understand why the librar doesn't use the well-known document for OIDC? That's what it is meant to be used for.
I guess this library is meant to be only used with the pure OktaAuth service, not as a general OIDC library, unfortunately?!