Skip to content
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions Directory.Build.props
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<Project>
<PropertyGroup>
<!-- This should be passed from the VSTS build -->
<MicrosoftIdentityAbstractionsVersion Condition="'$(MicrosoftIdentityAbstractionsVersion)' == ''">9.1.0</MicrosoftIdentityAbstractionsVersion>
<MicrosoftIdentityAbstractionsVersion Condition="'$(MicrosoftIdentityAbstractionsVersion)' == ''">9.2.0</MicrosoftIdentityAbstractionsVersion>
<!-- This will generate AssemblyVersion, AssemblyFileVersion and AssemblyInformationVersion -->
<Version>$(MicrosoftIdentityAbstractionsVersion)</Version>
<AssemblyOriginatorKeyFile>$(MSBuildThisFileDirectory)\build\35MSSharedLib1024.snk</AssemblyOriginatorKeyFile>
Expand All @@ -19,7 +19,7 @@
</PropertyGroup>

<PropertyGroup>
<TargetFrameworks>netstandard2.0;netstandard2.1;net462;net8.0</TargetFrameworks>
<TargetFrameworks>netstandard2.0;netstandard2.1;net462;net8.0;net9.0</TargetFrameworks>
<SignAssembly>true</SignAssembly>
<AssemblyOriginatorKeyFile>../../build/MSAL.snk</AssemblyOriginatorKeyFile>
<GenerateDocumentationFile>true</GenerateDocumentationFile>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,196 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.

#if NET8_0_OR_GREATER
using System;
using System.Text.Json;
using System.Text.Json.Serialization;

namespace Microsoft.Identity.Abstractions
{
/// <summary>
/// Custom JSON converter for CredentialDescription to handle proper serialization/deserialization
/// of credential information based on SourceType.
/// </summary>
/// <remarks>BE CAREFUL when you serialize a credential description. The secrets it contains
/// will be serialized too depending on the CredentialSource (ClientSecret, Base64Encoded, and Password)</remarks>
public class CredentialDescriptionJsonConverter : JsonConverter<CredentialDescription>
{
/// <inheritdoc/>
public override CredentialDescription Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
{
if (reader.TokenType != JsonTokenType.StartObject)
{
throw new JsonException("Expected start of object");
}

var credentialDescription = new CredentialDescription();

while (reader.Read())
{
if (reader.TokenType == JsonTokenType.EndObject)
{
return credentialDescription;
}

if (reader.TokenType != JsonTokenType.PropertyName)
{
throw new JsonException("Expected property name");
}

string propertyName = reader.GetString()!;
reader.Read();

switch (propertyName.ToLowerInvariant())
{
case "sourcetype":
string sourceType = reader.GetString()!;
credentialDescription.SourceType = Enum.Parse<CredentialSource>(sourceType);
break;
case "base64encodedvalue":
credentialDescription.Base64EncodedValue = reader.GetString();
break;
case "certificatestorepath":
credentialDescription.CertificateStorePath = reader.GetString();
break;
case "certificatedistinguishedname":
credentialDescription.CertificateDistinguishedName = reader.GetString();
break;
case "certificatethumbprint":
credentialDescription.CertificateThumbprint = reader.GetString();
break;
case "certificatediskpath":
credentialDescription.CertificateDiskPath = reader.GetString();
break;
case "certificatepassword":
credentialDescription.CertificatePassword = reader.GetString();
break;
case "clientsecret":
credentialDescription.ClientSecret = reader.GetString();
break;
case "managedidentityclientid":
credentialDescription.ManagedIdentityClientId = reader.GetString();
break;
case "signedassertionfilediskpath":
credentialDescription.SignedAssertionFileDiskPath = reader.GetString();
break;
case "keyvaulturl":
credentialDescription.KeyVaultUrl = reader.GetString();
break;
case "keyvaultcertificatename":
credentialDescription.KeyVaultCertificateName = reader.GetString();
break;
case "tokenexchangeurl":
credentialDescription.TokenExchangeUrl = reader.GetString();
break;
case "tokenexchangeauthority":
credentialDescription.TokenExchangeAuthority = reader.GetString();
break;
case "skip":
credentialDescription.Skip = reader.GetBoolean();
break;
case "customsignedassertionprovidername":
credentialDescription.CustomSignedAssertionProviderName = reader.GetString();
break;
case "customsignedassertionproviderdata":
credentialDescription.CustomSignedAssertionProviderData =
JsonSerializer.Deserialize<System.Collections.Generic.Dictionary<string, object>>(ref reader, options);
break;
case "decryptkeysauthenticationoptions":
credentialDescription.DecryptKeysAuthenticationOptions =
JsonSerializer.Deserialize<AuthorizationHeaderProviderOptions>(ref reader, options);
break;
}
}

throw new JsonException("Expected end of object");
}

/// <inheritdoc/>
public override void Write(Utf8JsonWriter writer, CredentialDescription value, JsonSerializerOptions options)
{
ArgumentNullException.ThrowIfNull(writer);
ArgumentNullException.ThrowIfNull(value);
writer.WriteStartObject();

writer.WritePropertyName("SourceType");
JsonSerializer.Serialize(writer, Enum.GetName(value.SourceType), options);

switch (value.SourceType)
{
case CredentialSource.Base64Encoded:
if (!string.IsNullOrEmpty(value.Base64EncodedValue))
writer.WriteString("Base64EncodedValue", value.Base64EncodedValue);
break;

case CredentialSource.Path:
if (!string.IsNullOrEmpty(value.CertificateDiskPath))
writer.WriteString("CertificateDiskPath", value.CertificateDiskPath);
if (!string.IsNullOrEmpty(value.CertificatePassword))
writer.WriteString("CertificatePassword", value.CertificatePassword);
break;

case CredentialSource.StoreWithThumbprint:
if (!string.IsNullOrEmpty(value.CertificateStorePath))
writer.WriteString("CertificateStorePath", value.CertificateStorePath);
if (!string.IsNullOrEmpty(value.CertificateThumbprint))
writer.WriteString("CertificateThumbprint", value.CertificateThumbprint);
break;

case CredentialSource.StoreWithDistinguishedName:
if (!string.IsNullOrEmpty(value.CertificateStorePath))
writer.WriteString("CertificateStorePath", value.CertificateStorePath);
if (!string.IsNullOrEmpty(value.CertificateDistinguishedName))
writer.WriteString("CertificateDistinguishedName", value.CertificateDistinguishedName);
break;

case CredentialSource.KeyVault:
if (!string.IsNullOrEmpty(value.KeyVaultUrl))
writer.WriteString("KeyVaultUrl", value.KeyVaultUrl);
if (!string.IsNullOrEmpty(value.KeyVaultCertificateName))
writer.WriteString("KeyVaultCertificateName", value.KeyVaultCertificateName);
break;

case CredentialSource.ClientSecret:
if (!string.IsNullOrEmpty(value.ClientSecret))
writer.WriteString("ClientSecret", value.ClientSecret);
break;

case CredentialSource.SignedAssertionFromManagedIdentity:
if (!string.IsNullOrEmpty(value.ManagedIdentityClientId))
writer.WriteString("ManagedIdentityClientId", value.ManagedIdentityClientId);
if (!string.IsNullOrEmpty(value.TokenExchangeUrl))
writer.WriteString("TokenExchangeUrl", value.TokenExchangeUrl);
if (!string.IsNullOrEmpty(value.TokenExchangeAuthority))
writer.WriteString("TokenExchangeAuthority", value.TokenExchangeAuthority);
break;

case CredentialSource.SignedAssertionFilePath:
if (!string.IsNullOrEmpty(value.SignedAssertionFileDiskPath))
writer.WriteString("SignedAssertionFileDiskPath", value.SignedAssertionFileDiskPath);
break;

case CredentialSource.AutoDecryptKeys:
if (value.DecryptKeysAuthenticationOptions != null)
{
writer.WritePropertyName("DecryptKeysAuthenticationOptions");
JsonSerializer.Serialize(writer, value.DecryptKeysAuthenticationOptions, options);
}
break;

case CredentialSource.CustomSignedAssertion:
if (!string.IsNullOrEmpty(value.CustomSignedAssertionProviderName))
writer.WriteString("CustomSignedAssertionProviderName", value.CustomSignedAssertionProviderName);
if (value.CustomSignedAssertionProviderData != null)
{
writer.WritePropertyName("CustomSignedAssertionProviderData");
JsonSerializer.Serialize(writer, value.CustomSignedAssertionProviderData, options);
}
break;
}

writer.WriteEndObject();
}
}
}
#endif
Original file line number Diff line number Diff line change
Expand Up @@ -39,5 +39,5 @@
<AdditionalFiles Include="PublicAPI/$(TargetFramework)/PublicAPI.Shipped.txt" />
<AdditionalFiles Include="PublicAPI/$(TargetFramework)/PublicAPI.Unshipped.txt" />
</ItemGroup>

</Project>
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
#nullable enable
Microsoft.Identity.Abstractions.CredentialDescriptionJsonConverter
Microsoft.Identity.Abstractions.CredentialDescriptionJsonConverter.CredentialDescriptionJsonConverter() -> void
Microsoft.Identity.Abstractions.IAuthorizationHeaderProvider<TResult>
Microsoft.Identity.Abstractions.IAuthorizationHeaderProvider<TResult>.CreateAuthorizationHeaderAsync(Microsoft.Identity.Abstractions.DownstreamApiOptions! downstreamApiOptions, System.Security.Claims.ClaimsPrincipal? claimsPrincipal = null, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) -> System.Threading.Tasks.Task<TResult>!
Microsoft.Identity.Abstractions.MicrosoftEntraApplicationOptions
Expand All @@ -17,5 +19,7 @@ Microsoft.Identity.Abstractions.MicrosoftEntraApplicationOptions.SendX5C.get ->
Microsoft.Identity.Abstractions.MicrosoftEntraApplicationOptions.SendX5C.set -> void
Microsoft.Identity.Abstractions.MicrosoftEntraApplicationOptions.TenantId.get -> string?
Microsoft.Identity.Abstractions.MicrosoftEntraApplicationOptions.TenantId.set -> void
override Microsoft.Identity.Abstractions.CredentialDescriptionJsonConverter.Read(ref System.Text.Json.Utf8JsonReader reader, System.Type! typeToConvert, System.Text.Json.JsonSerializerOptions! options) -> Microsoft.Identity.Abstractions.CredentialDescription!
override Microsoft.Identity.Abstractions.CredentialDescriptionJsonConverter.Write(System.Text.Json.Utf8JsonWriter! writer, Microsoft.Identity.Abstractions.CredentialDescription! value, System.Text.Json.JsonSerializerOptions! options) -> void
override Microsoft.Identity.Abstractions.MicrosoftEntraApplicationOptions.Authority.get -> string?
override Microsoft.Identity.Abstractions.MicrosoftEntraApplicationOptions.Authority.set -> void
Loading