visual-studio-codevscode-extensionsvscode-tasks

How to authenticate VSCode extension via browser SSO so extension can post to server API?


I want to create a simple VSCode extension that does a REST API POST of the contents of the editor window to a URL.

The issue is the URL is in a corporate environment behind a browser based single sign on sequence that requires multi-factor authentication with a hardware token and does multiple redirects when a user logs on normally through the browser. I'm not looking to circumvent this in any way, but simply authenticate the VSCode extension somehow so it can do the POST (and re-authenticating every session is fine, just not for every post).

The SSO authentication process seems to be fine with multiple windows in the browser, so e.g. you can login in one window and then do say AJAX POSTS from Javascript in another window to the REST API. So I kind of want VSCode to be considered just another window in that scenario.

I am thinking something like opening a browser window within VSCode itself to allow the user to manually authenticate, then somehow the session is maintained and VSCode can POST to the REST API URL when it wants? Or perhaps triggering a window in an external browser for the authentication but then how would VSCode be authenticated to do the POSTS as the external browser would be a separate application.

Client OS is Windows 8 (corporate policy!) if that makes any difference. I don't have any access to modify anything on the server.

Any thoughts/suggestions welcome, thanks.


Solution

  • Im not sure if i got your problem totally right but i had a similar problem. Its a bit late but anyway...
    My problem was that i needed my VSCode extension to authenticate via a OAuth provider via SSO. So we also needed to open a browser and receive the api_key via the extension. Here's my solution:

    1. First setup an openid client for this i used this openid-client
    2. Generate the Auth URL with the client and open it in Browser
    3. Start a server and listen on local port for the answer of the browser
    4. With the credentials from the oAuthProvider get the API token

    Heres a code example:

        import { Issuer, generators } from 'openid-client';    
        const oidcIssuer = await Issuer.discover('your_oauth_address');
        const oAuthClient = new oidcIssuer.Client({
          client_id: 'your_client_id',
          redirect_uris: 'http://localhost:3000',
          response_types: 'code',
          // The reason for the following settings you can find on: https://stackoverflow.com/questions/76588498/getting-typeerror-client-secret-basic-client-authentication-method-requires-a-c
          token_endpoint_auth_method: 'none',
        });
        const codeVerifier = generators.codeVerifier();
        const authUrl = oAuthClient.authorizationUrl({
          code_challenge: generators.codeChallenge(codeVerifier),
          code_challenge_method: 'S256',
          scope: 'openid offline_access profile',
        });
        
        // Open the URL in an browser
        await vscode.env.openExternal(vscode.Uri.parse(authUrl));
        
        // Create a server to listen on port and handle response
        const app = express();
        app.get('/', async (req, res) => {
          const params = oAuthClient.callbackParams(req);
        // The tokenSet constains the auth_token and refresh_token
        const tokenSet = await oAuthClient.callback('http://localhost:3000', params, { code_verifier: codeVerifier });
        
          // Here your code to get the API Key
        
          res.send('Login success.');
          // Close the server after successful call
          server.close();
          server.closeAllConnections();
        });
        const server = app.listen(3000, () => {});