Uploaded image for project: 'Core Server'
  1. Core Server
  2. SERVER-67654

Implement authorization code token acquisition flow in the mongo shell

    • Type: Icon: Task Task
    • Resolution: Done
    • Priority: Icon: Major - P3 Major - P3
    • None
    • Affects Version/s: None
    • Component/s: None
    • Labels:
      None
    • Security 2022-08-22, Security 2022-09-05, Security 2022-09-19, Security 2022-10-03, Security 2022-10-17, Security 2022-10-31

      After SERVER-67625, the server now can recognize the OIDC SASL mechanism when featureFlagOIDCSpike is enabled and has the ability to provide the client with the requisite authURL, clientId, and clientSecret needed to retrieve the authorization code and then the ID token. Additionally, the server is now capable of parsing and validating ID tokens presented to it as compactly serialized JWSes. 

      In order to validate the server's ability to participate in OIDC authentication flows, we can model the client application-side authorization code flow in the mongo shell. This will allow an end user to authenticate to a standalone mongod deployment using an external identity provider (in this case, MongoDB's Okta authorization server).

      This ticket will require the following components:

      1. Create a new SaslOIDCClientConversation class that extends from SaslClientConversation. In its first step, it should simply send the username to the server. Refer to the implementation of SaslOIDCServerConversation for the exact format that this should be sent in.
      2. In the second step, it should parse the idp, clientId, and clientSecret from the server. After parsing that information, it should launch a browser pointing to idp + /oauth2/default/v1/authorize?client_id=<clientId>&response_type=code&scope=openid&state=<randomstring>&redirect_uri=http://localhost:47617/authorize/callback using the system syscall (this should work on Unix systems, and the shell will be running on OS X for demo purposes). Then, it should launch a HTTP server listening on all local interfaces at port 47617.
      3. In order to build the HTTP server, vendor the boost::beast library. To vendor the library into the server codebase, modify this line such that it only contains beast and then run the script.
      4. Use this example to help build the HTTP server with beast. It should only service GET requests at the /authorize/callback endpoint. In the /authorize/code endpoint, it look for a parameter called code in the request. That parameter will store the authorization code after the end user performs successful authentication to the IDP via the browser.
      5. After retrieving the authorization code, the HTTP server should launch a HTTP client POST request to the IDP's token endpoint, which will be the idp + /oauth2/v1/token?redirect_uri=http://localhost:47617/authorize/token&grant_type=authorization_code&code=<code>. The POST request's header will have accept: application/json, authorization: <B64(client_id:client_secret)>, and content-type: application/x-www-form-urlencoded as parameters. The HTTP server will then parse the id_token field in the response in order to get the serialized JWS representation of the ID token and return it to the SaslOIDCClientConversation.
      6. The SaslOIDCClientConversation's second step will then return the serialized token as the payload to be sent to the server and will return true to indicate that the client-side SASL session is now complete.

            Assignee:
            varun.ravichandran@mongodb.com Varun Ravichandran
            Reporter:
            varun.ravichandran@mongodb.com Varun Ravichandran
            Votes:
            0 Vote for this issue
            Watchers:
            2 Start watching this issue

              Created:
              Updated:
              Resolved: