Closed BurningDog closed 2 years ago
The websites I'm authenticating with OAuth make API calls to my business API - everything is on different domains. I don't want to store the OAuth JWT in localStorage, but rather httpOnly secure cookies. That cookie then must be set by the API - which makes it part of the OAuth flow (from a user perspective) and the user must be automatically redirected back to their starting point once done.
During the OAuth authorization code grant workflow, the user needs to be sent back from the connecting API to their starting point - on the source website. I need to know what this starting point is, either by putting it into a session on the API, or (which is much easier), having a source
parameter in the redirect_uri
which will match any value.
I would like to connect multiple resource websites to my OAuth server. Each of these websites are JavaScript apps which make API calls to a backend which needs to load up the User object from the OAuth server. So instead of the authorization code grant workflow being:
it is:
redirect to a specially crafted url on backend API
-> redirect to OAuth server -> login -> authorize OAuth client -> redirect to backend API -> request JWT from OAuth server -> set cookie with JWT -> redirect to JS app
-> use JWT in API calls to backend, which uses the JWT to make API calls to the OAuth server.In the first flow, the OAuth client is the website; in the second, it is the backend API.
In the first flow, the url in the redirect to website
step is https://example.com/redirected
, which is the url I've registered when creating the OAuth client.
However, in the second flow, I would like redirect to a specially crafted url on backend API
to look like https://my-business-api.com/redirected?source=https://example.com/dashboard
(or https://my-business-api.com/redirected?source=example-website
as I can then get the value of example-website
from the database).
validateRedirectUri()
in AuthCodeGrant
This would then match the docs and would be my preferred approach.
I'm happy to PR this, but wanted to check this approach would be ok.
The redirect_uri
value of https://my-business-api.com/redirected?source={*}
would then match https://my-business-api.com/redirected?source=https://another-website.com
I'm not sure how happy bash would be with this command. I'm using zsh on Mac, and
console league:oauth2-server:update-client EGAPI --add-redirect-uri=https://my-business-api.com/redirected?source={*}
got auto-changed to
console league:oauth2-server:update-client EGAPI --add-redirect-uri=https://my-business-api.com/redirected\?source\=\{\*\}
This seems a bit harder to implement - regex matching, and messing around with curly brackets in shells.
Sorry for the confusion here @BurningDog. The client can pre-register multiple return URLs and can specify which one they want to use when issuing a request or can leave the parameter blank and we will use either the first redirect uri registered or the only redirect uri registered.
See this code for where we do this https://github.com/thephpleague/oauth2-server/blob/19dc5e47c465bc9f1804859660b7efe456a40713/src/Grant/AuthCodeGrant.php#L399-L411
The OAuth 2 spec dictates that we must have exact matching URIs for redirects and as far as I can recall, these shouldn't be dynamically set ever. Sorry again for any confusion caused around this.
I will mark this issue as closed but feel free to come back with any further comments and I will reopen this if i've made a mistake anywhere. Thanks
@BurningDog Have you evaluated using the state
param to convey your dynamic data?
See https://www.oauth.com/oauth2-servers/redirect-uris/redirect-uri-registration/#per-request
The docs at https://oauth2.thephpleague.com/authorization-server/auth-code-grant/ say:
This seems to imply that
redirect_uri
could be dynamically set by the requesting client. However, this is not the case - only pre-registeredredirect_uri
s are allowed - see RedirectUriValidator::matchExactUri() - and note thatvalidateRedirectUri()
is not implemented byAuthCodeGrant
.Feature request
redirect_uri
which is specified in the incoming request, orI would prefer 1. More context follows for my use-case.