/// <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()); }
/// <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); }
/// <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()); }
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); }
/// <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()))); }
/// <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 })); }
/// <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); }
/// <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()))); }