public static void ValidateToken(string tokenString, string secret) { var securityKey = new System.IdentityModel.Tokens.InMemorySymmetricSecurityKey(Encoding.Default.GetBytes(secret)); var jwt = new System.IdentityModel.Tokens.JwtSecurityToken(tokenString); var tokenValidationParameters = new System.IdentityModel.Tokens.TokenValidationParameters() { ValidAudiences = new string[] { audience }, ValidIssuers = new string[] { issuer }, IssuerSigningKey = securityKey }; System.IdentityModel.Tokens.SecurityToken validatedToken; var handler = new System.IdentityModel.Tokens.JwtSecurityTokenHandler(); handler.ValidateToken(tokenString, tokenValidationParameters, out validatedToken); }
/// <inheritdoc /> public async Task <ActionableMessageTokenValidationResult> ValidateTokenAsync( string token, string targetServiceBaseUrl) { if (string.IsNullOrEmpty(token)) { throw new ArgumentException("token is null or empty.", "token"); } if (string.IsNullOrEmpty(targetServiceBaseUrl)) { throw new ArgumentException("url is null or empty.", "targetServiceBaseUrl"); } CancellationToken cancellationToken; OpenIdConnectConfiguration o365OpenIdConfig = await OpenIdConnectConfigurationRetriever.GetAsync(O365OpenIdConfiguration.MetadataUrl, cancellationToken); ClaimsPrincipal claimsPrincipal; ActionableMessageTokenValidationResult result = new ActionableMessageTokenValidationResult(); var parameters = new System.IdentityModel.Tokens.TokenValidationParameters() { ValidateIssuer = true, ValidIssuers = new[] { O365OpenIdConfiguration.TokenIssuer }, ValidateAudience = true, ValidAudiences = new[] { targetServiceBaseUrl }, ValidateLifetime = true, ClockSkew = TimeSpan.FromMinutes(TokenTimeValidationClockSkewBufferInMinutes), RequireSignedTokens = true, IssuerSigningKeys = o365OpenIdConfig.SigningTokens.SelectMany(st => st.SecurityKeys), }; System.IdentityModel.Tokens.JwtSecurityTokenHandler tokenHandler = new System.IdentityModel.Tokens.JwtSecurityTokenHandler(); try { // This will validate the token's lifetime and the following claims: // // iss // aud // claimsPrincipal = tokenHandler.ValidateToken(token, parameters, out System.IdentityModel.Tokens.SecurityToken validatedToken); } catch (SecurityTokenSignatureKeyNotFoundException ex) { Trace.TraceError("Token signature key not found."); result.Exception = ex; return(result); } catch (SecurityTokenExpiredException ex) { Trace.TraceError("Token expired."); result.Exception = ex; return(result); } catch (SecurityTokenInvalidSignatureException ex) { Trace.TraceError("Invalid signature."); result.Exception = ex; return(result); } catch (Exception ex) { Trace.TraceError(ex.Message); result.Exception = ex; return(result); } if (claimsPrincipal == null) { Trace.TraceError("Identity not found in the token."); result.Exception = new InvalidOperationException("Identity not found in the token"); return(result); } ClaimsIdentity identity = claimsPrincipal.Identities.OfType <ClaimsIdentity>().FirstOrDefault(); if (identity == null) { Trace.TraceError("Claims not found in the token."); result.Exception = new InvalidOperationException("Claims not found in the token."); return(null); } if (!string.Equals(GetClaimValue(identity, "appid"), O365OpenIdConfiguration.AppId, StringComparison.OrdinalIgnoreCase)) { Trace.TraceError( "App ID does not match. Expected: {0} Actual: {1}", O365OpenIdConfiguration.AppId, GetClaimValue(identity, "appid")); return(null); } result.ValidationSucceeded = true; result.Sender = GetClaimValue(identity, "sender"); // Get the value of the "sub" claim. Passing in "sub" will not return a value because the TokenHandler // maps "sub" to ClaimTypes.NameIdentifier. More info here // https://github.com/AzureAD/azure-activedirectory-identitymodel-extensions-for-dotnet/issues/415. result.ActionPerformer = GetClaimValue(identity, ClaimTypes.NameIdentifier); return(result); }