private static async Task PrintClaimsIntrospectionClient() { // Get DiscoveryClient from IdentityServer using IdentityModel DiscoveryClient discoInstance = new DiscoveryClient(authority: authority) { Policy = new DiscoveryPolicy { RequireHttps = false } // For development }; DiscoveryResponse disco = await discoInstance.GetAsync(); if (disco.IsError) { Console.WriteLine("Disco error {0}", disco.Error); return; } var introspectionClient = new IntrospectionClient(endpoint: disco.IntrospectionEndpoint, clientId: "api1", clientSecret: clientSecret); var response = await introspectionClient.SendAsync(new IntrospectionRequest { Token = _token.AccessToken }); if (!response.IsError) { Console.WriteLine("Claims for the user"); response.Claims.ToList().ForEach(claim => Console.WriteLine("{0}: {1}", claim.Type, claim.Value)); Console.WriteLine("\n\n"); } }
private async Task <IntrospectionClient> InitializeIntrospectionClient() { string endpoint; if (Options.IntrospectionEndpoint.IsPresent()) { endpoint = Options.IntrospectionEndpoint; } else { endpoint = await GetIntrospectionEndpointFromDiscoveryDocument().ConfigureAwait(false); Options.IntrospectionEndpoint = endpoint; } IntrospectionClient client; if (Options.IntrospectionHttpHandler != null) { client = new IntrospectionClient( endpoint, innerHttpMessageHandler: Options.IntrospectionHttpHandler); } else { client = new IntrospectionClient(endpoint); } client.Timeout = Options.DiscoveryTimeout; return(client); }
public async Task when_refreshing_old_access_token_should_not_change_old_exp() { var tokenClient = new TokenClient(TokenEndpoint, clientId, clientSecret, _handler); var tokenResponse = await tokenClient.RequestResourceOwnerPasswordAsync("bob", "bob", "api1 offline_access"); var introspectionClient = new IntrospectionClient(IntrospectionEndpoint, scope, scopeSecret, _handler); var introspectionResponse1 = await introspectionClient.SendAsync(new IntrospectionRequest { Token = tokenResponse.AccessToken }); var exp1 = Int32.Parse(introspectionResponse1.Claims.Single(x => x.Item1 == "exp").Item2); await Task.Delay(1000); var refreshResponse = await tokenClient.RequestRefreshTokenAsync(tokenResponse.RefreshToken); var introspectionResponse2 = await introspectionClient.SendAsync(new IntrospectionRequest { Token = tokenResponse.AccessToken }); var exp2 = Int32.Parse(introspectionResponse2.Claims.Single(x => x.Item1 == "exp").Item2); exp1.Should().Be(exp2); }
private static void Introspection(string accessToken) { var client = new IntrospectionClient( "https://localhost:44333/core/connect/introspect", "write", "secret"); var request = new IntrospectionRequest { Token = accessToken }; var result = client.SendAsync(request).Result; if (result.IsError) { Console.WriteLine(result.Error); } else { if (result.IsActive) { result.Claims.ToList().ForEach(c => Console.WriteLine("{0}: {1}", c.Item1, c.Item2)); } else { Console.WriteLine("token is not active"); } } }
private static async Task <ClaimsPrincipal> ValidateToken(string jwtToken, string issuer, string resource) { var introspectionClient = new IntrospectionClient( Environment.GetEnvironmentVariable("IdpIntrospectionEndpoint"), Environment.GetEnvironmentVariable("IdpIntrospectionEndpointClientId"), Environment.GetEnvironmentVariable("IdpIntrospectionEndpointClientSecret")); var response = await introspectionClient.SendAsync( new IntrospectionRequest { Token = jwtToken }); if (!response.IsActive) { return(null); } var handler = new JwtSecurityTokenHandler(); handler.InboundClaimTypeMap.Clear(); var principal = handler.ValidateToken(jwtToken, new TokenValidationParameters() { ValidIssuer = issuer, ValidAudience = resource, ValidateIssuerSigningKey = false, SignatureValidator = (t, param) => new JwtSecurityToken(t), NameClaimType = "sub" }, out SecurityToken _); return(principal); }
private static IReadOnlyList <IRemoteExecutorAccessor> CreateRemoteExecutors( IDictionary <NameString, DocumentNode> schemas) { var executors = new List <IRemoteExecutorAccessor>(); foreach (NameString name in schemas.Keys) { DocumentNode schema = IntrospectionClient.RemoveBuiltInTypes(schemas[name]); IQueryExecutor executor = Schema.Create(schema, c => { c.Options.StrictValidation = false; c.UseNullResolver(); foreach (ScalarTypeDefinitionNode typeDefinition in schema.Definitions.OfType <ScalarTypeDefinitionNode>()) { c.RegisterType(new StringType( typeDefinition.Name.Value, typeDefinition.Description?.Value)); } }).MakeExecutable(b => b.UseQueryDelegationPipeline(name)); executors.Add(new RemoteExecutorAccessor(name, executor)); } return(executors); }
public async Task Additional_request_parameters_should_be_handled_correctly() { var document = File.ReadAllText(FileName.Create("success_introspection_response.json")); var handler = new NetworkHandler(document, HttpStatusCode.OK); var client = new IntrospectionClient( Endpoint, "client", innerHttpMessageHandler: handler); var additionalParams = new Dictionary <string, string> { { "scope", "scope1 scope2" }, { "foo", "bar" } }; var response = await client.SendAsync(new IntrospectionRequest { Token = "token", Parameters = additionalParams }); // check request var fields = QueryHelpers.ParseQuery(handler.Body); fields.Count.Should().Be(4); fields["client_id"].First().Should().Be("client"); fields["token"].First().Should().Be("token"); fields["scope"].First().Should().Be("scope1 scope2"); fields["foo"].First().Should().Be("bar"); // check response response.IsError.Should().BeFalse(); response.ErrorType.Should().Be(ResponseErrorType.None); response.HttpStatusCode.Should().Be(HttpStatusCode.OK); response.IsActive.Should().BeTrue(); response.Claims.Should().NotBeEmpty(); }
public async Task <TokenValidationResult> IsValidToken(string accessToken) { var client = new IntrospectionClient(appSettings.IntrospectUrl); var result = await client.SendAsync(new IntrospectionRequest { Token = accessToken, ClientId = appSettings.ClientId, ClientSecret = appSettings.ClientSecret }).ConfigureAwait(false); if (result.IsError) { Log.Error($"An error occurred while validating the access token - {result.Error}"); return(TokenValidationResult.Error); } if (!result.IsActive) { Log.Error("Access token is not active"); return(TokenValidationResult.Expired); } return(TokenValidationResult.Success); }
public async Task ShouldAuthenticateWhenUsingResourceOwnerFlowReferenceToken() { // arrange TokenResponse tokenResponse; IntrospectionResponse introspectionResponse; var referenceScopeName = fixture.Configuration["SpikeReferenceAudience"]; var clientId = fixture.Configuration["SpikeReferenceClient"]; var username = fixture.Configuration["SpikeTestUsername"]; var password = fixture.Configuration["SpikeTestPassword"]; var scopeSecret = fixture.Configuration["ScopeReferenceSecret"]; var handler = fixture.Server.CreateHandler(); DiscoveryResponse discovery = await GetDiscoveryResponse(handler); // act using (var tokenClient = new TokenClient(discovery.TokenEndpoint, clientId, secret, handler)) { tokenResponse = await tokenClient.RequestResourceOwnerPasswordAsync(username, password, apiScope); } using (var introspectionClient = new IntrospectionClient(discovery.IntrospectionEndpoint, referenceScopeName, scopeSecret, handler)) { introspectionResponse = await introspectionClient.SendAsync(new IntrospectionRequest() { Token = tokenResponse.AccessToken }); } // assert introspectionResponse.IsError.Should().BeFalse(); introspectionResponse.Raw.Should().NotBeNullOrWhiteSpace(); }
private static void Introspection(string accessToken) { var client = new IntrospectionClient( Constants.IntrospectionEndpoint, "api1", "secret"); var request = new IntrospectionRequest { Token = accessToken }; var result = client.SendAsync(request).Result; if (result.IsError) { Console.WriteLine(result.Error); } else { if (result.IsActive) { result.Claims.ToList().ForEach(c => Console.WriteLine("{0}: {1}", c.Item1, c.Item2)); } else { Console.WriteLine("token is not active"); } } }
public async Task Response_data_should_be_valid_using_multiple_scopes() { var tokenClient = new TokenClient( TokenEndpoint, "client1", "secret", _handler); var tokenResponse = await tokenClient.RequestClientCredentialsAsync("api3-a api3-b"); var introspectionClient = new IntrospectionClient( IntrospectionEndpoint, "api3", "secret", _handler); var response = await introspectionClient.SendAsync(new IntrospectionRequest { Token = tokenResponse.AccessToken }); var values = response.Json.ToObject <Dictionary <string, object> >(); values["aud"].GetType().Name.Should().Be("String"); var iss = values["iss"].GetType().Name.Should().Be("String");; var nbf = values["nbf"].GetType().Name.Should().Be("Int64");; var exp = values["exp"].GetType().Name.Should().Be("Int64");; var clientId = values["client_id"].GetType().Name.Should().Be("String");; var active = values["active"].GetType().Name.Should().Be("Boolean");; var scopes = (values["scope"] as JArray).Select(x => x.ToString()).ToArray(); scopes.Length.Should().Be(2); scopes.Should().BeEquivalentTo(new string[] { "api3-a", "api3-b" }); }
private async Task <bool> DownloadSchemaAsync(InitCommandContext context) { using var activity = Output.WriteActivity("Download schema"); try { HttpClient client = HttpClientFactory.Create( context.Uri, context.Token, context.Scheme); DocumentNode schema = await IntrospectionClient.LoadSchemaAsync(client); schema = IntrospectionClient.RemoveBuiltInTypes(schema); string schemaFilePath = FileSystem.CombinePath( context.Path, context.SchemaFileName); await FileSystem.WriteToAsync(schemaFilePath, stream => Task.Run(() => SchemaSyntaxSerializer.Serialize( schema, stream, true))); return(true); } catch (HttpRequestException ex) { activity.WriteError( HCErrorBuilder.New() .SetMessage(ex.Message) .SetCode("HTTP_ERROR") .Build()); return(false); } }
private static void TokenIntrospection(string introscpectionEndpoint, string accessToken, string scope, string secret) { var client = new IntrospectionClient(introscpectionEndpoint, scope, secret); var request = new IntrospectionRequest { Token = accessToken }; var result = client.SendAsync(request).Result; if (result.IsError) { Console.WriteLine(result.Error); } else { if (result.IsActive) { var claims = result.Claims.ToList(); var expirationClaim = claims.FirstOrDefault(x => x.Type == "exp"); var validFromClaim = claims.FirstOrDefault(x => x.Type == "nbf"); long expirationTimeStamp = Convert.ToInt64(expirationClaim.Value); long validFromTimeStamp = Convert.ToInt64(validFromClaim.Value); var expirationDate = TimeStampToDate(expirationTimeStamp); var issuedDate = TimeStampToDate(validFromTimeStamp); } else { Console.WriteLine("token is not active"); } } }
public async Task Valid_Token_Valid_Scope_Multiple() { var tokenClient = new TokenClient( TokenEndpoint, "client1", "secret", _handler); var tokenResponse = await tokenClient.RequestClientCredentialsAsync("api1 api2"); var introspectionClient = new IntrospectionClient( IntrospectionEndpoint, "api1", "secret", _handler); var response = await introspectionClient.SendAsync(new IntrospectionRequest { Token = tokenResponse.AccessToken }); response.IsActive.Should().Be(true); response.IsError.Should().Be(false); var scopes = from c in response.Claims where c.Type == "scope" select c; scopes.Count().Should().Be(1); scopes.First().Value.Should().Be("api1"); }
/// <summary> /// Determines if we currently have a valid Authentication token or if we have an expired Authentication token /// we will attempt to refresh it /// </summary> /// <param name="authTokens">Authentication Token</param> /// <returns>True if we have a valid access token</returns> protected virtual async Task <bool> IsValidAccessToken(IAuthTokens authTokens) { if (IsResourcePassworFlowProvider) { return(true); } if (!string.IsNullOrEmpty(authTokens.AccessToken)) { // Check if it is a valid token var tokenResult = await IntrospectionClient.IsValidToken(authTokens.AccessToken) .ConfigureAwait(false); // If it is not a valid token - has it expired? if (tokenResult == TokenValidationResult.Success) { return(true); } // If it has expired and we have a refresh token, refresh the access token. if (tokenResult == TokenValidationResult.Expired && !string.IsNullOrEmpty(authTokens.RefreshToken)) { return(await RefreshTokens(authTokens).ConfigureAwait(false)); } } return(false); }
public async Task Response_data_should_be_valid_using_multiple_scopes() { var tokenClient = new TokenClient( TokenEndpoint, "client1", "secret", _handler); var tokenResponse = await tokenClient.RequestClientCredentialsAsync("api1 api2 unrestricted.api"); var introspectionClient = new IntrospectionClient( IntrospectionEndpoint, "unrestricted.api", "secret", _handler); var response = await introspectionClient.SendAsync(new IntrospectionRequest { Token = tokenResponse.AccessToken }); var values = response.Json.ToObject <Dictionary <string, object> >(); values["aud"].GetType().Name.Should().Be("String"); var iss = values["iss"].GetType().Name.Should().Be("String");; var nbf = values["nbf"].GetType().Name.Should().Be("Int64");; var exp = values["exp"].GetType().Name.Should().Be("Int64");; var clientId = values["client_id"].GetType().Name.Should().Be("String");; var active = values["active"].GetType().Name.Should().Be("Boolean");; var scopes = values["scope"] as JArray; scopes.Count.Should().Be(3); }
private static async Task <IntrospectionClient> InitializeIntrospectionClient(OAuth2IntrospectionOptions options) { string endpoint; if (IsPresent(options.IntrospectionEndpoint)) { endpoint = options.IntrospectionEndpoint; } else { endpoint = await GetIntrospectionEndpointFromDiscoveryDocument(options).ConfigureAwait(false); options.IntrospectionEndpoint = endpoint; } IntrospectionClient client; if (options.IntrospectionHttpHandler != null) { client = new IntrospectionClient( endpoint, headerStyle: options.BasicAuthenticationHeaderStyle, innerHttpMessageHandler: options.IntrospectionHttpHandler); } else { client = new IntrospectionClient(endpoint); } client.Timeout = options.DiscoveryTimeout; return(client); }
public IntrospectionEndpointTokenProvider(IdentityServerBearerTokenAuthenticationOptions options, ILoggerFactory loggerFactory) { _logger = loggerFactory.Create(this.GetType().FullName); if (string.IsNullOrWhiteSpace(options.Authority)) { throw new Exception("Authority must be set to use validation endpoint."); } var baseAddress = options.Authority.EnsureTrailingSlash(); baseAddress += "connect/introspect"; var introspectionEndpoint = baseAddress; var handler = options.IntrospectionHttpHandler ?? new WebRequestHandler(); if (options.BackchannelCertificateValidator != null) { // Set the cert validate callback var webRequestHandler = handler as WebRequestHandler; if (webRequestHandler == null) { throw new InvalidOperationException("The back channel handler must derive from WebRequestHandler in order to use a certificate validator"); } webRequestHandler.ServerCertificateValidationCallback = options.BackchannelCertificateValidator.Validate; } if (!string.IsNullOrEmpty(options.ClientId)) { _client = new IntrospectionClient(() => new HttpMessageInvoker(handler), new IntrospectionClientOptions { Address = introspectionEndpoint, ClientId = options.ClientId, ClientSecret = options.ClientSecret }); //_client = new IntrospectionClient( // introspectionEndpoint, // options.ClientId, // options.ClientSecret, // handler); } else { _client = new IntrospectionClient(() => new HttpMessageInvoker(handler), new IntrospectionClientOptions { Address = introspectionEndpoint }); //_client = new IntrospectionClient( // introspectionEndpoint, // innerHttpMessageHandler: handler); } _options = options; }
public async Task <JsonResult> IntroTestAsync() { var token = HttpContext.Request.Headers["Authorization"].ToString().Replace("Bearer ", ""); var client = "MainSite"; var introspectionClient = new IntrospectionClient(DiscoveryResponse.IntrospectionEndpoint, client, Configuration["ApiInfo:Secrect"]); var response = await introspectionClient.SendAsync(new IntrospectionRequest { Token = token }); return(Json("")); }
async Task <bool> IsAccessTokenValidAsync(Tokens tokens) { var introspectionClient = new IntrospectionClient(MockIdSvrUiPipeline.IntrospectionEndpoint, scope_name, scope_secret, _mockPipeline.Handler); var response = await introspectionClient.SendAsync(new IntrospectionRequest { Token = tokens.AccessToken, TokenTypeHint = IdentityModel.OidcConstants.TokenTypes.AccessToken }); return(response.IsError == false && response.IsActive); }
private async Task <IntrospectionResponse> ValidateToken(string token) { var clientInstroption = new IntrospectionClient(WebConfigurationManager.AppSettings["is3host"] + "/identity/core/connect/introspect", "sampleAPI", "dmsecret"); var request = new IntrospectionRequest { Token = token }; return(clientInstroption.SendAsync(request).Result); }
public async Task <IEnumerable <String> > Secure() { var accessToken = await HttpContext.Authentication.GetTokenAsync("access_token"); var introspectionClient = new IntrospectionClient("https://localhost:44388/connect/introspect", "MyAPI", "TopSecret"); var response = await introspectionClient.SendAsync(new IntrospectionRequest { Token = accessToken }); var isActive = response.IsActive; var claims = response.Claims; return(new[] { "secure1", "secure2", $"isActive: {isActive}", JsonConvert.SerializeObject(claims) }); }
/// <summary> /// Introspection of access token using Identity Server 4's Introspect Client to connect to the introspection endpoint. /// </summary> public static async Task <IntrospectionResponse> OfAccessToken(IntrospectionTokenModel itm) { var introspectionClient = new IntrospectionClient( itm.IntrospectionPath, itm.ScopeName, itm.ScopePassword ); return(await introspectionClient.SendAsync(new IntrospectionRequest { Token = itm.AccessToken })); }
protected override async Task <int> ExecuteCommandAsync() { int result = -1; try { var discoClient = await DiscoveryClient.GetAsync(Server.Value()); if (discoClient.IsError) { Logger.LogError($"{discoClient.ErrorType} : {discoClient.Error}"); } else { var client = new IntrospectionClient(discoClient.IntrospectionEndpoint, Client.Value(), Secret.Value()); var request = new IntrospectionRequest { Token = Token.Value() }; var introspectionResponse = await client.SendAsync(request); if (introspectionResponse.IsError) { Logger.LogError(introspectionResponse.Error); } else { if (introspectionResponse.IsActive) { introspectionResponse.Claims.ToList().ForEach( c => Logger.LogInformation($"{c.Type}: {c.Value}")); } else { Logger.LogInformation("token is not active"); } } } } catch (Exception ex) { throw new CommandException(ex.Message); } return(result); }
public async Task Invalid_Token() { var introspectionClient = new IntrospectionClient( IntrospectionEndpoint, "api1", "secret", _handler); var response = await introspectionClient.SendAsync(new IntrospectionRequest { Token = "invalid" }); response.IsActive.Should().Be(false); response.IsError.Should().Be(false); }
public async Task Exception_should_be_handled_correctly() { var handler = new NetworkHandler(new Exception("exception")); var client = new IntrospectionClient( Endpoint, "client", innerHttpMessageHandler: handler); var response = await client.SendAsync(new IntrospectionRequest { Token = "token" }); response.IsError.Should().BeTrue(); response.ErrorType.Should().Be(ResponseErrorType.Exception); response.Error.Should().Be("exception"); response.Exception.Should().NotBeNull(); }
public async Task Http_error_should_be_handled_correctly() { var handler = new NetworkHandler(HttpStatusCode.NotFound, "not found"); var client = new IntrospectionClient( Endpoint, "client", innerHttpMessageHandler: handler); var response = await client.SendAsync(new IntrospectionRequest { Token = "token" }); response.IsError.Should().BeTrue(); response.ErrorType.Should().Be(ResponseErrorType.Http); response.HttpStatusCode.Should().Be(HttpStatusCode.NotFound); response.Error.Should().Be("not found"); }
public async Task Response_data_with_user_authentication_should_be_valid_using_single_scope() { var tokenClient = new TokenClient( TokenEndpoint, "ro.client", "secret", _handler); var tokenResponse = await tokenClient.RequestResourceOwnerPasswordAsync("bob", "bob", "api1"); tokenResponse.IsError.Should().BeFalse(); var introspectionClient = new IntrospectionClient( IntrospectionEndpoint, "api1", "secret", _handler); var response = await introspectionClient.SendAsync(new IntrospectionRequest { Token = tokenResponse.AccessToken }); var values = response.Json.ToObject <Dictionary <string, object> >(); values["aud"].GetType().Name.Should().Be("JArray"); var audiences = ((JArray)values["aud"]); foreach (var aud in audiences) { aud.Type.Should().Be(JTokenType.String); } values["iss"].GetType().Name.Should().Be("String"); values["nbf"].GetType().Name.Should().Be("Int64"); values["exp"].GetType().Name.Should().Be("Int64"); values["auth_time"].GetType().Name.Should().Be("Int64"); values["client_id"].GetType().Name.Should().Be("String"); values["sub"].GetType().Name.Should().Be("String"); values["active"].GetType().Name.Should().Be("Boolean"); var scopes = values["scope"] as JArray; scopes.Count.Should().Be(1); }
public async Task Malformed_response_document_should_be_handled_correctly() { var document = "invalid"; var handler = new NetworkHandler(document, HttpStatusCode.OK); var client = new IntrospectionClient( Endpoint, "client", innerHttpMessageHandler: handler); var response = await client.SendAsync(new IntrospectionRequest { Token = "token" }); response.IsError.Should().BeTrue(); response.ErrorType.Should().Be(ResponseErrorType.Exception); response.Raw.Should().Be("invalid"); response.Exception.Should().NotBeNull(); }
private async Task UpdateSchemaAsync(string path, SchemaFile schemaFile) { var httpClient = new HttpClient(); httpClient.BaseAddress = new Uri(schemaFile.Url); if (Token != null) { httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue( Scheme ?? "bearer", Token); } var stopwatch = Stopwatch.StartNew(); Console.WriteLine("Download schema started."); DocumentNode schema = await IntrospectionClient.LoadSchemaAsync(httpClient); schema = IntrospectionClient.RemoveBuiltInTypes(schema); Console.WriteLine( "Download schema completed in " + $"{stopwatch.ElapsedMilliseconds} ms for {path}."); stopwatch.Restart(); Console.WriteLine("Client configuration started."); string fileName = IOPath.Combine(path, schemaFile.Name + ".graphql"); if (File.Exists(fileName)) { File.Delete(fileName); } using (var stream = File.Create(fileName)) { using (var sw = new StreamWriter(stream)) { SchemaSyntaxSerializer.Serialize(schema, sw, true); } } Console.WriteLine( "Client configuration completed in " + $"{stopwatch.ElapsedMilliseconds} ms for {path}."); }