Unusual customer OAuth params
My customer has their own OAuth provider which I must use. Their flow requires that to sign in, my app redirects to
customer-oauth/account/signin?redirect=<redirect_url>&some=custom¶ms=needed
Once the user logs in there, they are returned to my app, at the url redirect_url?customer_portal_token=<some_token>
Note the customer_portal_token
, a custom param they use. Once they are redirected, I must call customer-oauth/auth/get-token
with the customer_portal_token
short-lived token, which will return me a new access_token.
oidc-client-ts
and react-oidc-context
setup
Before understanding their non-standard naming convention, I had set my app up with oidc-client-ts
with react, via react-oidc-context
, as I've done many times before with something like keycloak:
import { AuthProvider, AuthProviderProps } from "react-oidc-context";
const oidcConfig: AuthProviderProps = {
authority: AUTHORITY,
redirect_uri: MY_APP_URL,
};
const App = () => {
return (
<AuthProvider {...oidcConfig}>
<AppHere />
</AuthProvider />
)
}
import { useAuth } from "react-oidc-context";
const DeeperInTheApp = () => {
const { isAuthenticated, signinRedirect, signoutRedirect } = useAuth();
return isAuthenticated
? <button onClick={() => signinRedirect()}>logout</button>
: <button onClick={() => signoutRedirect()}>login</button>
}
The happy path with keycloak
This works well with keycloak. With keycloak, when the login button is clicked, a call to KEYCLOAK_URL/realms/master/.well-known/openid-configuration
is made, and the oidc metadata has the url of the signin url, as well as the token url. The user is redirected to the signin url, where they log in. On login success, they are returned to my app at the url of something like redirect_url?state=<hash>&session_state=<hash>&iss=<redirect_url>&code=<code_hash>
. A call is made to the token route from the well-known
call using the params in that signin redirect url, and a response is gotten with things like id_token
, acess_token
, refresh_token
, etc. The react-oidc-context is then considered "logged in", as expected.
Massaging customer custom OAuth params into this setup
In my case, there is no metadata route for the oidc. So I have to provide that manually in my oidcConfig:
const oidcConfig: AuthProviderProps = {
authority: CUSTOMER_OIDC,
metadata: {
issuer: CUSTOMER_OIDC,
authorization_endpoint: `${CUSTOMER_OIDC}/account/signin`,
token_endpoint: `${CUSTOMER_OIDC}/get-refresh`,
},
};
With some custom params on sign-in:
const DeeperInTheApp = () => {
const { isAuthenticated, signinRedirect, user, signoutRedirect } = useAuth();
return isAuthenticated
? <button
onClick={() => signinRedirect(
extraQueryParams({
some: 'custom',
params: 'needed'
})
)}>
logout
</button>
: <button onClick={() => signoutRedirect()}>login</button>
}
This works - when I click the login butto, signinRedirect
is called. I am taken to the customer's OAuth portal, with all the correct custom params put in, with my app's url as the redirect url. After sign-in, I am taken back to my app.
But now instead of oidc-client-ts knowing to call the token_endpoint
with the param customer_portal_token=<the_token_from_signin_redirect>
, nothing happens.
How can I push oidc-client-ts and react-oidc-context to take this final step, and call the customer's custom token endpoint, with the custom customer_portal_token
param that is found in the signin redirect url? I want to leverage all the existing functionality of oidc-client-ts and react-oidc-context without having to basically write my own auth handler. Seems like I should be able to coax the libraries into calling the token route with the custom param, saving the response in the react-oidc-context state, and have the oidc-context consider the app authenticated.
Is this possible?