示例#1
0
        /// <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);
        }
示例#2
0
        /// <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>();
        }
示例#3
0
        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"));
        }
示例#6
0
        /// <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);
        }
示例#8
0
        /// <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;
        }
示例#10
0
        /// <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();
        }