private async Task<AccessTokenIntrospectionResult> IntrospectTokenOnlineAsync(string accessToken, AccessTokenType accessTokenType, DiscoveryDocumentShortInfo discoveryDocument) { // TODO: This approach should be reconsidered in future. /* The solution below allows use "Orleans.Security" with IdentityServer4 v2.x and IdentityServer4 v3.x. At the same time, DLR with Reflection in is a bad idea. */ const string fullyQualifiedNameOfType = "IdentityModel.Client.HttpClientTokenIntrospectionExtensions, IdentityModel"; dynamic request = Activator.CreateInstance(Type.GetType("IdentityModel.Client.TokenIntrospectionRequest, IdentityModel", true)); request.Address = discoveryDocument.IntrospectionEndpoint; request.ClientId = _identityServer4Info.ClientId; request.Token = accessToken; request.ClientSecret = _identityServer4Info.ClientSecret; var cancellationToken = default(CancellationToken); var param = new object[] { _httpClient,request, cancellationToken }; var introspectionResponse = await RuntimeMethodBinder.InvokeAsync(fullyQualifiedNameOfType, "IntrospectTokenAsync", param, 3); // TODO: This should be used normally. /* var request = new TokenIntrospectionRequest { Address = discoveryDocument.IntrospectionEndpoint, ClientId = _identityServer4Info.ClientId, Token = accessToken, ClientSecret = _identityServer4Info.ClientSecret, }; var introspectionResponse = await _httpClient.IntrospectTokenAsync(request); */ var nameOfTokenType = accessTokenType == AccessTokenType.Jwt ? "JWT" : "Reference"; // ReSharper disable once ConvertIfStatementToReturnStatement if (!introspectionResponse.IsError) { return new AccessTokenIntrospectionResult(accessTokenType, introspectionResponse.Claims, introspectionResponse.IsActive); } _logger.LogTrace(LoggingEvents.AccessTokenValidationFailed, $"{LoggingEvents.AccessTokenValidationFailed.Name} Token type: {nameOfTokenType} " + $"Reason: {introspectionResponse.Error} " + $"Token value: {accessToken}"); return new AccessTokenIntrospectionResult(accessTokenType, introspectionResponse.Claims, false); }
internal static IEnumerable <Claim> Verify(string jwt, string audience, DiscoveryDocumentShortInfo discoveryDocument) { var keys = new List <SecurityKey>(); foreach (var webKey in discoveryDocument.Keys) { var e = Base64Url.Decode(webKey.E); var n = Base64Url.Decode(webKey.N); var key = new RsaSecurityKey(new RSAParameters { Exponent = e, Modulus = n }) { KeyId = webKey.Kid }; keys.Add(key); } var parameters = new TokenValidationParameters { ValidIssuer = discoveryDocument.Issuer, ValidAudience = audience, IssuerSigningKeys = keys, NameClaimType = JwtClaimTypes.Name, RoleClaimType = JwtClaimTypes.Role, RequireSignedTokens = true }; var handler = new JwtSecurityTokenHandler(); handler.InboundClaimTypeMap.Clear(); var claimsPrincipal = handler.ValidateToken(jwt, parameters, out var validatedToken); return(claimsPrincipal.Claims); }