/// <summary> /// Initializes a new instance of the <see cref="IdxClient"/> class using the specified <see cref="HttpClient"/>. /// </summary> /// <param name="apiClientConfiguration"> /// The client configuration. If <c>null</c>, the library will attempt to load /// configuration from an <c>okta.yaml</c> file or environment variables. /// </param> /// <param name="httpClient">The HTTP client to use for requests to the Okta API.</param> /// <param name="logger">The logging interface to use, if any.</param> public IdxClient( IdxConfiguration configuration = null, HttpClient httpClient = null, ILogger logger = null) { Configuration = GetConfigurationOrDefault(configuration); IdxConfigurationValidator.Validate(Configuration); GenerateStateCodeVerifierAndChallenge(); _logger = logger ?? NullLogger.Instance; var userAgentBuilder = new UserAgentBuilder("okta-idx-dotnet", typeof(IdxClient).GetTypeInfo().Assembly.GetName().Version); // TODO: Allow proxy configuration httpClient = httpClient ?? DefaultHttpClient.Create( connectionTimeout: null, proxyConfiguration: null, logger: _logger); var oktaBaseConfiguration = OktaConfigurationConverter.Convert(Configuration); var resourceTypeResolverFactory = new AbstractResourceTypeResolverFactory(ResourceTypeHelper.GetAllDefinedTypes(typeof(Resource))); var requestExecutor = new DefaultRequestExecutor(oktaBaseConfiguration, httpClient, _logger); var resourceFactory = new ResourceFactory(this, _logger, resourceTypeResolverFactory); _dataStore = new DefaultDataStore( requestExecutor, new DefaultSerializer(), resourceFactory, _logger, userAgentBuilder); }
/// <summary> /// Initializes a new instance of the <see cref="OktaClient"/> class. /// </summary> /// <param name="apiClientConfiguration"> /// The client configuration. If <c>null</c>, the library will attempt to load /// configuration from an <c>okta.yaml</c> file or environment variables. /// </param> /// <param name="logger">The logging interface to use, if any.</param> /// <param name="serializer">The JSON serializer to use, if any. Using the <c>DefaultSerializer</c> is still strongly recommended since it has all the behavior this SDK needs to work properly. /// If a custom serializer is used, the developer is responsible to add the required logic for this SDK to continue working properly. See <see cref="DefaultSerializer"/> to check out what can be configured. /// </param> public OktaClient(OktaClientConfiguration apiClientConfiguration = null, ILogger logger = null, ISerializer serializer = null) { Configuration = GetConfigurationOrDefault(apiClientConfiguration); OktaClientConfigurationValidator.Validate(Configuration); logger = logger ?? NullLogger.Instance; serializer = serializer ?? new DefaultSerializer(); var defaultClient = DefaultHttpClient.Create( Configuration.ConnectionTimeout, Configuration.Proxy, logger); var resourceFactory = new ResourceFactory(this, logger); IOAuthTokenProvider oAuthTokenProvider = (Configuration.AuthorizationMode == AuthorizationMode.PrivateKey) ? new DefaultOAuthTokenProvider(Configuration, resourceFactory, logger: logger) : NullOAuthTokenProvider.Instance; var requestExecutor = new DefaultRequestExecutor(Configuration, defaultClient, logger, oAuthTokenProvider: oAuthTokenProvider); _dataStore = new DefaultDataStore( requestExecutor, serializer, resourceFactory, logger); PayloadHandler.TryRegister <PkixCertPayloadHandler>(); PayloadHandler.TryRegister <PemFilePayloadHandler>(); PayloadHandler.TryRegister <X509CaCertPayloadHandler>(); }
private static IDataStore PrepareIDataStore(OktaClientConfiguration apiClientConfiguration) { OktaClientConfiguration oktaClientConfiguration = PrepareOktaClientConfiguration(apiClientConfiguration); Microsoft.Extensions.Logging.ILogger logger = Microsoft.Extensions.Logging.Abstractions.NullLogger.Instance; HttpClient httpClient = DefaultHttpClient.Create( oktaClientConfiguration.ConnectionTimeout, oktaClientConfiguration.Proxy, logger); AbstractResourceTypeResolverFactory resourceTypeResolverFactory = null; BaseOktaClient baseOktaClient = new BaseOktaClient(); dynamic resourceFactory = new ResourceFactory(baseOktaClient, logger, resourceTypeResolverFactory); var requestExecutor = new DefaultRequestExecutor(oktaClientConfiguration, httpClient, logger); UserAgentBuilder userAgentBuilder = new UserAgentBuilder( "custom", typeof(CustomAuthnClient).GetTypeInfo().Assembly.GetName().Version); IDataStore dataStore = new DefaultDataStore( requestExecutor, new DefaultSerializer(), resourceFactory, logger, userAgentBuilder); return(dataStore); }
public async Task NotRetryRequestOnceWhenResponseIsNot401AndAuthorizationModeIsPrivateKeyAsync(HttpStatusCode statusCode) { var requestMessageHandler = new MockHttpMessageHandler(string.Empty, statusCode); var httpClientRequest = new HttpClient(requestMessageHandler); var configuration = new OktaClientConfiguration(); configuration.OktaDomain = "https://myOktaDomain.oktapreview.com"; configuration.AuthorizationMode = AuthorizationMode.PrivateKey; configuration.ClientId = "foo"; configuration.PrivateKey = TestCryptoKeys.GetMockRSAPrivateKeyConfiguration(); configuration.Scopes = new List <string> { "foo" }; var oktaClient = new OktaClient(configuration); var logger = Substitute.For <ILogger>(); var resourceFactory = new ResourceFactory(oktaClient, logger); var tokenResponse = @"{""token_type"":""Bearer"",""expires_in"":3600,""access_token"":""foo"",""scope"":""okta.users.read okta.users.manage""}"; var tokenMessageHandler = new MockHttpMessageHandler(tokenResponse, HttpStatusCode.OK); var httpClientToken = new HttpClient(tokenMessageHandler); var tokenProvider = new DefaultOAuthTokenProvider(configuration, resourceFactory, httpClientToken); var requestExecutor = new DefaultRequestExecutor(configuration, httpClientRequest, logger, new NoRetryStrategy(), tokenProvider); var response = await requestExecutor.GetAsync("foo", null, default(CancellationToken)); response.StatusCode.Should().Be((int)statusCode); tokenMessageHandler.NumberOfCalls.Should().Be(1); requestMessageHandler.NumberOfCalls.Should().Be(1); }
public async Task CallRequestMessageProviderOnPostAsync() { var httpClientRequest = new HttpClient(); var configuration = new OktaClientConfiguration { OktaDomain = "https://okta.okta.com", Token = "foo", }; var logger = Substitute.For <ILogger>(); var mockHttpRequestMessageProvider = Substitute.For <IHttpRequestMessageProvider>(); mockHttpRequestMessageProvider .CreateHttpRequestMessage(Arg.Any <HttpRequest>(), Arg.Any <string>()) .Returns(new HttpRequestMessage()); var testRequestExecutor = new DefaultRequestExecutor(configuration, httpClientRequest, logger, new NoRetryStrategy(), null, mockHttpRequestMessageProvider); var testHttpRequest = new HttpRequest { Uri = "/api/v1" }; await testRequestExecutor.PostAsync(testHttpRequest, CancellationToken.None); mockHttpRequestMessageProvider .Received(1) .CreateHttpRequestMessage(Arg.Is(testHttpRequest), Arg.Is <string>("api/v1")); }
/// <summary> /// Initializes a new instance of the <see cref="OktaClient"/> class using the specified <see cref="HttpClient"/>. /// </summary> /// <param name="apiClientConfiguration"> /// The client configuration. If <c>null</c>, the library will attempt to load /// configuration from an <c>okta.yaml</c> file or environment variables. /// </param> /// <param name="httpClient">The HTTP client to use for requests to the Okta API.</param> /// <param name="logger">The logging interface to use, if any.</param> public OktaClient(OktaClientConfiguration apiClientConfiguration, HttpClient httpClient, ILogger logger = null) { Configuration = GetConfigurationOrDefault(apiClientConfiguration); ThrowIfInvalidConfiguration(Configuration); logger = logger ?? NullLogger.Instance; var requestExecutor = new DefaultRequestExecutor(Configuration, httpClient, logger); var resourceFactory = new ResourceFactory(this, logger); _dataStore = new DefaultDataStore( requestExecutor, new DefaultSerializer(), resourceFactory, logger); }
/// <summary> /// Initializes a new instance of the <see cref="OktaClient"/> class. /// </summary> /// <param name="apiClientConfiguration">The client configuration.</param> /// <param name="logger">The logging interface.</param> /// <remarks> /// Configuration can also be specified with a YAML file, or by environment variables. /// </remarks> public OktaClient(OktaClientConfiguration apiClientConfiguration = null, ILogger logger = null) { var compiled = CompileFromConfigurationSources(apiClientConfiguration); var config = new OktaClientConfiguration(); compiled.GetSection("okta").GetSection("client").Bind(config); ThrowIfInvalidConfiguration(config); Configuration = config.DeepClone(); logger = logger ?? NullLogger.Instance; var requestExecutor = new DefaultRequestExecutor(config, logger); var resourceFactory = new ResourceFactory(this, logger); _dataStore = new DefaultDataStore(requestExecutor, new DefaultSerializer(), resourceFactory, logger); }
/// <summary> /// Initializes a new instance of the <see cref="OktaClient"/> class using the specified <see cref="HttpClient"/>. /// </summary> /// <param name="apiClientConfiguration"> /// The client configuration. If <c>null</c>, the library will attempt to load /// configuration from an <c>okta.yaml</c> file or environment variables. /// </param> /// <param name="httpClient">The HTTP client to use for requests to the Okta API.</param> /// <param name="logger">The logging interface to use, if any.</param> /// <param name="retryStrategy">The retry strategy interface to use, if any.</param> /// <param name="serializer">The JSON serializer to use, if any. Using the <c>DefaultSerializer</c> is still strongly recommended since it has all the behavior this SDK needs to work properly. /// If a custom serializer is used, the developer is responsible to add the required logic for this SDK to continue working properly. See <see cref="DefaultSerializer"/> to check out what settings can be configured. /// </param> public OktaClient(OktaClientConfiguration apiClientConfiguration, HttpClient httpClient, ILogger logger = null, IRetryStrategy retryStrategy = null, ISerializer serializer = null) { Configuration = GetConfigurationOrDefault(apiClientConfiguration); OktaClientConfigurationValidator.Validate(Configuration); logger = logger ?? NullLogger.Instance; serializer = serializer ?? new DefaultSerializer(); var requestExecutor = new DefaultRequestExecutor(Configuration, httpClient, logger, retryStrategy); var resourceFactory = new ResourceFactory(this, logger); _dataStore = new DefaultDataStore( requestExecutor, serializer, resourceFactory, logger); }
public DefaultClient( IClientApiKey apiKey, string baseUrl, AuthenticationScheme authenticationScheme, int connectionTimeout, IWebProxy proxy, IHttpClient httpClient, IJsonSerializer serializer, ICacheProvider cacheProvider, IUserAgentBuilder userAgentBuilder, ILogger logger, TimeSpan identityMapExpiration) { if (apiKey == null || !apiKey.IsValid()) { throw new ArgumentException("API Key is not valid."); } if (string.IsNullOrEmpty(baseUrl)) { throw new ArgumentNullException("Base URL cannot be empty."); } if (connectionTimeout < 0) { throw new ArgumentException("Timeout cannot be negative."); } this.logger = logger; this.apiKey = apiKey; this.baseUrl = baseUrl; this.connectionTimeout = connectionTimeout; this.proxy = proxy; this.cacheProvider = cacheProvider; this.authenticationScheme = authenticationScheme; this.serializer = serializer; this.httpClient = httpClient; var requestExecutor = new DefaultRequestExecutor(httpClient, apiKey, authenticationScheme, this.logger); this.dataStore = new DefaultDataStore(this as IClient, requestExecutor, baseUrl, this.serializer, this.logger, userAgentBuilder, cacheProvider, identityMapExpiration); this.dataStoreAsync = this.dataStore as IInternalAsyncDataStore; this.dataStoreSync = this.dataStore as IInternalSyncDataStore; }
/// <summary> /// Initializes a new instance of the <see cref="OktaClient"/> class. /// </summary> /// <param name="apiClientConfiguration"> /// The client configuration. If <c>null</c>, the library will attempt to load /// configuration from an <c>okta.yaml</c> file or environment variables. /// </param> /// <param name="logger">The logging interface to use, if any.</param> public OktaClient(OktaClientConfiguration apiClientConfiguration = null, ILogger logger = null) { Configuration = GetConfigurationOrDefault(apiClientConfiguration); ThrowIfInvalidConfiguration(Configuration); logger = logger ?? NullLogger.Instance; var defaultClient = DefaultHttpClient.Create( Configuration.ConnectionTimeout, Configuration.Proxy, logger); var requestExecutor = new DefaultRequestExecutor(Configuration, defaultClient, logger); var resourceFactory = new ResourceFactory(this, logger); _dataStore = new DefaultDataStore( requestExecutor, new DefaultSerializer(), resourceFactory, logger); }
public async Task NotSendCloseConnectionHeaderWhenUsingTheDefaultClient() { var testOktaClient = TestClient.Create(); var configuration = testOktaClient.Configuration; var httpClient = DefaultHttpClient.Create(configuration.ConnectionTimeout, configuration.Proxy, NullLogger.Instance); var requestExecutor = new DefaultRequestExecutor(configuration, httpClient, NullLogger.Instance); var resourceFactory = new ResourceFactory(testOktaClient, NullLogger.Instance); var dataStore = new DefaultDataStore(requestExecutor, new DefaultSerializer(), resourceFactory, NullLogger.Instance); var response = await dataStore.GetAsync <Resource>( new HttpRequest { // Endpoint that returns a chunked response Uri = $"/api/v1/meta/schemas/user/default", }, null, default(CancellationToken)); var connectionHeader = response.Headers.FirstOrDefault(x => x.Key.Equals("connection", StringComparison.OrdinalIgnoreCase)); connectionHeader.Value?.Any(s => s.Equals("close", StringComparison.OrdinalIgnoreCase)).Should().BeFalse(); }