Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

OAuth2 redirect implementation #135

Open
cay89 opened this issue Aug 12, 2024 · 2 comments
Open

OAuth2 redirect implementation #135

cay89 opened this issue Aug 12, 2024 · 2 comments
Labels
bug Something isn't working

Comments

@cay89
Copy link

cay89 commented Aug 12, 2024

Description

I want to use OpenID Connect's authorization code flow here:

image

Part of this flow involves redirecting to the client after authentication is completed on the Identity Provider's side. However, it seems that this part of the flow is not yet implemented in Laravel Rest API.

By default, the Swagger UI sets the redirect URI to /oauth2-redirect.html, and there is an implementation to handle the response: https://github.com/swagger-api/swagger-ui/blob/master/dist/oauth2-redirect.html. The default redirect URI also can be change as well: https://stackoverflow.com/questions/49518868/oauth2-authorization-in-nelmioapidocbundle/49519134#49519134.

So maybe the easiest way to handle this is to install Swagger UI in my own project and then create a route where I load Swagger UI's oauth2-redirect.html. If I want to change the redirect URI as well, then I want to override your blade template where the Swagger UI was loaded. Later it might be a problem that the Swagger UI version used by the Laravel Rest API is different from mine, so I have to pay attention to that too.

The question is, do I have to do this with a workaround, or do you plan for the Laravel Rest API to support this as well?

@GautierDele
Copy link
Member

I'm not quite sure to understand the problem you have there, using openID, you have the "openIdConnectUrl" and then you'll need to redirect to the correct url
I'm not an openApi expert but this seems to be possible using this: https://github.com/swagger-api/swagger-ui/blob/master/dist/oauth2-redirect.html#L12

For the security schemes I used the openApi examples, this might not be related to SwaggerUI

If I understand well, the problem is only on the redirect side once openId protocol has been approved on server ?

@cay89
Copy link
Author

cay89 commented Aug 16, 2024

@GautierDele The problem occurs when the Identity Provider redirects you back to the application (in our case, the API documentation). A 404 error will occur if we do not set the oauth2RedirectUrl in the SwaggerUI settings, or create a route for the default /oauth2-redirect.html URL which does not exist by default. The Swagger UI code above should be served at this URL to handle the response and 'remember' the tokens for use in the documentation.

Here's my rough workaround for testing routes/api-php:

Route::get('/oauth2-redirect.html', function () {
    return OAUTH2_REDIRECT;
})->name('oauth2-redirect');

// https://github.com/swagger-api/swagger-ui/blob/master/dist/oauth2-redirect.html
const OAUTH2_REDIRECT = <<<CODE
<!doctype html>
<html lang="en-US">
<head>
    <title>Swagger UI: OAuth2 Redirect</title>
</head>
<body>
<script>
    'use strict';
    function run () {
        var oauth2 = window.opener.swaggerUIRedirectOauth2;
        var sentState = oauth2.state;
        var redirectUrl = oauth2.redirectUrl;
        var isValid, qp, arr;

        if (/code|token|error/.test(window.location.hash)) {
            qp = window.location.hash.substring(1).replace('?', '&');
        } else {
            qp = location.search.substring(1);
        }

        arr = qp.split("&");
        arr.forEach(function (v,i,_arr) { _arr[i] = '"' + v.replace('=', '":"') + '"';});
        qp = qp ? JSON.parse('{' + arr.join() + '}',
                function (key, value) {
                    return key === "" ? value : decodeURIComponent(value);
                }
        ) : {};

        isValid = qp.state === sentState;

        if ((
          oauth2.auth.schema.get("flow") === "accessCode" ||
          oauth2.auth.schema.get("flow") === "authorizationCode" ||
          oauth2.auth.schema.get("flow") === "authorization_code"
        ) && !oauth2.auth.code) {
            if (!isValid) {
                oauth2.errCb({
                    authId: oauth2.auth.name,
                    source: "auth",
                    level: "warning",
                    message: "Authorization may be unsafe, passed state was changed in server. The passed state wasn't returned from auth server."
                });
            }

            if (qp.code) {
                delete oauth2.state;
                oauth2.auth.code = qp.code;
                oauth2.callback({auth: oauth2.auth, redirectUrl: redirectUrl});
            } else {
                let oauthErrorMsg;
                if (qp.error) {
                    oauthErrorMsg = "["+qp.error+"]: " +
                        (qp.error_description ? qp.error_description+ ". " : "no accessCode received from the server. ") +
                        (qp.error_uri ? "More info: "+qp.error_uri : "");
                }

                oauth2.errCb({
                    authId: oauth2.auth.name,
                    source: "auth",
                    level: "error",
                    message: oauthErrorMsg || "[Authorization failed]: no accessCode received from the server."
                });
            }
        } else {
            oauth2.callback({auth: oauth2.auth, token: qp, isValid: isValid, redirectUrl: redirectUrl});
        }
        window.close();
    }

    if (document.readyState !== 'loading') {
        run();
    } else {
        document.addEventListener('DOMContentLoaded', function () {
            run();
        });
    }
</script>
</body>
</html>
CODE;

@GautierDele GautierDele added the bug Something isn't working label Oct 4, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

2 participants