Wondering if the following approach is valid
Front End:
-
ASP.NET MVC (4.7.2) →
-
(serves angular spa that makes api callls)
-
OKTA Middleware (implicit flow) →
-
Login →
-
Subsequent requests use cookie for auth.
Back End API Calls:
-
ASP.NET MVC (4.7.2) (currently same web app as front end) →
-
(essentially backend making http calls to itself)
-
Get token from issuer →
-
Make API call →
-
API Authentication Filter validates Token
-
(the filter tries to validate via token if request isn’t authenticated yet).
Additional Detail:
There are API calls from the font-end, and those would be authenticated with the cookie.
All other ‘expected’ API calls would come from our internal servers only, and will send a token with every request.
Validating the token with the following code:
(rough draft prototype coded in LinqPad)
public static void ValidateToken(string tokenFromOkta)
{
var issuer = $"{AuthConfig.I.OktaDomain}/oauth2/{AuthConfig.I.OktaApiIssuer}";
issuer.Dump("Issuer URL");
//Get validation info from OKta
var configurationManager = new ConfigurationManager<OpenIdConnectConfiguration>(
issuer + "/.well-known/oauth-authorization-server",
new OpenIdConnectConfigurationRetriever(),
new HttpDocumentRetriever());
var discoveryDocument = configurationManager.GetConfigurationAsync(default(CancellationToken)).Result;
var signingKeys = discoveryDocument.SigningKeys;
//Owin JWT validates
var handler = new JwtSecurityTokenHandler();
var validationParameters = new Microsoft.IdentityModel.Tokens.TokenValidationParameters()
{
RequireExpirationTime = true,
RequireSignedTokens = true,
ValidateIssuer = true,
ValidateAudience = false,
ValidIssuer = issuer,
ValidateIssuerSigningKey = true,
IssuerSigningKeys = signingKeys,
ValidateLifetime = true,
// 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
};
SecurityToken validatedToken;
var resultToken = JToken.Parse(tokenFromOkta);
var tokenString = resultToken.Value<string>("access_token");
var claimsPrincipal = handler.ValidateToken(tokenString, validationParameters, out validatedToken);
validatedToken.Dump("validated token");
claimsPrincipal.Dump("Claims Prinicipal");
}