diff --git a/src/Microsoft.IdentityModel.Protocols.OpenIdConnect/Configuration/OpenIdConnectConfiguration.cs b/src/Microsoft.IdentityModel.Protocols.OpenIdConnect/Configuration/OpenIdConnectConfiguration.cs index 6ddc1b613d..36fb436a61 100644 --- a/src/Microsoft.IdentityModel.Protocols.OpenIdConnect/Configuration/OpenIdConnectConfiguration.cs +++ b/src/Microsoft.IdentityModel.Protocols.OpenIdConnect/Configuration/OpenIdConnectConfiguration.cs @@ -28,6 +28,7 @@ public class OpenIdConnectConfiguration : BaseConfiguration private ICollection _claimsSupported; private ICollection _claimsLocalesSupported; private ICollection _claimTypesSupported; + private ICollection _codeChallengeMethodsSupported; private ICollection _displayValuesSupported; private ICollection _dPoPSigningAlgValuesSupported; private ICollection _grantTypesSupported; @@ -42,6 +43,8 @@ public class OpenIdConnectConfiguration : BaseConfiguration private ICollection _requestObjectSigningAlgValuesSupported; private ICollection _responseModesSupported; private ICollection _responseTypesSupported; + private ICollection _revocationEndpointAuthMethodsSupported; + private ICollection _revocationEndpointAuthSigningAlgValuesSupported; private ICollection _scopesSupported; private ICollection _subjectTypesSupported; private ICollection _tokenEndpointAuthMethodsSupported; @@ -233,6 +236,24 @@ public OpenIdConnectConfiguration(string json) Interlocked.CompareExchange(ref _claimTypesSupported, new Collection(), null) ?? _claimTypesSupported; + /// + /// Gets the collection of 'code_challenge_methods_supported' + /// + [JsonPropertyName(OpenIdProviderMetadataNames.CodeChallengeMethodsSupported)] + public ICollection CodeChallengeMethodsSupported => + _codeChallengeMethodsSupported ?? + Interlocked.CompareExchange(ref _codeChallengeMethodsSupported, new Collection(), null) ?? + _codeChallengeMethodsSupported; + + /// + /// Gets or sets the 'device_authorization_endpoint'. + /// + [JsonPropertyName(OpenIdProviderMetadataNames.DeviceAuthorizationEndpoint)] +#if NET6_0_OR_GREATER + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] +#endif + public string DeviceAuthorizationEndpoint { get; set; } + /// /// Gets the collection of 'display_values_supported' /// @@ -374,7 +395,7 @@ public OpenIdConnectConfiguration(string json) /// Gets or sets the /// [JsonIgnore] - public JsonWebKeySet JsonWebKeySet {get; set;} + public JsonWebKeySet JsonWebKeySet { get; set; } /// /// Boolean value specifying whether the OP can pass a sid (session ID) query parameter to identify the RP session at the OP when the logout_uri is used. Dafault Value is false. @@ -508,6 +529,33 @@ public OpenIdConnectConfiguration(string json) Interlocked.CompareExchange(ref _responseTypesSupported, new Collection(), null) ?? _responseTypesSupported; + /// + /// Gets or sets the 'revocation_endpoint' + /// + [JsonPropertyName(OpenIdProviderMetadataNames.RevocationEndpoint)] +#if NET6_0_OR_GREATER + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] +#endif + public string RevocationEndpoint { get; set; } + + /// + /// Gets the collection of 'revocation_endpoint_auth_methods_supported'. + /// + [JsonPropertyName(OpenIdProviderMetadataNames.RevocationEndpointAuthMethodsSupported)] + public ICollection RevocationEndpointAuthMethodsSupported => + _revocationEndpointAuthMethodsSupported ?? + Interlocked.CompareExchange(ref _revocationEndpointAuthMethodsSupported, new Collection(), null) ?? + _revocationEndpointAuthMethodsSupported; + + /// + /// Gets the collection of 'revocation_endpoint_auth_signing_alg_values_supported'. + /// + [JsonPropertyName(OpenIdProviderMetadataNames.RevocationEndpointAuthSigningAlgValuesSupported)] + public ICollection RevocationEndpointAuthSigningAlgValuesSupported => + _revocationEndpointAuthSigningAlgValuesSupported ?? + Interlocked.CompareExchange(ref _revocationEndpointAuthSigningAlgValuesSupported, new Collection(), null) ?? + _revocationEndpointAuthSigningAlgValuesSupported; + /// /// Gets or sets the 'service_documentation' /// @@ -688,6 +736,17 @@ public bool ShouldSerializeClaimTypesSupported() return ClaimTypesSupported.Count > 0; } + /// + /// Gets a bool that determines if the 'code_challenge_methods_supported' (CodeChallengeMethodsSupported) property should be serialized. + /// This is used by Json.NET in order to conditionally serialize properties. + /// + /// true if 'code_challenge_methods_supported' (CodeChallengeMethodsSupported) is not empty; otherwise, false. + [EditorBrowsable(EditorBrowsableState.Never)] + public bool ShouldSerializeCodeChallengeMethodsSupported() + { + return CodeChallengeMethodsSupported.Count > 0; + } + /// /// Gets a bool that determines if the 'display_values_supported' (DisplayValuesSupported) property should be serialized. /// This is used by Json.NET in order to conditionally serialize properties. @@ -842,6 +901,28 @@ public bool ShouldSerializeResponseTypesSupported() return ResponseTypesSupported.Count > 0; } + /// + /// Gets a bool that determines if the 'revocation_endpoint_auth_methods_supported' (RevocationEndpointAuthMethodsSupported) property should be serialized. + /// This is used by Json.NET in order to conditionally serialize properties. + /// + /// true if 'revocation_endpoint_auth_methods_supported' (RevocationEndpointAuthMethodsSupported) is not empty; otherwise, false. + [EditorBrowsable(EditorBrowsableState.Never)] + public bool ShouldSerializeRevocationEndpointAuthMethodsSupported() + { + return RevocationEndpointAuthMethodsSupported.Count > 0; + } + + /// + /// Gets a bool that determines if the 'revocation_endpoint_auth_signing_alg_values_supported' (RevocationEndpointAuthSigningAlgValuesSupported) property should be serialized. + /// This is used by Json.NET in order to conditionally serialize properties. + /// + /// true if 'revocation_endpoint_auth_signing_alg_values_supported' (RevocationEndpointAuthSigningAlgValuesSupported) is not empty; otherwise, false. + [EditorBrowsable(EditorBrowsableState.Never)] + public bool ShouldSerializeRevocationEndpointAuthSigningAlgValuesSupported() + { + return RevocationEndpointAuthSigningAlgValuesSupported.Count > 0; + } + /// /// Gets a bool that determines if the 'SigningKeys' property should be serialized. /// This is used by Json.NET in order to conditionally serialize properties. diff --git a/src/Microsoft.IdentityModel.Protocols.OpenIdConnect/Json/OpenIdConnectConfigurationSerializer.cs b/src/Microsoft.IdentityModel.Protocols.OpenIdConnect/Json/OpenIdConnectConfigurationSerializer.cs index fc877effad..73ace9f25f 100644 --- a/src/Microsoft.IdentityModel.Protocols.OpenIdConnect/Json/OpenIdConnectConfigurationSerializer.cs +++ b/src/Microsoft.IdentityModel.Protocols.OpenIdConnect/Json/OpenIdConnectConfigurationSerializer.cs @@ -40,7 +40,9 @@ internal static class OpenIdConnectConfigurationSerializer "CLAIMS_PARAMETER_SUPPORTED", "CLAIMS_SUPPORTED", "CLAIM_TYPES_SUPPORTED", + "CODE_CHALLENGE_METHODS_SUPPORTED", ".WELL-KNOWN/OPENID-CONFIGURATION", + "DEVICE_AUTHORIZATION_ENDPOINT", "DISPLAY_VALUES_SUPPORTED", "DPOP_SIGNING_ALG_VALUES_SUPPORTED", "END_SESSION_ENDPOINT", @@ -71,6 +73,9 @@ internal static class OpenIdConnectConfigurationSerializer "REQUIRE_REQUEST_URI_REGISTRATION", "RESPONSE_MODES_SUPPORTED", "RESPONSE_TYPES_SUPPORTED", + "REVOCATION_ENDPOINT", + "REVOCATION_ENDPOINT_AUTH_METHODS_SUPPORTED", + "REVOCATION_ENDPOINT_AUTH_SIGNING_ALG_VALUES_SUPPORTED", "SERVICE_DOCUMENTATION", "SCOPES_SUPPORTED", "SUBJECT_TYPES_SUPPORTED", @@ -97,7 +102,7 @@ public static OpenIdConnectConfiguration Read(string json, OpenIdConnectConfigur { return Read(ref reader, config); } - catch(JsonException ex) + catch (JsonException ex) { if (ex.GetType() == typeof(JsonException)) throw; @@ -131,7 +136,7 @@ public static OpenIdConnectConfiguration Read(ref Utf8JsonReader reader, OpenIdC LogHelper.MarkAsNonPII(reader.CurrentDepth), LogHelper.MarkAsNonPII(reader.BytesConsumed)))); - while(true) + while (true) { #region Check property name using ValueTextEquals // https://datatracker.ietf.org/doc/html/rfc7517#section-4, does not require that we reject JSON with duplicate member names. @@ -174,6 +179,12 @@ public static OpenIdConnectConfiguration Read(ref Utf8JsonReader reader, OpenIdC else if (reader.ValueTextEquals(Utf8Bytes.ClaimTypesSupported)) JsonPrimitives.ReadStrings(ref reader, config.ClaimTypesSupported, MetadataName.ClaimTypesSupported, ClassName, true); + else if (reader.ValueTextEquals(Utf8Bytes.CodeChallengeMethodsSupported)) + JsonPrimitives.ReadStrings(ref reader, config.CodeChallengeMethodsSupported, MetadataName.CodeChallengeMethodsSupported, ClassName, true); + + else if (reader.ValueTextEquals(Utf8Bytes.DeviceAuthorizationEndpoint)) + config.DeviceAuthorizationEndpoint = JsonPrimitives.ReadString(ref reader, MetadataName.DeviceAuthorizationEndpoint, ClassName, true); + else if (reader.ValueTextEquals(Utf8Bytes.DisplayValuesSupported)) JsonPrimitives.ReadStrings(ref reader, config.DisplayValuesSupported, MetadataName.DisplayValuesSupported, ClassName, true); @@ -277,14 +288,20 @@ public static OpenIdConnectConfiguration Read(ref Utf8JsonReader reader, OpenIdC else if (reader.ValueTextEquals(Utf8Bytes.ResponseTypesSupported)) JsonPrimitives.ReadStrings(ref reader, config.ResponseTypesSupported, MetadataName.ResponseTypesSupported, ClassName, true); - else if (reader.ValueTextEquals(Utf8Bytes.ScopesSupported)) - JsonPrimitives.ReadStrings(ref reader, config.ScopesSupported, MetadataName.ScopesSupported, ClassName, true); + else if (reader.ValueTextEquals(Utf8Bytes.RevocationEndpoint)) + config.RevocationEndpoint = JsonPrimitives.ReadString(ref reader, MetadataName.RevocationEndpoint, ClassName, true); + + else if (reader.ValueTextEquals(Utf8Bytes.RevocationEndpointAuthMethodsSupported)) + JsonPrimitives.ReadStrings(ref reader, config.RevocationEndpointAuthMethodsSupported, MetadataName.RevocationEndpointAuthMethodsSupported, ClassName, true); + + else if (reader.ValueTextEquals(Utf8Bytes.RevocationEndpointAuthSigningAlgValuesSupported)) + JsonPrimitives.ReadStrings(ref reader, config.RevocationEndpointAuthSigningAlgValuesSupported, MetadataName.RevocationEndpointAuthSigningAlgValuesSupported, ClassName, true); else if (reader.ValueTextEquals(Utf8Bytes.ServiceDocumentation)) - config.ServiceDocumentation = JsonPrimitives.ReadString(ref reader, MetadataName.ScopesSupported, ClassName, true); + config.ServiceDocumentation = JsonPrimitives.ReadString(ref reader, MetadataName.ServiceDocumentation, ClassName, true); - else if (reader.ValueTextEquals(Utf8Bytes.SubjectTypesSupported)) - JsonPrimitives.ReadStrings(ref reader, config.SubjectTypesSupported, MetadataName.SubjectTypesSupported, ClassName, true); + else if (reader.ValueTextEquals(Utf8Bytes.ScopesSupported)) + JsonPrimitives.ReadStrings(ref reader, config.ScopesSupported, MetadataName.ScopesSupported, ClassName, true); else if (reader.ValueTextEquals(Utf8Bytes.SubjectTypesSupported)) JsonPrimitives.ReadStrings(ref reader, config.SubjectTypesSupported, MetadataName.SubjectTypesSupported, ClassName, true); @@ -366,6 +383,12 @@ public static OpenIdConnectConfiguration Read(ref Utf8JsonReader reader, OpenIdC else if (propertyName.Equals(MetadataName.ClaimTypesSupported, StringComparison.OrdinalIgnoreCase)) JsonPrimitives.ReadStrings(ref reader, config.ClaimTypesSupported, propertyName, ClassName); + else if (propertyName.Equals(MetadataName.CodeChallengeMethodsSupported, StringComparison.OrdinalIgnoreCase)) + JsonPrimitives.ReadStrings(ref reader, config.CodeChallengeMethodsSupported, propertyName, ClassName); + + else if (propertyName.Equals(MetadataName.DeviceAuthorizationEndpoint, StringComparison.OrdinalIgnoreCase)) + config.DeviceAuthorizationEndpoint = JsonPrimitives.ReadString(ref reader, propertyName, ClassName); + else if (propertyName.Equals(MetadataName.DisplayValuesSupported, StringComparison.OrdinalIgnoreCase)) JsonPrimitives.ReadStrings(ref reader, config.DisplayValuesSupported, propertyName, ClassName); @@ -407,7 +430,7 @@ public static OpenIdConnectConfiguration Read(ref Utf8JsonReader reader, OpenIdC else if (propertyName.Equals(MetadataName.IdTokenEncryptionEncValuesSupported, StringComparison.OrdinalIgnoreCase)) JsonPrimitives.ReadStrings(ref reader, config.IdTokenEncryptionEncValuesSupported, propertyName, ClassName); - else if (propertyName.Equals(MetadataName.IdTokenSigningAlgValuesSupported , StringComparison.OrdinalIgnoreCase)) + else if (propertyName.Equals(MetadataName.IdTokenSigningAlgValuesSupported, StringComparison.OrdinalIgnoreCase)) JsonPrimitives.ReadStrings(ref reader, config.IdTokenSigningAlgValuesSupported, propertyName, ClassName); else if (propertyName.Equals(MetadataName.IntrospectionEndpoint, StringComparison.OrdinalIgnoreCase)) @@ -470,6 +493,15 @@ public static OpenIdConnectConfiguration Read(ref Utf8JsonReader reader, OpenIdC else if (propertyName.Equals(MetadataName.ResponseTypesSupported, StringComparison.OrdinalIgnoreCase)) JsonPrimitives.ReadStrings(ref reader, config.ResponseTypesSupported, propertyName, ClassName); + else if (propertyName.Equals(MetadataName.RevocationEndpoint, StringComparison.OrdinalIgnoreCase)) + config.RevocationEndpoint = JsonPrimitives.ReadString(ref reader, propertyName, ClassName); + + else if (propertyName.Equals(MetadataName.RevocationEndpointAuthMethodsSupported, StringComparison.OrdinalIgnoreCase)) + JsonPrimitives.ReadStrings(ref reader, config.RevocationEndpointAuthMethodsSupported, propertyName, ClassName); + + else if (propertyName.Equals(MetadataName.RevocationEndpointAuthSigningAlgValuesSupported, StringComparison.OrdinalIgnoreCase)) + JsonPrimitives.ReadStrings(ref reader, config.RevocationEndpointAuthSigningAlgValuesSupported, propertyName, ClassName); + else if (propertyName.Equals(MetadataName.ScopesSupported, StringComparison.OrdinalIgnoreCase)) JsonPrimitives.ReadStrings(ref reader, config.ScopesSupported, propertyName, ClassName); @@ -577,6 +609,12 @@ public static void Write(ref Utf8JsonWriter writer, OpenIdConnectConfiguration c if (config.ClaimTypesSupported.Count > 0) JsonPrimitives.WriteStrings(ref writer, Utf8Bytes.ClaimTypesSupported, config.ClaimTypesSupported); + if (config.CodeChallengeMethodsSupported.Count > 0) + JsonPrimitives.WriteStrings(ref writer, Utf8Bytes.CodeChallengeMethodsSupported, config.CodeChallengeMethodsSupported); + + if (!string.IsNullOrEmpty(config.DeviceAuthorizationEndpoint)) + writer.WriteString(Utf8Bytes.DeviceAuthorizationEndpoint, config.DeviceAuthorizationEndpoint); + if (config.DisplayValuesSupported.Count > 0) JsonPrimitives.WriteStrings(ref writer, Utf8Bytes.DisplayValuesSupported, config.DisplayValuesSupported); @@ -638,7 +676,7 @@ public static void Write(ref Utf8JsonWriter writer, OpenIdConnectConfiguration c writer.WriteString(Utf8Bytes.PushedAuthorizationRequestEndpoint, config.PushedAuthorizationRequestEndpoint); if (!string.IsNullOrEmpty(config.RegistrationEndpoint)) - writer.WriteString(Utf8Bytes.RegistrationEndpoint, config.RegistrationEndpoint); + writer.WriteString(Utf8Bytes.RegistrationEndpoint, config.RegistrationEndpoint); if (config.RequestObjectEncryptionAlgValuesSupported.Count > 0) JsonPrimitives.WriteStrings(ref writer, Utf8Bytes.RequestObjectEncryptionAlgValuesSupported, config.RequestObjectEncryptionAlgValuesSupported); @@ -670,6 +708,15 @@ public static void Write(ref Utf8JsonWriter writer, OpenIdConnectConfiguration c if (config.ScopesSupported.Count > 0) JsonPrimitives.WriteStrings(ref writer, Utf8Bytes.ScopesSupported, config.ScopesSupported); + if (!string.IsNullOrEmpty(config.RevocationEndpoint)) + writer.WriteString(Utf8Bytes.RevocationEndpoint, config.RevocationEndpoint); + + if (config.RevocationEndpointAuthMethodsSupported.Count > 0) + JsonPrimitives.WriteStrings(ref writer, Utf8Bytes.RevocationEndpointAuthMethodsSupported, config.RevocationEndpointAuthMethodsSupported); + + if (config.RevocationEndpointAuthSigningAlgValuesSupported.Count > 0) + JsonPrimitives.WriteStrings(ref writer, Utf8Bytes.RevocationEndpointAuthSigningAlgValuesSupported, config.RevocationEndpointAuthSigningAlgValuesSupported); + if (!string.IsNullOrEmpty(config.ServiceDocumentation)) writer.WriteString(Utf8Bytes.ServiceDocumentation, config.ServiceDocumentation); @@ -708,4 +755,3 @@ public static void Write(ref Utf8JsonWriter writer, OpenIdConnectConfiguration c #endregion } } - diff --git a/src/Microsoft.IdentityModel.Protocols.OpenIdConnect/OpenIdProviderMetadataNames.cs b/src/Microsoft.IdentityModel.Protocols.OpenIdConnect/OpenIdProviderMetadataNames.cs index 554f81a0f7..62f15637c6 100644 --- a/src/Microsoft.IdentityModel.Protocols.OpenIdConnect/OpenIdProviderMetadataNames.cs +++ b/src/Microsoft.IdentityModel.Protocols.OpenIdConnect/OpenIdProviderMetadataNames.cs @@ -24,6 +24,8 @@ public static class OpenIdProviderMetadataNames public const string ClaimsParameterSupported = "claims_parameter_supported"; public const string ClaimsSupported = "claims_supported"; public const string ClaimTypesSupported = "claim_types_supported"; + public const string CodeChallengeMethodsSupported = "code_challenge_methods_supported"; + public const string DeviceAuthorizationEndpoint = "device_authorization_endpoint"; public const string Discovery = ".well-known/openid-configuration"; public const string DisplayValuesSupported = "display_values_supported"; public const string DPoPSigningAlgValuesSupported = "dpop_signing_alg_values_supported"; @@ -56,6 +58,9 @@ public static class OpenIdProviderMetadataNames public const string RequireRequestUriRegistration = "require_request_uri_registration"; public const string ResponseModesSupported = "response_modes_supported"; public const string ResponseTypesSupported = "response_types_supported"; + public const string RevocationEndpoint = "revocation_endpoint"; + public const string RevocationEndpointAuthMethodsSupported = "revocation_endpoint_auth_methods_supported"; + public const string RevocationEndpointAuthSigningAlgValuesSupported = "revocation_endpoint_auth_signing_alg_values_supported"; public const string ServiceDocumentation = "service_documentation"; public const string ScopesSupported = "scopes_supported"; public const string SubjectTypesSupported = "subject_types_supported"; @@ -89,6 +94,8 @@ internal static class OpenIdProviderMetadataUtf8Bytes public static ReadOnlySpan ClaimsParameterSupported => "claims_parameter_supported"u8; public static ReadOnlySpan ClaimsSupported => "claims_supported"u8; public static ReadOnlySpan ClaimTypesSupported => "claim_types_supported"u8; + public static ReadOnlySpan CodeChallengeMethodsSupported => "code_challenge_methods_supported"u8; + public static ReadOnlySpan DeviceAuthorizationEndpoint => "device_authorization_endpoint"u8; public static ReadOnlySpan Discovery => ".well-known/openid-configuration"u8; public static ReadOnlySpan DisplayValuesSupported => "display_values_supported"u8; public static ReadOnlySpan DPoPSigningAlgValuesSupported => "dpop_signing_alg_values_supported"u8; @@ -121,6 +128,9 @@ internal static class OpenIdProviderMetadataUtf8Bytes public static ReadOnlySpan RequireRequestUriRegistration => "require_request_uri_registration"u8; public static ReadOnlySpan ResponseModesSupported => "response_modes_supported"u8; public static ReadOnlySpan ResponseTypesSupported => "response_types_supported"u8; + public static ReadOnlySpan RevocationEndpoint => "revocation_endpoint"u8; + public static ReadOnlySpan RevocationEndpointAuthMethodsSupported => "revocation_endpoint_auth_methods_supported"u8; + public static ReadOnlySpan RevocationEndpointAuthSigningAlgValuesSupported => "revocation_endpoint_auth_signing_alg_values_supported"u8; public static ReadOnlySpan ServiceDocumentation => "service_documentation"u8; public static ReadOnlySpan ScopesSupported => "scopes_supported"u8; public static ReadOnlySpan SubjectTypesSupported => "subject_types_supported"u8; diff --git a/test/Microsoft.IdentityModel.Protocols.OpenIdConnect.Tests/OpenIdConfigData.cs b/test/Microsoft.IdentityModel.Protocols.OpenIdConnect.Tests/OpenIdConfigData.cs index 56495e2331..1f60d43365 100644 --- a/test/Microsoft.IdentityModel.Protocols.OpenIdConnect.Tests/OpenIdConfigData.cs +++ b/test/Microsoft.IdentityModel.Protocols.OpenIdConnect.Tests/OpenIdConfigData.cs @@ -42,123 +42,128 @@ public static OpenIdConnectConfiguration FullyPopulatedWithKeys public static string HttpsBadUri = "https://_____NoSuchfile____"; #region Configuration Strings - public static string OpenIdConnectMetadataPingString = @"{""authorization_endpoint"":""https:\/\/connect-interop.pinglabs.org:9031\/as\/authorization.oauth2"", - ""issuer"":""https:\/\/connect-interop.pinglabs.org:9031"", - ""id_token_signing_alg_values_supported"":[""none"",""HS256"",""HS384"",""HS512"",""RS256"",""RS384"",""RS512"",""ES256"",""ES384"",""ES512""], - ""claim_types_supported"":[""normal""], - ""claims_parameter_supported"":false, - ""ping_end_session_endpoint"":""https:\/\/connect-interop.pinglabs.org:9031\/idp\/startSLO.ping"", - ""ping_revoked_sris_endpoint"":""https:\/\/connect-interop.pinglabs.org:9031\/pf-ws\/rest\/sessionMgmt\/revokedSris"", - ""request_parameter_supported"":false, - ""request_uri_parameter_supported"":false, - ""response_modes_supported"":[""fragment"",""query"",""form_post""], - ""response_types_supported"":[""code"",""token"",""id_token"",""code token"",""code id_token"",""token id_token"",""code token id_token""], - ""revocation_endpoint"":""https:\/\/connect-interop.pinglabs.org:9031\/as\/revoke_token.oauth2"", - ""scopes_supported"":[""phone"",""address"",""email"",""openid"",""profile""], - ""subject_types_supported"":[""public""], - ""token_endpoint"":""https:\/\/connect-interop.pinglabs.org:9031\/as\/token.oauth2"", - ""token_endpoint_auth_methods_supported"":[""client_secret_basic"",""client_secret_post""], - ""userinfo_endpoint"":""https:\/\/connect-interop.pinglabs.org:9031\/idp\/userinfo.openid"", - ""version"":""3.0""}"; + public static string OpenIdConnectMetadataPingString = @"{""authorization_endpoint"": ""https:\/\/connect-interop.pinglabs.org:9031\/as\/authorization.oauth2"", + ""issuer"": ""https:\/\/connect-interop.pinglabs.org:9031"", + ""id_token_signing_alg_values_supported"": [""none"", ""HS256"", ""HS384"", ""HS512"", ""RS256"", ""RS384"", ""RS512"", ""ES256"", ""ES384"", ""ES512""], + ""claim_types_supported"": [""normal""], + ""claims_parameter_supported"": false, + ""ping_end_session_endpoint"": ""https:\/\/connect-interop.pinglabs.org:9031\/idp\/startSLO.ping"", + ""ping_revoked_sris_endpoint"": ""https:\/\/connect-interop.pinglabs.org:9031\/pf-ws\/rest\/sessionMgmt\/revokedSris"", + ""request_parameter_supported"": false, + ""request_uri_parameter_supported"": false, + ""response_modes_supported"": [""fragment"", ""query"", ""form_post""], + ""response_types_supported"": [""code"", ""token"", ""id_token"", ""code token"", ""code id_token"", ""token id_token"", ""code token id_token""], + ""revocation_endpoint"": ""https:\/\/connect-interop.pinglabs.org:9031\/as\/revoke_token.oauth2"", + ""scopes_supported"": [""phone"", ""address"", ""email"", ""openid"", ""profile""], + ""subject_types_supported"": [""public""], + ""token_endpoint"": ""https:\/\/connect-interop.pinglabs.org:9031\/as\/token.oauth2"", + ""token_endpoint_auth_methods_supported"": [""client_secret_basic"", ""client_secret_post""], + ""userinfo_endpoint"": ""https:\/\/connect-interop.pinglabs.org:9031\/idp\/userinfo.openid"", + ""version"": ""3.0""}"; public static string JsonFile = @"OpenIdConnectMetadata.json"; public static string OpenIdConnectMetadataFileEnd2End = @"OpenIdConnectMetadataEnd2End.json"; public static string OpenIdConnectMetadataFileEnd2EndEC = @"OpenIdConnectMetadataEnd2EndEC.json"; public static string JsonWebKeySetBadUriFile = @"OpenIdConnectMetadataJsonWebKeySetBadUri.json"; public static string JsonAllValues = - @"{ ""acr_values_supported"" : [""acr_value1"", ""acr_value2"", ""acr_value3""], - ""authorization_endpoint"" : ""https://login.windows.net/d062b2b0-9aca-4ff7-b32a-ba47231a4002/oauth2/authorize"", - ""authorization_response_iss_parameter_supported"" : false, - ""backchannel_authentication_endpoint"" : ""https://login.windows.net/d062b2b0-9aca-4ff7-b32a-ba47231a4002/oauth2/bc-authorize"", - ""backchannel_authentication_request_signing_alg_values_supported"" : [""ES384"", ""ES512""], - ""backchannel_token_delivery_modes_supported"" : [""poll"", ""ping""], - ""backchannel_user_code_parameter_supported"" : false, + @"{ ""acr_values_supported"": [""acr_value1"", ""acr_value2"", ""acr_value3""], + ""authorization_endpoint"": ""https://login.windows.net/d062b2b0-9aca-4ff7-b32a-ba47231a4002/oauth2/authorize"", + ""authorization_response_iss_parameter_supported"": false, + ""backchannel_authentication_endpoint"": ""https://login.windows.net/d062b2b0-9aca-4ff7-b32a-ba47231a4002/oauth2/bc-authorize"", + ""backchannel_authentication_request_signing_alg_values_supported"": [""ES384"", ""ES512""], + ""backchannel_token_delivery_modes_supported"": [""poll"", ""ping""], + ""backchannel_user_code_parameter_supported"": false, + ""code_challenge_methods_supported"": [""plain"", ""S256""], + ""device_authorization_endpoint"": ""https://login.windows.net/d062b2b0-9aca-4ff7-b32a-ba47231a4002/oauth2/devicecode"", ""frontchannel_logout_session_supported"": ""true"", ""frontchannel_logout_supported"": ""true"", - ""check_session_iframe"":""https://login.windows.net/d062b2b0-9aca-4ff7-b32a-ba47231a4002/oauth2/checksession"", - ""claims_locales_supported"" : [ ""claim_local1"", ""claim_local2"", ""claim_local3"" ], - ""claims_parameter_supported"" : true, - ""claims_supported"": [ ""sub"", ""iss"", ""aud"", ""exp"", ""iat"", ""auth_time"", ""acr"", ""amr"", ""nonce"", ""email"", ""given_name"", ""family_name"", ""nickname"" ], - ""claim_types_supported"" : [ ""Normal Claims"", ""Aggregated Claims"", ""Distributed Claims"" ], - ""display_values_supported"" : [ ""displayValue1"", ""displayValue2"", ""displayValue3"" ], - ""dpop_signing_alg_values_supported"" : [""ES384"", ""ES512""], - ""end_session_endpoint"" : ""https://login.windows.net/d062b2b0-9aca-4ff7-b32a-ba47231a4002/oauth2/logout"", - ""grant_types_supported"" : [""authorization_code"",""implicit""], - ""http_logout_supported"" : true, - ""id_token_encryption_alg_values_supported"" : [""RSA1_5"", ""A256KW""], - ""id_token_encryption_enc_values_supported"" : [""A128CBC-HS256"",""A256CBC-HS512""], - ""id_token_signing_alg_values_supported"" : [""RS256""], - ""introspection_endpoint"" : ""https://login.windows.net/d062b2b0-9aca-4ff7-b32a-ba47231a4002/oauth2/introspect"", - ""introspection_endpoint_auth_methods_supported"" : [""client_secret_post"",""private_key_jwt""], - ""introspection_endpoint_auth_signing_alg_values_supported"" : [""ES192"", ""ES256""], - ""issuer"" : ""https://sts.windows.net/d062b2b0-9aca-4ff7-b32a-ba47231a4002/"", - ""jwks_uri"" : ""JsonWebKeySet.json"", - ""logout_session_supported"" : true, - ""microsoft_multi_refresh_token"" : true, - ""op_policy_uri"" : ""https://login.windows.net/d062b2b0-9aca-4ff7-b32a-ba47231a4002/op_policy_uri"", - ""op_tos_uri"" : ""https://login.windows.net/d062b2b0-9aca-4ff7-b32a-ba47231a4002/op_tos_uri"", - ""prompt_values_supported"" : [""none"", ""login"", ""consent""], - ""pushed_authorization_request_endpoint"" : ""https://login.windows.net/d062b2b0-9aca-4ff7-b32a-ba47231a4002/oauth2/par"", - ""request_object_encryption_alg_values_supported"" : [""A192KW"", ""A256KW""], - ""request_object_encryption_enc_values_supported"" : [""A192GCM"",""A256GCM""], - ""request_object_signing_alg_values_supported"" : [""PS256"", ""PS512""], - ""request_parameter_supported"" : true, - ""request_uri_parameter_supported"" : true, - ""require_pushed_authorization_requests"" : false, - ""require_request_uri_registration"" : true, - ""response_modes_supported"" : [""query"", ""fragment"",""form_post""], - ""response_types_supported"" : [""code"",""id_token"",""code id_token""], - ""service_documentation"" : ""https://login.windows.net/d062b2b0-9aca-4ff7-b32a-ba47231a4002/service_documentation"", - ""scopes_supported"" : [""openid""], - ""subject_types_supported"" : [""pairwise""], - ""token_endpoint"" : ""https://login.windows.net/d062b2b0-9aca-4ff7-b32a-ba47231a4002/oauth2/token"", - ""token_endpoint_auth_methods_supported"" : [""client_secret_post"",""private_key_jwt""], - ""token_endpoint_auth_signing_alg_values_supported"" : [""ES192"", ""ES256""], - ""ui_locales_supported"" : [""hak-CN"", ""en-us""], - ""userinfo_endpoint"" : ""https://login.microsoftonline.com/add29489-7269-41f4-8841-b63c95564420/openid/userinfo"", - ""userinfo_encryption_alg_values_supported"" : [""ECDH-ES+A128KW"",""ECDH-ES+A192KW""], - ""userinfo_encryption_enc_values_supported"" : [""A256CBC-HS512"", ""A128CBC-HS256""], - ""userinfo_signing_alg_values_supported"" : [""ES384"", ""ES512""] + ""check_session_iframe"": ""https://login.windows.net/d062b2b0-9aca-4ff7-b32a-ba47231a4002/oauth2/checksession"", + ""claims_locales_supported"": [""claim_local1"", ""claim_local2"", ""claim_local3"" ], + ""claims_parameter_supported"": true, + ""claims_supported"": [""sub"", ""iss"", ""aud"", ""exp"", ""iat"", ""auth_time"", ""acr"", ""amr"", ""nonce"", ""email"", ""given_name"", ""family_name"", ""nickname"" ], + ""claim_types_supported"": [""Normal Claims"", ""Aggregated Claims"", ""Distributed Claims"" ], + ""display_values_supported"": [""displayValue1"", ""displayValue2"", ""displayValue3"" ], + ""dpop_signing_alg_values_supported"": [""ES384"", ""ES512""], + ""end_session_endpoint"": ""https://login.windows.net/d062b2b0-9aca-4ff7-b32a-ba47231a4002/oauth2/logout"", + ""grant_types_supported"": [""authorization_code"", ""implicit""], + ""http_logout_supported"": true, + ""id_token_encryption_alg_values_supported"": [""RSA1_5"", ""A256KW""], + ""id_token_encryption_enc_values_supported"": [""A128CBC-HS256"", ""A256CBC-HS512""], + ""id_token_signing_alg_values_supported"": [""RS256""], + ""introspection_endpoint"": ""https://login.windows.net/d062b2b0-9aca-4ff7-b32a-ba47231a4002/oauth2/introspect"", + ""introspection_endpoint_auth_methods_supported"": [""client_secret_post"", ""private_key_jwt""], + ""introspection_endpoint_auth_signing_alg_values_supported"": [""ES192"", ""ES256""], + ""issuer"": ""https://sts.windows.net/d062b2b0-9aca-4ff7-b32a-ba47231a4002/"", + ""jwks_uri"": ""JsonWebKeySet.json"", + ""logout_session_supported"": true, + ""microsoft_multi_refresh_token"": true, + ""op_policy_uri"": ""https://login.windows.net/d062b2b0-9aca-4ff7-b32a-ba47231a4002/op_policy_uri"", + ""op_tos_uri"": ""https://login.windows.net/d062b2b0-9aca-4ff7-b32a-ba47231a4002/op_tos_uri"", + ""prompt_values_supported"": [""none"", ""login"", ""consent""], + ""pushed_authorization_request_endpoint"": ""https://login.windows.net/d062b2b0-9aca-4ff7-b32a-ba47231a4002/oauth2/par"", + ""request_object_encryption_alg_values_supported"": [""A192KW"", ""A256KW""], + ""request_object_encryption_enc_values_supported"": [""A192GCM"", ""A256GCM""], + ""request_object_signing_alg_values_supported"": [""PS256"", ""PS512""], + ""request_parameter_supported"": true, + ""request_uri_parameter_supported"": true, + ""require_pushed_authorization_requests"": false, + ""require_request_uri_registration"": true, + ""response_modes_supported"": [""query"", ""fragment"", ""form_post""], + ""response_types_supported"": [""code"", ""id_token"", ""code id_token""], + ""revocation_endpoint"": ""https://login.windows.net/d062b2b0-9aca-4ff7-b32a-ba47231a4002/oauth2/revocation"", + ""revocation_endpoint_auth_methods_supported"": [""client_secret_post"", ""client_secret_basic""], + ""revocation_endpoint_auth_signing_alg_values_supported"": [""ES192"", ""ES256""], + ""service_documentation"": ""https://login.windows.net/d062b2b0-9aca-4ff7-b32a-ba47231a4002/service_documentation"", + ""scopes_supported"": [""openid""], + ""subject_types_supported"": [""pairwise""], + ""token_endpoint"": ""https://login.windows.net/d062b2b0-9aca-4ff7-b32a-ba47231a4002/oauth2/token"", + ""token_endpoint_auth_methods_supported"": [""client_secret_post"", ""private_key_jwt""], + ""token_endpoint_auth_signing_alg_values_supported"": [""ES192"", ""ES256""], + ""ui_locales_supported"": [""hak-CN"", ""en-us""], + ""userinfo_endpoint"": ""https://login.microsoftonline.com/add29489-7269-41f4-8841-b63c95564420/openid/userinfo"", + ""userinfo_encryption_alg_values_supported"": [""ECDH-ES+A128KW"", ""ECDH-ES+A192KW""], + ""userinfo_encryption_enc_values_supported"": [""A256CBC-HS512"", ""A128CBC-HS256""], + ""userinfo_signing_alg_values_supported"": [""ES384"", ""ES512""] }"; public static string OpenIdConnectMetadataSingleX509DataString = - @"{ ""authorization_endpoint"":""https://login.windows.net/d062b2b0-9aca-4ff7-b32a-ba47231a4002/oauth2/authorize"", - ""check_session_iframe"":""https://login.windows.net/d062b2b0-9aca-4ff7-b32a-ba47231a4002/oauth2/checksession"", - ""end_session_endpoint"":""https://login.windows.net/d062b2b0-9aca-4ff7-b32a-ba47231a4002/oauth2/logout"", - ""id_token_signing_alg_values_supported"":[""RS256""], - ""issuer"":""https://sts.windows.net/d062b2b0-9aca-4ff7-b32a-ba47231a4002/"", - ""jwks_uri"":""JsonWebKeySetSingleX509Data.json"", + @"{ ""authorization_endpoint"": ""https://login.windows.net/d062b2b0-9aca-4ff7-b32a-ba47231a4002/oauth2/authorize"", + ""check_session_iframe"": ""https://login.windows.net/d062b2b0-9aca-4ff7-b32a-ba47231a4002/oauth2/checksession"", + ""end_session_endpoint"": ""https://login.windows.net/d062b2b0-9aca-4ff7-b32a-ba47231a4002/oauth2/logout"", + ""id_token_signing_alg_values_supported"": [""RS256""], + ""issuer"": ""https://sts.windows.net/d062b2b0-9aca-4ff7-b32a-ba47231a4002/"", + ""jwks_uri"": ""JsonWebKeySetSingleX509Data.json"", ""microsoft_multi_refresh_token"":true, - ""response_types_supported"":[""code"",""id_token"",""code id_token""], - ""response_modes_supported"":[""query"",""fragment"",""form_post""], - ""scopes_supported"":[""openid""], - ""subject_types_supported"":[""pairwise""], - ""token_endpoint"":""https://login.windows.net/d062b2b0-9aca-4ff7-b32a-ba47231a4002/oauth2/token"", - ""token_endpoint_auth_methods_supported"":[""client_secret_post"",""private_key_jwt""] + ""response_types_supported"": [""code"", ""id_token"", ""code id_token""], + ""response_modes_supported"": [""query"", ""fragment"", ""form_post""], + ""scopes_supported"": [""openid""], + ""subject_types_supported"": [""pairwise""], + ""token_endpoint"": ""https://login.windows.net/d062b2b0-9aca-4ff7-b32a-ba47231a4002/oauth2/token"", + ""token_endpoint_auth_methods_supported"": [""client_secret_post"", ""private_key_jwt""] }"; public static string JsonWithSigningKeys = - @"{ ""authorization_endpoint"":""https://login.windows.net/d062b2b0-9aca-4ff7-b32a-ba47231a4002/oauth2/authorize"", - ""check_session_iframe"":""https://login.windows.net/d062b2b0-9aca-4ff7-b32a-ba47231a4002/oauth2/checksession"", - ""end_session_endpoint"":""https://login.windows.net/d062b2b0-9aca-4ff7-b32a-ba47231a4002/oauth2/logout"", - ""id_token_signing_alg_values_supported"":[""RS256""], - ""issuer"":""https://sts.windows.net/d062b2b0-9aca-4ff7-b32a-ba47231a4002/"", - ""jwks_uri"":""JsonWebKeySetSingleX509Data.json"", + @"{ ""authorization_endpoint"": ""https://login.windows.net/d062b2b0-9aca-4ff7-b32a-ba47231a4002/oauth2/authorize"", + ""check_session_iframe"": ""https://login.windows.net/d062b2b0-9aca-4ff7-b32a-ba47231a4002/oauth2/checksession"", + ""end_session_endpoint"": ""https://login.windows.net/d062b2b0-9aca-4ff7-b32a-ba47231a4002/oauth2/logout"", + ""id_token_signing_alg_values_supported"": [""RS256""], + ""issuer"": ""https://sts.windows.net/d062b2b0-9aca-4ff7-b32a-ba47231a4002/"", + ""jwks_uri"": ""JsonWebKeySetSingleX509Data.json"", ""microsoft_multi_refresh_token"":true, - ""response_types_supported"":[""code"",""id_token"",""code id_token""], - ""response_modes_supported"":[""query"",""fragment"",""form_post""], - ""scopes_supported"":[""openid""], - ""subject_types_supported"":[""pairwise""], - ""token_endpoint"":""https://login.windows.net/d062b2b0-9aca-4ff7-b32a-ba47231a4002/oauth2/token"", - ""token_endpoint_auth_methods_supported"":[""client_secret_post"",""private_key_jwt""], - ""SigningKeys"":[""key1"",""key2""] + ""response_types_supported"": [""code"", ""id_token"", ""code id_token""], + ""response_modes_supported"": [""query"", ""fragment"", ""form_post""], + ""scopes_supported"": [""openid""], + ""subject_types_supported"": [""pairwise""], + ""token_endpoint"": ""https://login.windows.net/d062b2b0-9aca-4ff7-b32a-ba47231a4002/oauth2/token"", + ""token_endpoint_auth_methods_supported"": [""client_secret_post"", ""private_key_jwt""], + ""SigningKeys"": [""key1"", ""key2""] }"; - public static string OpenIdConnectMetadataBadX509DataString = @"{""jwks_uri"":""JsonWebKeySetBadX509Data.json""}"; - public static string OpenIdConnectMetadataBadBase64DataString = @"{""jwks_uri"":""JsonWebKeySetBadBase64Data.json""}"; - public static string OpenIdConnectMetadataBadUriKeysString = @"{""jwks_uri"":""___NoSuchFile___""}"; + public static string OpenIdConnectMetadataBadX509DataString = @"{""jwks_uri"": ""JsonWebKeySetBadX509Data.json""}"; + public static string OpenIdConnectMetadataBadBase64DataString = @"{""jwks_uri"": ""JsonWebKeySetBadBase64Data.json""}"; + public static string OpenIdConnectMetadataBadUriKeysString = @"{""jwks_uri"": ""___NoSuchFile___""}"; public static string OpenIdConnectMetadataBadFormatString = @"{""issuer""::""https://sts.windows.net/d062b2b0-9aca-4ff7-b32a-ba47231a4002/""}"; - public static string OpenIdConnectMetadataPingLabsJWKSString = @"{""jwks_uri"":""PingLabsJWKS.json""}"; + public static string OpenIdConnectMetadataPingLabsJWKSString = @"{""jwks_uri"": ""PingLabsJWKS.json""}"; public static string OpenIdConnectMetatadataBadJson = @"{..."; #endregion @@ -191,14 +196,14 @@ public static OpenIdConnectConfiguration FullyPopulatedWithKeys "userinfo_endpoint": "https://openidconnect.googleapis.com/v1/userinfo", "revocation_endpoint": "https://oauth2.googleapis.com/revoke", "jwks_uri": "https://www.googleapis.com/oauth2/v3/certs", - "response_types_supported": ["code","id_token","code id_token"], + "response_types_supported": ["code", "id_token", "code id_token"], "subject_types_supported": ["public"], "id_token_signing_alg_values_supported": ["RS256"], - "scopes_supported": ["openid","email","profile"], - "token_endpoint_auth_methods_supported": ["client_secret_post","client_secret_basic"], - "claims_supported": ["aud","email","email_verified","exp","family_name","given_name","iat","iss","locale","name","picture","sub"], - "code_challenge_methods_supported": ["plain","S256"], - "grant_types_supported": ["authorization_code","refresh_token","urn:ietf:params:oauth:grant-type:device_code","urn:ietf:params:oauth:grant-type:jwt-bearer"] + "scopes_supported": ["openid", "email", "profile"], + "token_endpoint_auth_methods_supported": ["client_secret_post", "client_secret_basic"], + "claims_supported": ["aud", "email", "email_verified", "exp", "family_name", "given_name", "iat", "iss", "locale", "name", "picture", "sub"], + "code_challenge_methods_supported": ["plain", "S256"], + "grant_types_supported": ["authorization_code", "refresh_token", "urn:ietf:params:oauth:grant-type:device_code", "urn:ietf:params:oauth:grant-type:jwt-bearer"] } """; public static OpenIdConnectConfiguration AccountsGoogleComConfig @@ -209,12 +214,15 @@ public static OpenIdConnectConfiguration AccountsGoogleComConfig OpenIdConnectConfiguration config = new OpenIdConnectConfiguration { AuthorizationEndpoint = "https://accounts.google.com/o/oauth2/v2/auth", + DeviceAuthorizationEndpoint = "https://oauth2.googleapis.com/device/code", Issuer = "https://accounts.google.com", JwksUri = "https://www.googleapis.com/oauth2/v3/certs", + RevocationEndpoint = "https://oauth2.googleapis.com/revoke", TokenEndpoint = "https://oauth2.googleapis.com/token", UserInfoEndpoint = "https://openidconnect.googleapis.com/v1/userinfo", }; + AddToCollection(config.CodeChallengeMethodsSupported, "plain", "S256"); AddToCollection(config.ResponseTypesSupported, "code", "id_token", "code id_token"); config.SubjectTypesSupported.Add("public"); config.IdTokenSigningAlgValuesSupported.Add("RS256"); @@ -223,27 +231,22 @@ public static OpenIdConnectConfiguration AccountsGoogleComConfig AddToCollection(config.ClaimsSupported, "aud", "email", "email_verified", "exp", "family_name", "given_name", "iat", "iss", "locale", "name", "picture", "sub"); AddToCollection(config.GrantTypesSupported, "authorization_code", "refresh_token", "urn:ietf:params:oauth:grant-type:device_code", "urn:ietf:params:oauth:grant-type:jwt-bearer"); - // Adjust if Google changes their config or https://github.com/AzureAD/azure-activedirectory-identitymodel-extensions-for-dotnet/issues/2456 is implemented. - config.AdditionalData.Add("device_authorization_endpoint", "https://oauth2.googleapis.com/device/code"); - config.AdditionalData.Add("code_challenge_methods_supported", JsonUtilities.CreateJsonElement(""" ["plain","S256"] """)); - config.AdditionalData.Add("revocation_endpoint", "https://oauth2.googleapis.com/revoke"); - return config; } } #endregion - #region AADCommonV1 2/2/2024 https://login.microsoftonline.com/common/.well-known/openid-configuration + #region AADCommonV1 2/2/2024 https://login.microsoftonline.com/common/.well-known/openid-configuration public static string AADCommonV1Json => """ { "token_endpoint": "https://login.microsoftonline.com/common/oauth2/token", - "token_endpoint_auth_methods_supported": ["client_secret_post","private_key_jwt","client_secret_basic"], + "token_endpoint_auth_methods_supported": ["client_secret_post", "private_key_jwt", "client_secret_basic"], "jwks_uri": "https://login.microsoftonline.com/common/discovery/keys", - "response_modes_supported": ["query","fragment","form_post"], + "response_modes_supported": ["query", "fragment", "form_post"], "subject_types_supported": ["pairwise"], "id_token_signing_alg_values_supported": ["RS256"], - "response_types_supported": ["code","id_token","code id_token","token id_token","token"], + "response_types_supported": ["code", "id_token", "code id_token", "token id_token", "token"], "scopes_supported": ["openid"], "issuer": "https://sts.windows.net/{tenantid}/", "microsoft_multi_refresh_token": true, @@ -252,7 +255,7 @@ public static OpenIdConnectConfiguration AccountsGoogleComConfig "http_logout_supported": true, "frontchannel_logout_supported": true, "end_session_endpoint": "https://login.microsoftonline.com/common/oauth2/logout", - "claims_supported": ["sub","iss","cloud_instance_name","cloud_instance_host_name","cloud_graph_host_name","msgraph_host","aud","exp","iat","auth_time","acr","amr","nonce","email","given_name","family_name","nickname"], + "claims_supported": ["sub", "iss", "cloud_instance_name", "cloud_instance_host_name", "cloud_graph_host_name", "msgraph_host", "aud", "exp", "iat", "auth_time", "acr", "amr", "nonce", "email", "given_name", "family_name", "nickname"], "check_session_iframe": "https://login.microsoftonline.com/common/oauth2/checksession", "userinfo_endpoint": "https://login.microsoftonline.com/common/openid/userinfo", "kerberos_endpoint": "https://login.microsoftonline.com/common/kerberos", @@ -271,6 +274,7 @@ public static OpenIdConnectConfiguration AADCommonV1Config OpenIdConnectConfiguration config = new OpenIdConnectConfiguration { AuthorizationEndpoint = "https://login.microsoftonline.com/common/oauth2/authorize", + DeviceAuthorizationEndpoint = "https://login.microsoftonline.com/common/oauth2/devicecode", CheckSessionIframe = "https://login.microsoftonline.com/common/oauth2/checksession", HttpLogoutSupported = true, Issuer = "https://sts.windows.net/{tenantid}/", @@ -289,7 +293,6 @@ public static OpenIdConnectConfiguration AADCommonV1Config AddToCollection(config.TokenEndpointAuthMethodsSupported, "client_secret_post", "private_key_jwt", "client_secret_basic"); AddToCollection(config.ClaimsSupported, "sub", "iss", "cloud_instance_name", "cloud_instance_host_name", "cloud_graph_host_name", "msgraph_host", "aud", "exp", "iat", "auth_time", "acr", "amr", "nonce", "email", "given_name", "family_name", "nickname"); config.AdditionalData.Add("microsoft_multi_refresh_token", true); - config.AdditionalData.Add("device_authorization_endpoint", "https://login.microsoftonline.com/common/oauth2/devicecode"); config.AdditionalData.Add("kerberos_endpoint", "https://login.microsoftonline.com/common/kerberos"); config.AdditionalData.Add("tenant_region_scope", null); config.AdditionalData.Add("cloud_instance_name", "microsoftonline.com"); @@ -307,13 +310,13 @@ public static OpenIdConnectConfiguration AADCommonV1Config """ { "token_endpoint": "https://login.microsoftonline.com/common/oauth2/v2.0/token", - "token_endpoint_auth_methods_supported": ["client_secret_post","private_key_jwt","client_secret_basic"], + "token_endpoint_auth_methods_supported": ["client_secret_post", "private_key_jwt", "client_secret_basic"], "jwks_uri": "https://login.microsoftonline.com/common/discovery/v2.0/keys", - "response_modes_supported": ["query","fragment","form_post"], + "response_modes_supported": ["query", "fragment", "form_post"], "subject_types_supported": ["pairwise"], "id_token_signing_alg_values_supported": ["RS256"], - "response_types_supported": ["code","id_token","code id_token","id_token token"], - "scopes_supported": ["openid","profile","email","offline_access"], + "response_types_supported": ["code", "id_token", "code id_token", "id_token token"], + "scopes_supported": ["openid", "profile", "email", "offline_access"], "issuer": "https://login.microsoftonline.com/{tenantid}/v2.0", "request_uri_parameter_supported": false, "userinfo_endpoint": "https://graph.microsoft.com/oidc/userinfo", @@ -322,7 +325,7 @@ public static OpenIdConnectConfiguration AADCommonV1Config "http_logout_supported": true, "frontchannel_logout_supported": true, "end_session_endpoint": "https://login.microsoftonline.com/common/oauth2/v2.0/logout", - "claims_supported": ["sub","iss","cloud_instance_name","cloud_instance_host_name","cloud_graph_host_name","msgraph_host","aud","exp","iat","auth_time","acr","nonce","preferred_username","name","tid","ver","at_hash","c_hash","email"], + "claims_supported": ["sub", "iss", "cloud_instance_name", "cloud_instance_host_name", "cloud_graph_host_name", "msgraph_host", "aud", "exp", "iat", "auth_time", "acr", "nonce", "preferred_username", "name", "tid", "ver", "at_hash", "c_hash", "email"], "kerberos_endpoint": "https://login.microsoftonline.com/common/kerberos", "tenant_region_scope": null, "cloud_instance_name": "microsoftonline.com", @@ -339,6 +342,7 @@ public static OpenIdConnectConfiguration AADCommonV2Config OpenIdConnectConfiguration config = new OpenIdConnectConfiguration { AuthorizationEndpoint = "https://login.microsoftonline.com/common/oauth2/v2.0/authorize", + DeviceAuthorizationEndpoint = "https://login.microsoftonline.com/common/oauth2/v2.0/devicecode", HttpLogoutSupported = true, Issuer = "https://login.microsoftonline.com/{tenantid}/v2.0", JwksUri = "https://login.microsoftonline.com/common/discovery/v2.0/keys", @@ -355,7 +359,6 @@ public static OpenIdConnectConfiguration AADCommonV2Config AddToCollection(config.ScopesSupported, "openid", "profile", "email", "offline_access"); AddToCollection(config.TokenEndpointAuthMethodsSupported, "client_secret_post", "private_key_jwt", "client_secret_basic"); AddToCollection(config.ClaimsSupported, "sub", "iss", "cloud_instance_name", "cloud_instance_host_name", "cloud_graph_host_name", "msgraph_host", "aud", "exp", "iat", "auth_time", "acr", "nonce", "preferred_username", "name", "tid", "ver", "at_hash", "c_hash", "email"); - config.AdditionalData.Add("device_authorization_endpoint", "https://login.microsoftonline.com/common/oauth2/v2.0/devicecode"); config.AdditionalData.Add("kerberos_endpoint", "https://login.microsoftonline.com/common/kerberos"); config.AdditionalData.Add("tenant_region_scope", null); config.AdditionalData.Add("cloud_instance_name", "microsoftonline.com"); @@ -617,6 +620,8 @@ private static OpenIdConnectConfiguration SetDefaultConfiguration(OpenIdConnectC config.ClaimsParameterSupported = true; AddToCollection(config.ClaimsSupported, "sub", "iss", "aud", "exp", "iat", "auth_time", "acr", "amr", "nonce", "email", "given_name", "family_name", "nickname"); AddToCollection(config.ClaimTypesSupported, "Normal Claims", "Aggregated Claims", "Distributed Claims"); + AddToCollection(config.CodeChallengeMethodsSupported, "plain", "S256"); + config.DeviceAuthorizationEndpoint = "https://login.windows.net/d062b2b0-9aca-4ff7-b32a-ba47231a4002/oauth2/devicecode"; AddToCollection(config.DisplayValuesSupported, "displayValue1", "displayValue2", "displayValue3"); AddToCollection(config.DPoPSigningAlgValuesSupported, "ES384", "ES512"); config.EndSessionEndpoint = "https://login.windows.net/d062b2b0-9aca-4ff7-b32a-ba47231a4002/oauth2/logout"; @@ -646,8 +651,11 @@ private static OpenIdConnectConfiguration SetDefaultConfiguration(OpenIdConnectC config.RequireRequestUriRegistration = true; AddToCollection(config.ResponseModesSupported, "query", "fragment", "form_post"); AddToCollection(config.ResponseTypesSupported, "code", "id_token", "code id_token"); - config.ScopesSupported.Add("openid"); + config.RevocationEndpoint = "https://login.windows.net/d062b2b0-9aca-4ff7-b32a-ba47231a4002/oauth2/revocation"; + AddToCollection(config.RevocationEndpointAuthMethodsSupported, "client_secret_post", "client_secret_basic"); + AddToCollection(config.RevocationEndpointAuthSigningAlgValuesSupported, "ES192", "ES256"); config.ServiceDocumentation = "https://login.windows.net/d062b2b0-9aca-4ff7-b32a-ba47231a4002/service_documentation"; + config.ScopesSupported.Add("openid"); config.SubjectTypesSupported.Add("pairwise"); config.TokenEndpoint = "https://login.windows.net/d062b2b0-9aca-4ff7-b32a-ba47231a4002/oauth2/token"; AddToCollection(config.TokenEndpointAuthMethodsSupported, "client_secret_post", "private_key_jwt"); diff --git a/test/Microsoft.IdentityModel.Protocols.OpenIdConnect.Tests/OpenIdConnectConfigurationTests.cs b/test/Microsoft.IdentityModel.Protocols.OpenIdConnect.Tests/OpenIdConnectConfigurationTests.cs index 8baedf49a2..9ee0bb7cdb 100644 --- a/test/Microsoft.IdentityModel.Protocols.OpenIdConnect.Tests/OpenIdConnectConfigurationTests.cs +++ b/test/Microsoft.IdentityModel.Protocols.OpenIdConnect.Tests/OpenIdConnectConfigurationTests.cs @@ -83,6 +83,7 @@ public void Defaults() Assert.NotNull(configuration.ClaimsLocalesSupported); Assert.False(configuration.ClaimsParameterSupported); Assert.NotNull(configuration.ClaimTypesSupported); + Assert.NotNull(configuration.CodeChallengeMethodsSupported); Assert.NotNull(configuration.DisplayValuesSupported); Assert.NotNull(configuration.DPoPSigningAlgValuesSupported); Assert.NotNull(configuration.GrantTypesSupported); @@ -102,6 +103,8 @@ public void Defaults() Assert.False(configuration.RequireRequestUriRegistration); Assert.NotNull(configuration.ResponseModesSupported); Assert.NotNull(configuration.ResponseTypesSupported); + Assert.NotNull(configuration.RevocationEndpointAuthMethodsSupported); + Assert.NotNull(configuration.RevocationEndpointAuthSigningAlgValuesSupported); Assert.NotNull(configuration.ScopesSupported); Assert.NotNull(configuration.SigningKeys); Assert.NotNull(configuration.SubjectTypesSupported); @@ -138,8 +141,8 @@ public void GetSets() OpenIdConnectConfiguration configuration = new OpenIdConnectConfiguration(); Type type = typeof(OpenIdConnectConfiguration); PropertyInfo[] properties = type.GetProperties(); - if (properties.Length != 58) - Assert.True(false, "Number of properties has changed from 58 to: " + properties.Length + ", adjust tests"); + if (properties.Length != 63) + Assert.True(false, "Number of properties has changed from 63 to: " + properties.Length + ", adjust tests"); TestUtilities.CallAllPublicInstanceAndStaticPropertyGets(configuration, "OpenIdConnectConfiguration_GetSets"); @@ -154,6 +157,8 @@ public void GetSets() new KeyValuePair>("BackchannelUserCodeParameterSupported", new List{ false, true, true }), new KeyValuePair>("CheckSessionIframe", new List{ (string)null, Guid.NewGuid().ToString(), Guid.NewGuid().ToString() }), new KeyValuePair>("ClaimsParameterSupported", new List{ false, true, false }), + new KeyValuePair>("CodeChallengeMethodsSupported", new List{ false, true, true }), + new KeyValuePair>("DeviceAuthorizationEndpoint", new List{ (string)null, Guid.NewGuid().ToString(), Guid.NewGuid().ToString() }), new KeyValuePair>("EndSessionEndpoint", new List{ (string)null, Guid.NewGuid().ToString(), Guid.NewGuid().ToString() }), new KeyValuePair>("HttpLogoutSupported", new List{ false, true, true }), new KeyValuePair>("IntrospectionEndpoint", new List{ (string)null, Guid.NewGuid().ToString(), Guid.NewGuid().ToString() }), @@ -169,6 +174,9 @@ public void GetSets() new KeyValuePair>("RequestUriParameterSupported", new List{ false, true, true }), new KeyValuePair>("RequirePushedAuthorizationRequests", new List{ false, true, true }), new KeyValuePair>("RequireRequestUriRegistration", new List{ false, true, true }), + new KeyValuePair>("RevocationEndpoint", new List{ (string)null, Guid.NewGuid().ToString(), Guid.NewGuid().ToString() }), + new KeyValuePair>("RevocationEndpointAuthMethodsSupported", new List{ false, true, true }), + new KeyValuePair>("RevocationEndpointAuthSigningAlgValuesSupported", new List{ false, true, true }), new KeyValuePair>("ServiceDocumentation", new List{ (string)null, Guid.NewGuid().ToString(), Guid.NewGuid().ToString() }), new KeyValuePair>("TokenEndpoint", new List{ (string)null, Guid.NewGuid().ToString(), Guid.NewGuid().ToString() }), new KeyValuePair>("UserInfoEndpoint", new List{ (string)null, Guid.NewGuid().ToString(), Guid.NewGuid().ToString() }), @@ -286,6 +294,8 @@ public void NonemptyCollectionSerialization() "claims_supported", "claims_locales_supported", "claim_types_supported", + "code_challenge_methods_supported", + "device_authorization_endpoint", "display_values_supported", "dpop_signing_alg_values_supported", "grant_types_supported", @@ -300,6 +310,9 @@ public void NonemptyCollectionSerialization() "request_object_signing_alg_values_supported", "response_modes_supported", "response_types_supported", + "revocation_endpoint", + "revocation_endpoint_auth_methods_supported", + "revocation_endpoint_auth_signing_alg_values_supported", "scopes_supported", "subject_types_supported", "token_endpoint_auth_methods_supported", diff --git a/test/Microsoft.IdentityModel.Protocols.OpenIdConnect.Tests/OpenIdConnectMetadata.json b/test/Microsoft.IdentityModel.Protocols.OpenIdConnect.Tests/OpenIdConnectMetadata.json index e71ed8aa53..bf10bb1f2c 100644 --- a/test/Microsoft.IdentityModel.Protocols.OpenIdConnect.Tests/OpenIdConnectMetadata.json +++ b/test/Microsoft.IdentityModel.Protocols.OpenIdConnect.Tests/OpenIdConnectMetadata.json @@ -7,22 +7,24 @@ "backchannel_token_delivery_modes_supported": ["poll", "ping"], "backchannel_user_code_parameter_supported": false, "dpop_signing_alg_values_supported": ["ES384", "ES512"], - "frontchannel_logout_session_supported": "true", - "frontchannel_logout_supported": "true", + "frontchannel_logout_session_supported": "true", + "frontchannel_logout_supported": "true", "check_session_iframe": "https://login.windows.net/d062b2b0-9aca-4ff7-b32a-ba47231a4002/oauth2/checksession", "claims_locales_supported": ["claim_local1", "claim_local2", "claim_local3"], "claims_parameter_supported": true, "claims_supported": ["sub", "iss", "aud", "exp", "iat", "auth_time", "acr", "amr", "nonce", "email", "given_name", "family_name", "nickname"], "claim_types_supported": ["Normal Claims", "Aggregated Claims", "Distributed Claims"], + "code_challenge_methods_supported": ["plain", "S256"], + "device_authorization_endpoint": "https://login.windows.net/d062b2b0-9aca-4ff7-b32a-ba47231a4002/oauth2/devicecode", "display_values_supported": ["displayValue1", "displayValue2", "displayValue3"], "end_session_endpoint": "https://login.windows.net/d062b2b0-9aca-4ff7-b32a-ba47231a4002/oauth2/logout", - "grant_types_supported": ["authorization_code","implicit"], + "grant_types_supported": ["authorization_code", "implicit"], "http_logout_supported": true, "id_token_encryption_alg_values_supported": ["RSA1_5", "A256KW"], - "id_token_encryption_enc_values_supported": ["A128CBC-HS256","A256CBC-HS512"], + "id_token_encryption_enc_values_supported": ["A128CBC-HS256", "A256CBC-HS512"], "id_token_signing_alg_values_supported": ["RS256"], "introspection_endpoint": "https://login.windows.net/d062b2b0-9aca-4ff7-b32a-ba47231a4002/oauth2/introspect", - "introspection_endpoint_auth_methods_supported": ["client_secret_post","private_key_jwt"], + "introspection_endpoint_auth_methods_supported": ["client_secret_post", "private_key_jwt"], "introspection_endpoint_auth_signing_alg_values_supported": ["ES192", "ES256"], "issuer": "https://sts.windows.net/d062b2b0-9aca-4ff7-b32a-ba47231a4002/", "jwks_uri": "JsonWebKeySet.json", @@ -33,7 +35,7 @@ "prompt_values_supported": ["none", "login", "consent"], "pushed_authorization_request_endpoint": "https://login.windows.net/d062b2b0-9aca-4ff7-b32a-ba47231a4002/oauth2/par", "request_object_encryption_alg_values_supported": ["A192KW", "A256KW"], - "request_object_encryption_enc_values_supported": ["A192GCM","A256GCM"], + "request_object_encryption_enc_values_supported": ["A192GCM", "A256GCM"], "request_object_signing_alg_values_supported": ["PS256", "PS512"], "request_parameter_supported": true, "request_uri_parameter_supported": true, @@ -41,6 +43,9 @@ "require_request_uri_registration": true, "response_types_supported": ["code", "id_token", "code id_token"], "response_modes_supported": ["query", "fragment", "form_post"], + "revocation_endpoint": "https://login.windows.net/d062b2b0-9aca-4ff7-b32a-ba47231a4002/oauth2/revocation", + "revocation_endpoint_auth_methods_supported": ["client_secret_post", "client_secret_basic"], + "revocation_endpoint_auth_signing_alg_values_supported": ["ES192", "ES256"], "service_documentation": "https://login.windows.net/d062b2b0-9aca-4ff7-b32a-ba47231a4002/service_documentation", "scopes_supported": ["openid"], "subject_types_supported": ["pairwise"], @@ -49,7 +54,7 @@ "token_endpoint_auth_signing_alg_values_supported": ["ES192", "ES256"], "ui_locales_supported": ["hak-CN", "en-us"], "userinfo_endpoint": "https://login.microsoftonline.com/add29489-7269-41f4-8841-b63c95564420/openid/userinfo", - "userinfo_encryption_alg_values_supported": ["ECDH-ES+A128KW","ECDH-ES+A192KW"], + "userinfo_encryption_alg_values_supported": ["ECDH-ES+A128KW", "ECDH-ES+A192KW"], "userinfo_encryption_enc_values_supported": ["A256CBC-HS512", "A128CBC-HS256"], "userinfo_signing_alg_values_supported": ["ES384", "ES512"] -} \ No newline at end of file +} diff --git a/test/Microsoft.IdentityModel.Protocols.OpenIdConnect.Tests/OpenIdConnectSerializationTests.cs b/test/Microsoft.IdentityModel.Protocols.OpenIdConnect.Tests/OpenIdConnectSerializationTests.cs index 9d28137c02..22454614f5 100644 --- a/test/Microsoft.IdentityModel.Protocols.OpenIdConnect.Tests/OpenIdConnectSerializationTests.cs +++ b/test/Microsoft.IdentityModel.Protocols.OpenIdConnect.Tests/OpenIdConnectSerializationTests.cs @@ -57,8 +57,8 @@ public static TheoryData DesrializeTheoryData theoryData.Add(new OpenIdConnectTheoryData("AccountsGoogleCom") { - CompareTo = JsonUtilities.SetAdditionalDataKeysToUpperCase(OpenIdConfigData.AccountsGoogleComConfig), - Json = JsonUtilities.SetAdditionalDataKeysToUpperCase(OpenIdConfigData.AccountsGoogleComJson, OpenIdConfigData.AccountsGoogleComConfig) + CompareTo = OpenIdConfigData.AccountsGoogleComConfig, + Json = OpenIdConfigData.AccountsGoogleComJson }); theoryData.Add(new OpenIdConnectTheoryData("FrontChannelFalse")