Server to Server user authentication and get Access token

Attempting to test the server to server okta sso based customer login middleware service which will be used by frontend application and backend (to validate the token and get user profile detail)

Here is the kind of curl snippet I am trying to test this


function getAccessTokenInOkta() {
    local sessionToken=$1
    response=$(curl -sS  --request POST \
      --url "${OKTA_DOMAIN}/oauth2/v1/token" \
      --header 'Content-Type: application/x-www-form-urlencoded' \
      --data "grant_type=authorization_code&client_id=${OKTA_CLIENT_ID}&client_secret=${OKTA_CLIENT_SECRET}&redirect_uri=${OKTA_REDIRECT_URI}&code=${sessionToken}")

    echo "Access Token Response:"
    echo "${response}" | jq '.' || echo "${response}"
}


function loginUserInOkta() {
    local email=$1
    local password="${2:-'secure-password-rand-123'}"

    authn_response=$(curl -sS --request POST \
      --url "${OKTA_DOMAIN}/api/v1/authn" \
      --header 'Content-Type: application/json' \
      --data "{\"username\": \"${email}\", \"password\": \"${password}\"}")

    echo "Authn Response:"
    echo "${authn_response}" | jq '.' || echo "${authn_response}"

    sessionToken=$(echo "${authn_response}" | jq -r '.sessionToken')
    if [[ "${sessionToken}" != "null" ]]; then
      getAccessTokenInOkta "${sessionToken}"
    else
        echo "No sessionToken found in the authn response."
    fi
}

and seeing this response on the access_token retrieval Response:

{
  "error": "invalid_grant",
  "error_description": "The authorization code is invalid or has expired."
}

What Am I missing?

Note:

  • I enabled all API grant types to test.
  • login works and gives sessionToken with 5 minutes / 300 seconds life time as mentioned in the document. Retrieval of access_token called immediately next micro-second and getting this above response - so assuming this is not expired sessionToken but something to do with grant_type am passing vs whats in my account.

The authorization code needed for the /token request will be returned to your application when/if you make a /authorize request. This /authorize request is when you would provide the sessionToken as proof of the user completing primary authentication.

I recommend reading through our guide on how to implement Authorization Code flow to make sure you understand each of the calls needed. In this case, your sequence should be:

  1. POST to /api/v1/authn → returns a sessionToken
  2. Browser redirect to /oauth2/v1/authorize?sessionToken=${sessionTokenFromAuthn}&… → returns a code
  3. POST to /oauth2/v1/token, with the code returned during the /authorize call included in the request body → returns tokens

Here, we do not have user interaction between the time they entered user name/email, password but we want the middle layer to do complete auth and then respond the okta access_token as that is the one that has longer lifetime and can be refreshed.

So am I understand - the acess_token can only be generated through three steps?
In that case, what are the other available options we have for doing server to server auth to handle the middleware to do complete auth logic against okta for our frontend to only rely on middleware which will provide username, password only on the one request?

Here is the updated details on the current integration in plan and what is not working - looking for support here.

1. Frontend Interaction

  • Customers sign up or log in on the headless frontend platform. [Note: Customers do not interact with Okta directly; all communications are handled through the middleware - hence the request for Server-to-Server complete user account activities related integration flow/document, which seems not directly available.]
  • The frontend communicates with middleware for all account-related activities.

2. Middleware Role

  • Acts only as a transport layer, connecting to Okta for account activities like account creatio, login & all other user account activities.
  • Using the customer username, password - Middleware to acquire a token from Okta for the frontend to interact with our backend.

3. Backend Process

  • The backend receives tokens from the frontend.
  • To authorize customers, the backend checks token validity with middleware.
  • Middleware validates tokens with Okta and retrieves user details for the backend.
  • Backend uses these details to perform customer-related activities.

4. Token Refresh Flow / Validation Flow on Consecutive Requests to Backend

  • The frontend will do token refreshes (based on the token expiration timeline process) via middleware, which in turn communicates with Okta.
  • The refreshed token is sent back to the frontend, then to the backend.
  • The backend may use cached tokens/user details or verify them again through middleware when the token is not found in the cache.

Current Issue

  • We can obtain a sessionToken using Okta’s /api/v1/authn endpoint.
  • We need an access_token with a longer lifetime suitable for frontend use, which also needs to allow us to refresh and acquire a not expired/new expiry timeline-based token.
  • The current setup does not facilitate obtaining an access_token without browser redirects and additional user authentication steps.
     - Given the above integration plan, how can we modify the process to obtain an `access_token` without requiring browser redirects or additional user authentication?
     - What would be the best approach to integrate this functionality, ensuring the frontend can receive and refresh the `access_token` as needed for our user experience?

Hi Support Team @andrea

Kindly requesting your feedback on the issue that we are having - it will be very much helpful to get some kind of flow diagram like Implement authorization by grant type | Okta Developer