Get Token from Asp.net Core to pass to backend as verification

Hello!

I’m trying to integrate Okta authentication into a suite of apps that are built in-house. Initially, I had an idea for passing the user’s “token” once authenticated between the backend servers to be used as a “login” to verify the user before processing the request. Basically a flow like this:

  1. Users attempts to access .net core front end
  2. Redirected to Okta login page
  3. Successfully logs in and gets access to front end (everything working great up to this point)
  4. Get “token” of user
  5. Frontend wants to get information from different backend server
  6. Pass token to backend server
  7. Backend server validates token with Okta
  8. Backend sees user is validated and processes the request

I’ve searched and searched and can’t seem to find anything about this. So my question then: is this even possible (and if so what am I missing) or am I completely wrong and should do it a different way?

Thanks, and let me know if you’d like code samples, though it’s mostly the same as the .net core sample.

This sounds very similar to what I am trying to accomplish as well. I am able to authenticate the user and access the id token from the cookie in hopes to pass it in an authorization header when requesting data from my API’s. Here is my post, maybe your post will shed some light on what needs to be done or vice versa.

https://devforum.okta.com/t/cookie-and-jwt-auth/5923

Indeed it does sound similar! I actually was able to make some progress on this, but still a little stuck (maybe you can help). Basically, without even having to change any of my auth setup, I am able to get the token by using:
var idToken = await HttpContext.GetTokenAsync(“id_token”);

Then when I pass that to the backend, I run the following code to verify the jwt token:

//Enable TLS1.2 for okta
ServicePointManager.SecurityProtocol |= SecurityProtocolType.Tls12;
 var issuer = "https://{oktasubdomain}.okta.com";

var configurationManager = new ConfigurationManager<OpenIdConnectConfiguration>(
    issuer + "/.well-known/openid-configuration",
    new OpenIdConnectConfigurationRetriever(),
    new HttpDocumentRetriever());

try
{
    var validatedToken = OktaValidation.ValidateToken(token, issuer, configurationManager).Result;

    return validatedToken;
}
catch (Exception)
{
    return null;
}

Here’s the OktaValidation class:

public static class OktaValidation
{
    public static async Task<JwtSecurityToken> ValidateToken(
    string token,
    string issuer,
    IConfigurationManager<OpenIdConnectConfiguration> configurationManager,
    CancellationToken ct = default(CancellationToken))
    {
        if (string.IsNullOrEmpty(token)) throw new ArgumentNullException(nameof(token));
        if (string.IsNullOrEmpty(issuer)) throw new ArgumentNullException(nameof(issuer));

        var discoveryDocument = await configurationManager.GetConfigurationAsync(ct);
        var signingKeys = discoveryDocument.SigningKeys;

        var validationParameters = new TokenValidationParameters
        {
            RequireExpirationTime = true,
            RequireSignedTokens = true,
            ValidateIssuer = true,
            ValidIssuer = issuer,
            ValidateIssuerSigningKey = true,
            IssuerSigningKeys = signingKeys,
            //If I set this to false then it will verify...but that doesn't seem like the right thing to do
            ValidateLifetime = true, 
            ValidateAudience = false,
            // Allow for some drift in server time
            // (a lower value is better; we recommend two minutes or less)
            ClockSkew = TimeSpan.FromMinutes(2),
            // See additional validation for aud below
        };

        try
        {
            var principal = new JwtSecurityTokenHandler()
                .ValidateToken(token, validationParameters, out var rawValidatedToken);

            return (JwtSecurityToken)rawValidatedToken;
        }
        catch (SecurityTokenValidationException)
        {
            // Logging, etc.

            return null;
        }
    }
}

The problem right now is that the token is failing due to lifetime. We do have a high session timeout for our okta org, so maybe that’s why? The token lifetime doesn’t match the okta session lifetime, so the token is invalidating before okta requires a re-signin? If it’s a fresh signin then it validates fine…

You know the concept you have explained, sign in once and access many apps is know as Single Sign On or SSO for short, and OKTA already supports this. Why not try to implement your solution along this school of thought?

Hey @cjackson, that is what I am attempting to accomplish. However the backend server isn’t directly accessed by the user, so normal SSO authentication wouldn’t work. That’s what I’m trying to solve here with the token validation. I believe I have it functioning correctly, and after some further testing will post the results.