public void IsNullOrEmpty_ReturnsTrueForNullValues() { // Arrange, act and assert Assert.True(OpenIddictParameter.IsNullOrEmpty(new OpenIddictParameter((bool?)null))); Assert.True(OpenIddictParameter.IsNullOrEmpty(new OpenIddictParameter((long?)null))); Assert.True(OpenIddictParameter.IsNullOrEmpty(new OpenIddictParameter((string?)null))); Assert.True(OpenIddictParameter.IsNullOrEmpty(new OpenIddictParameter((string[]?)null))); }
public void IsNullOrEmpty_ReturnsTrueForEmptyValues() { // Arrange, act and assert Assert.True(OpenIddictParameter.IsNullOrEmpty(new OpenIddictParameter(string.Empty))); Assert.True(OpenIddictParameter.IsNullOrEmpty(new OpenIddictParameter(Array.Empty <string>()))); Assert.True(OpenIddictParameter.IsNullOrEmpty(new OpenIddictParameter( JsonSerializer.Deserialize <JsonElement>("[]")))); Assert.True(OpenIddictParameter.IsNullOrEmpty(new OpenIddictParameter( JsonSerializer.Deserialize <JsonElement>("{}")))); Assert.True(OpenIddictParameter.IsNullOrEmpty(new OpenIddictParameter( JsonSerializer.Deserialize <JsonElement>(@"{""field"":""""}").GetProperty("field")))); }
public void IsNullOrEmpty_ReturnsFalseForNonEmptyValues() { // Arrange, act and assert Assert.False(OpenIddictParameter.IsNullOrEmpty(new OpenIddictParameter(true))); Assert.False(OpenIddictParameter.IsNullOrEmpty(new OpenIddictParameter((bool?)true))); Assert.False(OpenIddictParameter.IsNullOrEmpty(new OpenIddictParameter(42))); Assert.False(OpenIddictParameter.IsNullOrEmpty(new OpenIddictParameter((long?)42))); Assert.False(OpenIddictParameter.IsNullOrEmpty(new OpenIddictParameter("Fabrikam"))); Assert.False(OpenIddictParameter.IsNullOrEmpty(new OpenIddictParameter(new[] { "Fabrikam" }))); Assert.False(OpenIddictParameter.IsNullOrEmpty(new OpenIddictParameter( JsonSerializer.Deserialize <JsonElement>(@"[""Fabrikam""]")))); Assert.False(OpenIddictParameter.IsNullOrEmpty(new OpenIddictParameter( JsonSerializer.Deserialize <JsonElement>(@"{""field"":""Fabrikam""}")))); Assert.False(OpenIddictParameter.IsNullOrEmpty(new OpenIddictParameter( JsonSerializer.Deserialize <JsonElement>(@"{""field"":""Fabrikam""}").GetProperty("field")))); }
private HttpRequestMessage CreateRequestMessage(OpenIddictRequest request, HttpMethod method, Uri uri) { // Note: a dictionary is deliberately not used here to allow multiple parameters with the // same name to be specified. While initially not allowed by the core OAuth2 specification, // this is required for derived drafts like the OAuth2 token exchange specification. var parameters = new List <KeyValuePair <string?, string?> >(); foreach (var parameter in request.GetParameters()) { // If the parameter is null or empty, send an empty value. if (OpenIddictParameter.IsNullOrEmpty(parameter.Value)) { parameters.Add(new KeyValuePair <string?, string?>(parameter.Key, string.Empty)); continue; } var values = (string?[]?)parameter.Value; if (values is not { Length: > 0 })
public void IsNullOrEmpty_ReturnsTrueForUndefinedValues() { // Arrange, act and assert Assert.True(OpenIddictParameter.IsNullOrEmpty(new OpenIddictParameter(default(JsonElement)))); }
private HttpRequestMessage CreateRequestMessage(OpenIddictRequest request, HttpMethod method, Uri uri) { // Note: a dictionary is deliberately not used here to allow multiple parameters with the // same name to be specified. While initially not allowed by the core OAuth2 specification, // this is required for derived drafts like the OAuth2 token exchange specification. var parameters = new List <KeyValuePair <string, string> >(); foreach (var parameter in request.GetParameters()) { // If the parameter is null or empty, send an empty value. if (OpenIddictParameter.IsNullOrEmpty(parameter.Value)) { parameters.Add(new KeyValuePair <string, string>(parameter.Key, string.Empty)); continue; } var values = (string[])parameter.Value; if (values == null || values.Length == 0) { continue; } foreach (var value in values) { parameters.Add(new KeyValuePair <string, string>(parameter.Key, value)); } } if (method == HttpMethod.Get && parameters.Count != 0) { var builder = new StringBuilder(); foreach (var parameter in parameters) { if (builder.Length != 0) { builder.Append('&'); } builder.Append(UrlEncoder.Default.Encode(parameter.Key)); builder.Append('='); builder.Append(UrlEncoder.Default.Encode(parameter.Value)); } if (!uri.IsAbsoluteUri) { uri = new Uri(HttpClient.BaseAddress, uri); } uri = new UriBuilder(uri) { Query = builder.ToString() }.Uri; } var message = new HttpRequestMessage(method, uri); if (method != HttpMethod.Get) { message.Content = new FormUrlEncodedContent(parameters); } return(message); }
public async ValueTask HandleAsync([NotNull] ProcessAuthenticationContext context) { if (context == null) { throw new ArgumentNullException(nameof(context)); } var parameters = await _cache.GetOrCreateAsync( key : string.Concat("af84c073-c27c-49fd-a54f-584fd60320d3", "\x1e", context.Issuer?.AbsoluteUri), factory : async entry => { entry.SetAbsoluteExpiration(TimeSpan.FromMinutes(30)); entry.SetPriority(CacheItemPriority.NeverRemove); return(await GetTokenValidationParametersAsync()); }); context.TokenValidationParameters.ValidIssuer = parameters.ValidIssuer; context.TokenValidationParameters.IssuerSigningKeys = parameters.IssuerSigningKeys; async ValueTask <TokenValidationParameters> GetTokenValidationParametersAsync() { using var client = _factory.CreateClient(Clients.Discovery); var response = await SendHttpRequestMessageAsync(client, context.Options.MetadataAddress); // Ensure the JWKS endpoint URL is present and valid. if (!response.TryGetParameter(Metadata.JwksUri, out var endpoint) || OpenIddictParameter.IsNullOrEmpty(endpoint)) { throw new InvalidOperationException("A discovery response containing an empty JWKS endpoint URL was returned."); } if (!Uri.TryCreate((string)endpoint, UriKind.Absolute, out Uri uri)) { throw new InvalidOperationException("A discovery response containing an invalid JWKS endpoint URL was returned."); } return(new TokenValidationParameters { ValidIssuer = (string)response[Metadata.Issuer], IssuerSigningKeys = await GetSigningKeysAsync(client, uri).ToListAsync() }); }
public async ValueTask HandleAsync([NotNull] ProcessAuthenticationContext context) { if (context == null) { throw new ArgumentNullException(nameof(context)); } var parameters = await _cache.GetOrCreateAsync( key : string.Concat("af84c073-c27c-49fd-a54f-584fd60320d3", "\x1e", context.Issuer?.AbsoluteUri), factory : async entry => { entry.SetAbsoluteExpiration(TimeSpan.FromMinutes(30)); entry.SetPriority(CacheItemPriority.NeverRemove); return(await GetTokenValidationParametersAsync()); }); context.TokenValidationParameters.ValidIssuer = parameters.ValidIssuer; context.TokenValidationParameters.IssuerSigningKeys = parameters.IssuerSigningKeys; async ValueTask <TokenValidationParameters> GetTokenValidationParametersAsync() { using var client = _factory.CreateClient(Clients.Discovery); var response = await SendHttpRequestMessageAsync(client, context.Options.MetadataAddress); // Ensure the JWKS endpoint URL is present and valid. if (!response.TryGetParameter(Metadata.JwksUri, out var endpoint) || OpenIddictParameter.IsNullOrEmpty(endpoint)) { throw new InvalidOperationException("A discovery response containing an empty JWKS endpoint URL was returned."); } if (!Uri.TryCreate((string)endpoint, UriKind.Absolute, out Uri uri)) { throw new InvalidOperationException("A discovery response containing an invalid JWKS endpoint URL was returned."); } return(new TokenValidationParameters { ValidIssuer = (string)response[Metadata.Issuer], IssuerSigningKeys = await GetSigningKeysAsync(client, uri).ToListAsync() }); } async IAsyncEnumerable <SecurityKey> GetSigningKeysAsync(HttpClient client, Uri address) { var response = await SendHttpRequestMessageAsync(client, address); var keys = response[JsonWebKeySetParameterNames.Keys]; if (keys == null) { throw new InvalidOperationException("The OAuth 2.0/OpenID Connect cryptography didn't contain any JSON web key"); } foreach (var payload in keys.Value.GetParameters()) { var type = (string)payload.Value[JsonWebKeyParameterNames.Kty]; if (string.IsNullOrEmpty(type)) { throw new InvalidOperationException("A JWKS response containing an invalid key was returned."); } var key = type switch { JsonWebAlgorithmsKeyTypes.RSA => new JsonWebKey { Kty = JsonWebAlgorithmsKeyTypes.RSA, E = (string)payload.Value[JsonWebKeyParameterNames.E], N = (string)payload.Value[JsonWebKeyParameterNames.N] }, JsonWebAlgorithmsKeyTypes.EllipticCurve => new JsonWebKey { Kty = JsonWebAlgorithmsKeyTypes.EllipticCurve, Crv = (string)payload.Value[JsonWebKeyParameterNames.Crv], X = (string)payload.Value[JsonWebKeyParameterNames.X], Y = (string)payload.Value[JsonWebKeyParameterNames.Y] }, _ => throw new InvalidOperationException("A JWKS response containing an unsupported key was returned.") }; key.KeyId = (string)payload.Value[JsonWebKeyParameterNames.Kid]; key.X5t = (string)payload.Value[JsonWebKeyParameterNames.X5t]; key.X5tS256 = (string)payload.Value[JsonWebKeyParameterNames.X5tS256]; if (payload.Value.TryGetParameter(JsonWebKeyParameterNames.X5c, out var chain)) { foreach (var certificate in chain.GetParameters()) { var value = (string)certificate.Value; if (string.IsNullOrEmpty(value)) { throw new InvalidOperationException("A JWKS response containing an invalid key was returned."); } key.X5c.Add(value); } } yield return(key); } }