/// <summary>
    /// Creates a unique key to be used as the cache key of the Identity Server access token, by combining infomration from the access token options object.
    /// See <see cref="PasswordOptions"/> for the access token options.
    /// </summary>
    /// <param name="options">The token service options</param>
    /// <returns>Returns a string representing a unique identifier to be used as the caching key, by getting the hashcode of the address, the client, the username and the scopes.</returns>
    public string GetCacheKey(IIdentityServerOptions options)
    {
        if (options == null)
        {
            throw new ArgumentNullException(nameof(options));
        }


        if (options is not PasswordOptions passwordOptions)
        {
            throw new InvalidOperationException("The '" + nameof(options) + "' argument cannot be expicitly converted to " + nameof(PasswordOptions) + ".");
        }

        if (passwordOptions.Address == null)
        {
            throw new InvalidOperationException(nameof(passwordOptions.Address) + " cannot be null.");
        }

        if (passwordOptions.ClientId == null)
        {
            throw new InvalidOperationException(nameof(passwordOptions.ClientId) + " cannot be null.");
        }

        if (passwordOptions.Scope == null)
        {
            throw new InvalidOperationException(nameof(passwordOptions.Scope) + " cannot be null.");
        }

        if (passwordOptions.Username == null)
        {
            throw new InvalidOperationException(nameof(passwordOptions.Username) + " cannot be null.");
        }

        return((passwordOptions.Address + passwordOptions.ClientId + passwordOptions.Scope + passwordOptions.Username).GetHashCode().ToString());
    }
Beispiel #2
0
 /// <summary>
 /// Sets the IdentityServer4 options for retrieving an access token using client credentials by using a delegate.
 /// </summary>
 /// <param name="optionsDelegate">The <see cref="Action{T}"/> delegate.</param>
 /// <returns>Returns the current instance of <see cref="HttpClientService"/> for method chaining.</returns>
 public HttpClientService SetIdentityServerOptions <TOptions>(Action <TOptions> optionsDelegate)
     where TOptions : class, IIdentityServerOptions
 {
     identityServerOptions = Activator.CreateInstance(typeof(TOptions)) as TOptions;
     optionsDelegate(identityServerOptions as TOptions);
     return(this);
 }
Beispiel #3
0
        /// <summary>
        /// Creates a unique key to be used as the cache key of the Identity Server access token, by combining infomration from the access token options object.
        /// See <see cref="ClientCredentialsOptions"/> for the access token options.
        /// </summary>
        /// <param name="options">The token service options</param>
        /// <returns>Returns a string representing a unique identifier to be used as the caching key, by getting the hashcode of the address, the client and scopes.</returns>
        public string GetCacheKey(IIdentityServerOptions options)
        {
            if (options == null)
            {
                throw new ArgumentNullException(nameof(options));
            }

            var clientCredentialOptions = options as ClientCredentialsOptions;

            if (clientCredentialOptions == null)
            {
                throw new InvalidOperationException("The '" + nameof(options) + "' argument cannot be expicitly converted to " + nameof(ClientCredentialsOptions) + ".");
            }

            if (clientCredentialOptions.Address == null)
            {
                throw new InvalidOperationException(nameof(clientCredentialOptions.Address) + " cannot be null.");
            }

            if (clientCredentialOptions.ClientId == null)
            {
                throw new InvalidOperationException(nameof(clientCredentialOptions.ClientId) + " cannot be null.");
            }

            if (clientCredentialOptions.Scope == null)
            {
                throw new InvalidOperationException(nameof(clientCredentialOptions.Scope) + " cannot be null.");
            }

            return((clientCredentialOptions.Address + clientCredentialOptions.ClientId + clientCredentialOptions.Scope).GetHashCode().ToString());
        }
Beispiel #4
0
        public HttpClientService SetIdentityServerOptions(string configurationSection)
        {
            if (_configuration == null)
            {
                throw new InvalidOperationException("The string configuraton cannot be used with the the lazy singleton instance of " + nameof(HttpClientService) + " (" + nameof(HttpClientServiceFactory) + "." + nameof(HttpClientServiceFactory.Instance) + ")");
            }

            var sectionExists = _configuration.GetChildren().Any(item => item.Key == configurationSection);

            if (!sectionExists)
            {
                throw new ArgumentException("The configuration section '" + configurationSection + "' cannot be found!", nameof(configurationSection));
            }

            //todo: find better way
            if (configurationSection.ToLower().EndsWith(nameof(ClientCredentialsOptions).ToLower()))
            {
                identityServerOptions = _configuration.GetSection(configurationSection).Get <ClientCredentialsOptions>();
            }
            else if (configurationSection.ToLower().EndsWith(nameof(PasswordOptions).ToLower()))
            {
                identityServerOptions = _configuration.GetSection(configurationSection).Get <PasswordOptions>();
            }
            else
            {
                //backward compatibility, v3 should eliminate this
                identityServerOptions = _configuration.GetSection(configurationSection).Get <ClientCredentialsOptions>();
                //throw new InvalidOperationException("The name or the suffix of the cofiguration section must be either '" + nameof(ClientCredentialsOptions) + "' or '" + nameof(PasswordOptions) + "'.");
            }

            return(this);
        }
Beispiel #5
0
        /// <summary>
        /// Finds the appropriate implementation of <see cref="IIdentityServerHttpClient"/> based on the <paramref name="options"/>.
        /// </summary>
        /// <param name="options">The <paramref name="options"/> for retrieving an access token.</param>
        /// <returns>An <see cref="IIdentityServerHttpClient"/>.</returns>
        public IIdentityServerHttpClient Get(IIdentityServerOptions options)
        {
            if (!_httpClients.Any(x => x.HttpClientOptionsType.IsAssignableFrom(options.GetType())))
            {
                throw new InvalidOperationException("There is no assignable type for the options selected.");
            }

            return(_httpClients.First(x => x.HttpClientOptionsType.IsAssignableFrom(options.GetType())));
        }
Beispiel #6
0
        /// <summary>
        /// Sets the IdentityServer4 options by passing an object that inherits from <see cref="ClientCredentialsOptions"/>
        /// </summary>
        /// <param name="options">The <see cref="IIdentityServerOptions"/> that contains the options.</param>
        public HttpClientService SetIdentityServerOptions <TOptions>(TOptions options)
            where TOptions : class, IIdentityServerOptions
        {
            if (options == null)
            {
                throw new ArgumentNullException(nameof(options));
            }

            identityServerOptions = options;
            return(this);
        }
        /// <summary>
        /// Retrieves a <see cref="TokenResponse"/> from the configured by the <paramref name="options"/>.
        /// </summary>
        /// <param name="options">The <see cref="PasswordOptions"/> for the IdentityServer4.</param>
        /// <returns>A <see cref="TokenResponse"/> object.</returns>
        public async Task <TokenResponse> GetTokenResponseAsync(IIdentityServerOptions options)
        {
            if (options == default)
            {
                throw new ArgumentNullException(nameof(options));
            }

            var passwordOptions = options as PasswordOptions;

            if (passwordOptions == null)
            {
                throw new InvalidOperationException("The '" + nameof(options) + "' argument cannot be expicitly converted to " + nameof(PasswordOptions) + ".");
            }

            if (passwordOptions.Address == null)
            {
                throw new InvalidOperationException(nameof(passwordOptions.Address) + " cannot be null.");
            }

            if (passwordOptions.ClientId == null)
            {
                throw new InvalidOperationException(nameof(passwordOptions.ClientId) + " cannot be null.");
            }

            if (passwordOptions.Scope == null)
            {
                throw new InvalidOperationException(nameof(passwordOptions.Scope) + " cannot be null.");
            }

            if (passwordOptions.Username == null)
            {
                throw new InvalidOperationException(nameof(passwordOptions.Username) + " cannot be null.");
            }

            return(await _httpClient.RequestPasswordTokenAsync(new PasswordTokenRequest
            {
                Address = passwordOptions.Address,
                ClientId = passwordOptions.ClientId,
                ClientSecret = passwordOptions.ClientSecret,
                Scope = passwordOptions.Scope,
                UserName = passwordOptions.Username,
                Password = passwordOptions.Password
            }));
        }
Beispiel #8
0
    /// <summary>
    /// Retrieves either a new access token using client credentials or the last valid from the caching engine.
    /// </summary>
    /// <param name="options">The token service options.</param>
    /// <returns>A <see cref="TokenResponse"/> instance.</returns>
    public async Task <TokenResponse> GetTokenResponseAsync(IIdentityServerOptions options)
    {
        if (options == default)
        {
            throw new ArgumentNullException(nameof(options));
        }

        var httpClient = _identityServerHttpClientSelector.Get(options);

        var tokenResponse = await _cache.AddOrGetExistingAsync(
            httpClient.GetCacheKey(options),
            async() =>
        {
            return(await httpClient.GetTokenResponseAsync(options));
        }
            );

        return(tokenResponse);
    }
Beispiel #9
0
        /// <summary>
        /// Retrieves a <see cref="TokenResponse"/> from the configured by the <paramref name="options"/>.
        /// </summary>
        /// <param name="options">The <see cref="ClientCredentialsOptions"/> for the IdentityServer4.</param>
        /// <returns>A <see cref="TokenResponse"/> object.</returns>
        public async Task <TokenResponse> GetTokenResponseAsync(IIdentityServerOptions options)
        {
            if (options == null)
            {
                throw new ArgumentNullException(nameof(options));
            }

            var clientCredentialOptions = options as ClientCredentialsOptions;

            if (clientCredentialOptions == null)
            {
                throw new InvalidOperationException("The '" + nameof(options) + "' argument cannot be expicitly converted to " + nameof(ClientCredentialsOptions) + ".");
            }

            if (clientCredentialOptions.Address == null)
            {
                throw new InvalidOperationException(nameof(clientCredentialOptions.Address) + " cannot be null.");
            }

            if (clientCredentialOptions.ClientId == null)
            {
                throw new InvalidOperationException(nameof(clientCredentialOptions.ClientId) + " cannot be null.");
            }

            if (clientCredentialOptions.Scope == null)
            {
                throw new InvalidOperationException(nameof(clientCredentialOptions.Scope) + " cannot be null.");
            }

            return(await _httpClient.RequestClientCredentialsTokenAsync(new ClientCredentialsTokenRequest
            {
                Address = clientCredentialOptions.Address,
                ClientId = clientCredentialOptions.ClientId,
                ClientSecret = clientCredentialOptions.ClientSecret,
                Scope = clientCredentialOptions.Scope
            }));
        }
 /// <summary>
 /// Finds the appropriate implementation of <see cref="IIdentityServerHttpClient"/> based on the <paramref name="options"/>.
 /// </summary>
 /// <param name="options">The <paramref name="options"/> for retrieving an access token.</param>
 /// <returns>An <see cref="IIdentityServerHttpClient"/>.</returns>
 public IIdentityServerHttpClient Get(IIdentityServerOptions options)
 {
     return(!_httpClients.Any(x => x.HttpClientOptionsType.IsAssignableFrom(options.GetType()))
         ? throw new InvalidOperationException("There is no assignable type for the options selected. Does your options inherit from either " + nameof(ClientCredentialsOptions) + " or " + nameof(PasswordOptions) + "?")
         : _httpClients.First(x => x.HttpClientOptionsType.IsAssignableFrom(options.GetType())));
 }