Skip to content

Commit

Permalink
First cut at OpenIdConnectConfiguration and SignedHttpRequest (#2214)
Browse files Browse the repository at this point in the history
* First cut at OpenIdConnectConfiguration and SignedHttpRequest

* addressed review comments

---------

Co-authored-by: Brent Schmaltz <[email protected]>
  • Loading branch information
brentschmaltz and Brent Schmaltz authored Aug 11, 2023
1 parent 9f734da commit 9512da8
Show file tree
Hide file tree
Showing 29 changed files with 3,304 additions and 1,363 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,7 @@ public static string CreateEncodedSignature(string input, SigningCredentials sig
/// <exception cref="ArgumentNullException"><paramref name="input"/> or <paramref name="signingCredentials"/> is null.</exception>
public static string CreateEncodedSignature(string input, SigningCredentials signingCredentials, bool cacheProvider)
{
// TODO create overload that takes a Span<byte> for the input
if (input == null)
throw LogHelper.LogArgumentNullException(nameof(input));

Expand Down

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@
using Microsoft.IdentityModel.Abstractions;
using Microsoft.IdentityModel.Logging;
using Microsoft.IdentityModel.Tokens;
using Newtonsoft.Json;

namespace Microsoft.IdentityModel.Protocols.OpenIdConnect
{
Expand Down Expand Up @@ -68,7 +67,7 @@ public static async Task<OpenIdConnectConfiguration> GetAsync(string address, ID
if (LogHelper.IsEnabled(EventLogLevel.Verbose))
LogHelper.LogVerbose(LogMessages.IDX21811, doc);

OpenIdConnectConfiguration openIdConnectConfiguration = JsonConvert.DeserializeObject<OpenIdConnectConfiguration>(doc);
OpenIdConnectConfiguration openIdConnectConfiguration = OpenIdConnectConfigurationSerializer.Read(doc);
if (!string.IsNullOrEmpty(openIdConnectConfiguration.JwksUri))
{
if (LogHelper.IsEnabled(EventLogLevel.Verbose))
Expand Down

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,10 @@
using System.Collections.Generic;
using System.Collections.Specialized;
using System.Reflection;
using System.Text;
using System.Text.Json;
using Microsoft.IdentityModel.Logging;
using Newtonsoft.Json.Linq;
using JsonPrimitives = Microsoft.IdentityModel.Tokens.Json.JsonSerializerPrimitives;

namespace Microsoft.IdentityModel.Protocols.OpenIdConnect
{
Expand All @@ -15,6 +17,8 @@ namespace Microsoft.IdentityModel.Protocols.OpenIdConnect
/// </summary>
public class OpenIdConnectMessage : AuthenticationProtocolMessage
{
internal const string ClassName = "Microsoft.IdentityModel.Protocols.OpenIdConnect.OpenIdConnectMessage";

/// <summary>
/// Initializes a new instance of the <see cref="OpenIdConnectMessage"/> class.
/// </summary>
Expand All @@ -30,7 +34,7 @@ public OpenIdConnectMessage(string json)

try
{
SetJsonParameters(JObject.Parse(json));
SetJsonParameters(json);
}
catch
{
Expand Down Expand Up @@ -82,7 +86,7 @@ public OpenIdConnectMessage(NameValueCollection nameValueCollection)
/// <summary>
/// Initializes a new instance of the <see cref="OpenIdConnectMessage"/> class.
/// </summary>
/// <param name="parameters">Enumeration of key value pairs.</param>
/// <param name="parameters">Enumeration of key value pairs.</param>
public OpenIdConnectMessage(IEnumerable<KeyValuePair<string, string[]>> parameters)
{
if (parameters == null)
Expand All @@ -104,30 +108,20 @@ public OpenIdConnectMessage(IEnumerable<KeyValuePair<string, string[]>> paramete
}
}

/// <summary>
/// Initializes a new instance of the <see cref="OpenIdConnectMessage"/> class.
/// </summary>
/// <param name="json">The JSON object from which the instance is created.</param>
[Obsolete("The 'OpenIdConnectMessage(object json)' constructor is obsolete. Please use 'OpenIdConnectMessage(string json)' instead.")]
public OpenIdConnectMessage(object json)
{
if (json == null)
throw LogHelper.LogArgumentNullException(nameof(json));

var jObject = JObject.Parse(json.ToString());
SetJsonParameters(jObject);
}

private void SetJsonParameters(JObject json)
private void SetJsonParameters(string json)
{
if (json == null)
throw LogHelper.LogArgumentNullException("json");
Utf8JsonReader reader = new(Encoding.UTF8.GetBytes(json).AsSpan());

foreach (var pair in json)
while (JsonPrimitives.ReaderRead(ref reader))
{
if (json.TryGetValue(pair.Key, out JToken value))
if (reader.TokenType == JsonTokenType.PropertyName)
{
SetParameter(pair.Key, value.ToString());
string propertyName = JsonPrimitives.GetPropertyName(ref reader, ClassName, true);
string propertyValue = null;
if (reader.TokenType == JsonTokenType.String)
propertyValue = JsonPrimitives.ReadString(ref reader, propertyName, ClassName);

SetParameter(propertyName, propertyValue);
}
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.

using System;

namespace Microsoft.IdentityModel.Protocols.OpenIdConnect
{
/// <summary>
Expand Down Expand Up @@ -53,4 +55,53 @@ public static class OpenIdConnectParameterNames
public const string VersionTelemetry = "x-client-ver";
#pragma warning restore 1591
}

/// <summary>
/// Parameter names for OpenIdConnect UTF8 bytes.
/// </summary>
internal static class OpenIdConnectParameterUtf8Bytes
{
public static ReadOnlySpan<byte> AccessToken => "access_token"u8;
public static ReadOnlySpan<byte> AcrValues => "acr_values"u8;
public static ReadOnlySpan<byte> ClaimsLocales => "claims_locales"u8;
public static ReadOnlySpan<byte> ClientAssertion => "client_assertion"u8;
public static ReadOnlySpan<byte> ClientAssertionType => "client_assertion_type"u8;
public static ReadOnlySpan<byte> ClientId => "client_id"u8;
public static ReadOnlySpan<byte> ClientSecret => "client_secret"u8;
public static ReadOnlySpan<byte> Code => "code"u8;
public static ReadOnlySpan<byte> Display => "display"u8;
public static ReadOnlySpan<byte> DomainHint => "domain_hint"u8;
public static ReadOnlySpan<byte> Error => "error"u8;
public static ReadOnlySpan<byte> ErrorDescription => "error_description"u8;
public static ReadOnlySpan<byte> ErrorUri => "error_uri"u8;
public static ReadOnlySpan<byte> ExpiresIn => "expires_in"u8;
public static ReadOnlySpan<byte> GrantType => "grant_type"u8;
public static ReadOnlySpan<byte> Iss => "iss"u8;
public static ReadOnlySpan<byte> IdToken => "id_token"u8;
public static ReadOnlySpan<byte> IdTokenHint => "id_token_hint"u8;
public static ReadOnlySpan<byte> IdentityProvider => "identity_provider"u8;
public static ReadOnlySpan<byte> LoginHint => "login_hint"u8;
public static ReadOnlySpan<byte> MaxAge => "max_age"u8;
public static ReadOnlySpan<byte> Nonce => "nonce"u8;
public static ReadOnlySpan<byte> Password => "password"u8;
public static ReadOnlySpan<byte> PostLogoutRedirectUri => "post_logout_redirect_uri"u8;
public static ReadOnlySpan<byte> Prompt => "prompt"u8;
public static ReadOnlySpan<byte> RedirectUri => "redirect_uri"u8;
public static ReadOnlySpan<byte> RefreshToken => "refresh_token"u8;
public static ReadOnlySpan<byte> RequestUri => "request_uri"u8;
public static ReadOnlySpan<byte> Resource => "resource"u8;
public static ReadOnlySpan<byte> ResponseMode => "response_mode"u8;
public static ReadOnlySpan<byte> ResponseType => "response_type"u8;
public static ReadOnlySpan<byte> Scope => "scope"u8;
public static ReadOnlySpan<byte> SkuTelemetry => "x-client-SKU"u8;
public static ReadOnlySpan<byte> SessionState => "session_state"u8;
public static ReadOnlySpan<byte> Sid => "sid"u8;
public static ReadOnlySpan<byte> State => "state"u8;
public static ReadOnlySpan<byte> TargetLinkUri => "target_link_uri"u8;
public static ReadOnlySpan<byte> TokenType => "token_type"u8;
public static ReadOnlySpan<byte> UiLocales => "ui_locales"u8;
public static ReadOnlySpan<byte> UserId => "user_id"u8;
public static ReadOnlySpan<byte> Username => "username"u8;
public static ReadOnlySpan<byte> VersionTelemetry => "x-client-ver"u8;
}
}
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.

using System;

namespace Microsoft.IdentityModel.Protocols.OpenIdConnect
{
/// <summary>
/// OpenIdProviderConfiguration Names
/// OpenIdProviderConfiguration MetadataName
/// http://openid.net/specs/openid-connect-discovery-1_0.html#ProviderMetadata
/// </summary>
public static class OpenIdProviderMetadataNames
Expand Down Expand Up @@ -58,4 +60,58 @@ public static class OpenIdProviderMetadataNames
public const string UserInfoSigningAlgValuesSupported = "userinfo_signing_alg_values_supported";
#pragma warning restore 1591
}

/// <summary>
/// OpenIdProviderConfiguration MetadataName - UTF8Bytes
/// http://openid.net/specs/openid-connect-discovery-1_0.html#ProviderMetadata
/// </summary>
internal static class OpenIdProviderMetadataUtf8Bytes
{
public static ReadOnlySpan<byte> AcrValuesSupported => "acr_values_supported"u8;
public static ReadOnlySpan<byte> AuthorizationEndpoint => "authorization_endpoint"u8;
public static ReadOnlySpan<byte> CheckSessionIframe => "check_session_iframe"u8;
public static ReadOnlySpan<byte> ClaimsLocalesSupported => "claims_locales_supported"u8;
public static ReadOnlySpan<byte> ClaimsParameterSupported => "claims_parameter_supported"u8;
public static ReadOnlySpan<byte> ClaimsSupported => "claims_supported"u8;
public static ReadOnlySpan<byte> ClaimTypesSupported => "claim_types_supported"u8;
public static ReadOnlySpan<byte> Discovery => ".well-known/openid-configuration"u8;
public static ReadOnlySpan<byte> DisplayValuesSupported => "display_values_supported"u8;
public static ReadOnlySpan<byte> EndSessionEndpoint => "end_session_endpoint"u8;
public static ReadOnlySpan<byte> FrontchannelLogoutSessionSupported => "frontchannel_logout_session_supported"u8;
public static ReadOnlySpan<byte> FrontchannelLogoutSupported => "frontchannel_logout_supported"u8;
public static ReadOnlySpan<byte> HttpLogoutSupported => "http_logout_supported"u8;
public static ReadOnlySpan<byte> GrantTypesSupported => "grant_types_supported"u8;
public static ReadOnlySpan<byte> IdTokenEncryptionAlgValuesSupported => "id_token_encryption_alg_values_supported"u8;
public static ReadOnlySpan<byte> IdTokenEncryptionEncValuesSupported => "id_token_encryption_enc_values_supported"u8;
public static ReadOnlySpan<byte> IdTokenSigningAlgValuesSupported => "id_token_signing_alg_values_supported"u8;
public static ReadOnlySpan<byte> IntrospectionEndpoint => "introspection_endpoint"u8;
public static ReadOnlySpan<byte> IntrospectionEndpointAuthMethodsSupported => "introspection_endpoint_auth_methods_supported"u8;
public static ReadOnlySpan<byte> IntrospectionEndpointAuthSigningAlgValuesSupported => "introspection_endpoint_auth_signing_alg_values_supported"u8;
public static ReadOnlySpan<byte> JwksUri => "jwks_uri"u8;
public static ReadOnlySpan<byte> Issuer => "issuer"u8;
public static ReadOnlySpan<byte> LogoutSessionSupported => "logout_session_supported"u8;
public static ReadOnlySpan<byte> MicrosoftMultiRefreshToken => "microsoft_multi_refresh_token"u8;
public static ReadOnlySpan<byte> OpPolicyUri => "op_policy_uri"u8;
public static ReadOnlySpan<byte> OpTosUri => "op_tos_uri"u8;
public static ReadOnlySpan<byte> RegistrationEndpoint => "registration_endpoint"u8;
public static ReadOnlySpan<byte> RequestObjectEncryptionAlgValuesSupported => "request_object_encryption_alg_values_supported"u8;
public static ReadOnlySpan<byte> RequestObjectEncryptionEncValuesSupported => "request_object_encryption_enc_values_supported"u8;
public static ReadOnlySpan<byte> RequestObjectSigningAlgValuesSupported => "request_object_signing_alg_values_supported"u8;
public static ReadOnlySpan<byte> RequestParameterSupported => "request_parameter_supported"u8;
public static ReadOnlySpan<byte> RequestUriParameterSupported => "request_uri_parameter_supported"u8;
public static ReadOnlySpan<byte> RequireRequestUriRegistration => "require_request_uri_registration"u8;
public static ReadOnlySpan<byte> ResponseModesSupported => "response_modes_supported"u8;
public static ReadOnlySpan<byte> ResponseTypesSupported => "response_types_supported"u8;
public static ReadOnlySpan<byte> ServiceDocumentation => "service_documentation"u8;
public static ReadOnlySpan<byte> ScopesSupported => "scopes_supported"u8;
public static ReadOnlySpan<byte> SubjectTypesSupported => "subject_types_supported"u8;
public static ReadOnlySpan<byte> TokenEndpoint => "token_endpoint"u8;
public static ReadOnlySpan<byte> TokenEndpointAuthMethodsSupported => "token_endpoint_auth_methods_supported"u8;
public static ReadOnlySpan<byte> TokenEndpointAuthSigningAlgValuesSupported => "token_endpoint_auth_signing_alg_values_supported"u8;
public static ReadOnlySpan<byte> UILocalesSupported => "ui_locales_supported"u8;
public static ReadOnlySpan<byte> UserInfoEndpoint => "userinfo_endpoint"u8;
public static ReadOnlySpan<byte> UserInfoEncryptionAlgValuesSupported => "userinfo_encryption_alg_values_supported"u8;
public static ReadOnlySpan<byte> UserInfoEncryptionEncValuesSupported => "userinfo_encryption_enc_values_supported"u8;
public static ReadOnlySpan<byte> UserInfoSigningAlgValuesSupported => "userinfo_signing_alg_values_supported"u8;
}
}
Original file line number Diff line number Diff line change
@@ -1,28 +1,5 @@
//------------------------------------------------------------------------------
//
// Copyright (c) Microsoft Corporation.
// All rights reserved.
//
// This code is licensed under the MIT License.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files(the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and / or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions :
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
//
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.

using System.Collections.Generic;
using Microsoft.IdentityModel.Logging;
Expand Down
Loading

0 comments on commit 9512da8

Please sign in to comment.