okta / okta-signin-widget

HTML/CSS/JS widget that provides out-of-the-box authentication UX for your organization's apps
Other
376 stars 319 forks source link

idpDiscovery with requestContext does not provide access & Id token #1512

Open ey52fpv opened 3 years ago

ey52fpv commented 3 years ago

:information_source: If you have a question, please post it on the Okta Developer Forum instead. Issues in this repository are reserved for bug reports and feature requests.

I'm submitting a

Background info

I'm working on React App with OKTA Sign in Widget that has 2 users flows internal organization users vs external. For external users, the password are stored in the APP's OKTA org and I'm able to retrieve access & id token on successful authentication. For internal users, the APP's OKTA org make a SAML request to organization's OKTA org for authentication and on successful authentication when it redirects to APP it does not come with access & id token.

const widget = new OktaSignIn({ baseUrl: XXX, clientId:XXX, redirectUri: window.location.origin + '/implicit/callback', i18n: { en: { 'primaryauth.title': 'XXX', }, }, authParams: { pkce:true, issuer:XXX, display: 'page', scopes: ['openid', 'profile', 'email'], responseMode: 'query', responseType: ['id_token', 'token'], }, tokenManager: { secure: false }, cookies: { secure: false }, features: { registration: false, idpDiscovery: true }, idpDiscovery:{ requestContext: '/home/oidc_client/1234/5678' } });

Code Snippet:

const { authState, authService } = useOktaAuth(); useEffect(() => { if (!authState.isPending) { if (!authState.isAuthenticated) { // When user isn't authenticated, forget any user info authService.login("/"); } else { authService.getUser().then((info) => { getUsers(info.sub); }); } } },[authState,authService]);

For internal users, authState is undefined and hence it redirects to login page.

Your environment

swiftone commented 3 years ago

Hi @ey52fpv - Are you using the widget hosted on an okta site, or on your own site? Unfortunately, for the latter case, idpDiscovery is not yet an officially supported feature.

ey52fpv commented 3 years ago

HI @swiftone we have widget hosted on our react app. I know idpdiscovery is only EA feature, but it's available for our OKTA tenant that we are using for the app. Also the authentication for internal users with IDP is happening as per the expected behaviour. Only the redirection back to app post authentication is causing problem.

ey52fpv commented 3 years ago

Is there a feasibility that the internal users flow will be redirected to apps '/implicit/callback' endpoint after authentication with authorization code?

moein commented 3 years ago

For future reference we did a small hack (which added very small overhead) for idp login. After setting requestContext for idpDiscovery to be the same as our redirect uri the only query parameter we were receiving was fromLogin=true We took advantage of this query parameter to know that the user has logged in through idp discovery so we triggered the token.getWithRedirect function of auth sdk. Here is the code we used on our callback route:

        if (getUrlParamValue('fromLogin') === 'true') {
            const oktaAuth = new OktaAuth({
                clientId: config.oktaClientId,
                redirectUri: window.location.origin + window.location.pathname,
                issuer: config.issuer,
                pkce: false
            })
            await oktaAuth.token.getWithRedirect({
                responseType: ['code'],
                state: sessionStorage.getItem(config.state)
            });

            return;
        }

2 important notes are since you are not receiving anything like state or nonce you shouldn't try to validate them when you get fromLogin=true and also this configuration is for authorization code flow so if you are using another flow you might have to change responseType and pkce configuration.

sflanker commented 3 years ago

While I appreciate the workaround suggestion above, adding an extra redirect cycle was more overhead that I am willing to accept. So I forked this package and created one that redirects IDP users to /oauth2/default/v1/authorize instead of redirecting to the dysfunctional IDP endpoint. See @invio/okta-signin-widget on npm. And here's a simple static HTML/JS example of how it works with IDP discovery and PKCE flow.