Skip to content
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
Show all changes
16 commits
Select commit Hold shift + click to select a range
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
1,888 changes: 1,888 additions & 0 deletions dotnet-install.sh

Large diffs are not rendered by default.

121 changes: 104 additions & 17 deletions src/Microsoft.Identity.Web.OidcFIC/OidcIdpSignedAssertionLoader.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,34 +4,119 @@
using System;
using System.Threading.Tasks;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
using Microsoft.Identity.Abstractions;
using Microsoft.Identity.Web;

namespace Microsoft.Identity.Web.OidcFic
{
internal class OidcIdpSignedAssertionLoader : ICustomSignedAssertionProvider
internal partial class OidcIdpSignedAssertionLoader : ICustomSignedAssertionProvider
{
private readonly ILogger<OidcIdpSignedAssertionLoader> _logger;
private readonly IOptionsMonitor<MicrosoftIdentityApplicationOptions> _options;
private readonly IConfiguration _configuration;
private readonly IServiceProvider _serviceProvider;
private readonly ITokenAcquirerFactory _tokenAcquirerFactory;

public OidcIdpSignedAssertionLoader(ILogger<OidcIdpSignedAssertionLoader> logger,
IOptionsMonitor<MicrosoftIdentityApplicationOptions> options,
IConfiguration configuration,
IServiceProvider serviceProvider,
ITokenAcquirerFactory tokenAcquirerFactory)
{
_logger = logger;
_options = options;
_configuration = configuration;
_serviceProvider = serviceProvider;
_tokenAcquirerFactory = tokenAcquirerFactory;
}

public CredentialSource CredentialSource => CredentialSource.CustomSignedAssertion;

public string Name => "OidcIdpSignedAssertion";

internal static class Logger
{
// Event IDs for OidcIdpSignedAssertionLoader
private static readonly EventId ConfigurationNotRegisteredEventId = new EventId(500, "OidcIdpConfigurationNotRegistered");
private static readonly EventId ConfigurationBindingEventId = new EventId(501, "OidcIdpConfigurationBinding");
private static readonly EventId CustomSignedAssertionProviderDataNullEventId = new EventId(502, "OidcIdpCustomSignedAssertionProviderDataNull");
private static readonly EventId ConfigurationSectionNullEventId = new EventId(503, "OidcIdpConfigurationSectionNull");
private static readonly EventId SignedAssertionProviderFailedEventId = new EventId(504, "OidcIdpSignedAssertionProviderFailed");

private static readonly Action<ILogger, string, Exception?> s_configurationNotRegistered =
LoggerMessage.Define<string>(
LogLevel.Error,
ConfigurationNotRegisteredEventId,
"[MsIdWeb] IConfiguration is not registered in the service collection. Please register IConfiguration or see {TroubleshootingLink} for more information.");

private static readonly Action<ILogger, string, Exception?> s_configurationBinding =
LoggerMessage.Define<string>(
LogLevel.Debug,
ConfigurationBindingEventId,
"[MsIdWeb] Binding configuration section '{SectionName}' to MicrosoftIdentityApplicationOptions");

private static readonly Action<ILogger, Exception?> s_customSignedAssertionProviderDataNull =
LoggerMessage.Define(
LogLevel.Error,
CustomSignedAssertionProviderDataNullEventId,
"[MsIdWeb] CustomSignedAssertionProviderData is null");

private static readonly Action<ILogger, Exception?> s_configurationSectionNull =
LoggerMessage.Define(
LogLevel.Error,
ConfigurationSectionNullEventId,
"[MsIdWeb] ConfigurationSection is null");

private static readonly Action<ILogger, string, string, Exception?> s_signedAssertionProviderFailed =
LoggerMessage.Define<string, string>(
LogLevel.Error,
SignedAssertionProviderFailedEventId,
"[MsIdWeb] Failed to get signed assertion from {ProviderName}. Exception occurred: {Message}. Setting skip to true.");

/// <summary>
/// Logger for when IConfiguration is not registered in the service collection.
/// </summary>
/// <param name="logger">ILogger.</param>
/// <param name="troubleshootingLink">Link to troubleshooting documentation.</param>
public static void ConfigurationNotRegistered(
ILogger logger,
string troubleshootingLink) => s_configurationNotRegistered(logger, troubleshootingLink, default!);

/// <summary>
/// Logger for binding configuration section to MicrosoftIdentityApplicationOptions.
/// </summary>
/// <param name="logger">ILogger.</param>
/// <param name="sectionName">Name of the configuration section.</param>
public static void ConfigurationBinding(
ILogger logger,
string sectionName) => s_configurationBinding(logger, sectionName, default!);

/// <summary>
/// Logger for when CustomSignedAssertionProviderData is null.
/// </summary>
/// <param name="logger">ILogger.</param>
public static void CustomSignedAssertionProviderDataNull(
ILogger logger) => s_customSignedAssertionProviderDataNull(logger, default!);

/// <summary>
/// Logger for when ConfigurationSection is null.
/// </summary>
/// <param name="logger">ILogger.</param>
public static void ConfigurationSectionNull(
ILogger logger) => s_configurationSectionNull(logger, default!);

/// <summary>
/// Logger for when signed assertion provider fails.
/// </summary>
/// <param name="logger">ILogger.</param>
/// <param name="providerName">Name of the provider.</param>
/// <param name="message">Exception message.</param>
public static void SignedAssertionProviderFailed(
ILogger logger,
string providerName,
string message) => s_signedAssertionProviderFailed(logger, providerName, message, default!);
}


public async Task LoadIfNeededAsync(CredentialDescription credentialDescription, CredentialSourceLoaderParameters? parameters = null)
{
Expand All @@ -40,28 +125,33 @@ public async Task LoadIfNeededAsync(CredentialDescription credentialDescription,
{
if (credentialDescription.CustomSignedAssertionProviderData == null)
{
if (_logger != null)
{
_logger.LogError(42, "CustomSignedAssertionProviderData is null");
}
Logger.CustomSignedAssertionProviderDataNull(_logger);
throw new InvalidOperationException("CustomSignedAssertionProviderData is null");
}

string? sectionName = credentialDescription.CustomSignedAssertionProviderData["ConfigurationSection"] as string;
if (sectionName == null)
{
if (_logger != null)
{
_logger.LogError(42, "ConfigurationSection is null");
}
Logger.ConfigurationSectionNull(_logger);
throw new InvalidOperationException("ConfigurationSection is null");
}

MicrosoftIdentityApplicationOptions microsoftIdentityApplicationOptions = _options.Get(sectionName);

if (string.IsNullOrEmpty(microsoftIdentityApplicationOptions.Instance) && microsoftIdentityApplicationOptions.Authority == "//v2.0")
{
_configuration.GetSection(sectionName).Bind(microsoftIdentityApplicationOptions);
// Get IConfiguration from service provider just-in-time
IConfiguration? configuration = _serviceProvider.GetService<IConfiguration>();
if (configuration == null)
{
const string troubleshootingLink = "https://aka.ms/ms-id-web/fic-oidc/troubleshoot";
Logger.ConfigurationNotRegistered(_logger, troubleshootingLink);
throw new InvalidOperationException("IConfiguration is not registered in the service collection. " +
"Please register IConfiguration or see https://aka.ms/ms-id-web/fic-oidc/troubleshoot for more information.");
}

Logger.ConfigurationBinding(_logger, sectionName);
configuration.GetSection(sectionName).Bind(microsoftIdentityApplicationOptions);
}

// Special case for Signed assertions with an FmiPath.
Expand All @@ -81,10 +171,7 @@ public async Task LoadIfNeededAsync(CredentialDescription credentialDescription,
}
catch (Exception ex)
{
if (_logger != null)
{
_logger.LogError(42, "Failed to get signed assertion from {ProviderName}. exception occurred: {Message}. Setting skip to true.", credentialDescription.CustomSignedAssertionProviderName, ex.Message);
}
Logger.SignedAssertionProviderFailed(_logger, credentialDescription.CustomSignedAssertionProviderName ?? "Unknown", ex.Message);
credentialDescription.Skip = true;
throw;
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.

using System.Runtime.CompilerServices;

[assembly: InternalsVisibleTo("Microsoft.Identity.Web.Test, PublicKey=00240000048000009400000006020000002400005253413100040000010001002D96616729B54F6D013D71559A017F50AA4861487226C523959D1579B93F3FDF71C08B980FD3130062B03D3DE115C4B84E7AC46AEF5E192A40E7457D5F3A08F66CEAB71143807F2C3CB0DA5E23B38F0559769978406F6E5D30CEADD7985FC73A5A609A8B74A1DF0A29399074A003A226C943D480FEC96DBEC7106A87896539AD")]
[assembly: InternalsVisibleTo("Microsoft.Identity.Web.Test.Common, PublicKey=00240000048000009400000006020000002400005253413100040000010001002D96616729B54F6D013D71559A017F50AA4861487226C523959D1579B93F3FDF71C08B980FD3130062B03D3DE115C4B84E7AC46AEF5E192A40E7457D5F3A08F66CEAB71143807F2C3CB0DA5E23B38F0559769978406F6E5D30CEADD7985FC73A5A609A8B74A1DF0A29399074A003A226C943D480FEC96DBEC7106A87896539AD")]
[assembly: InternalsVisibleTo("Microsoft.Identity.Web.Test.Integration, PublicKey=00240000048000009400000006020000002400005253413100040000010001002D96616729B54F6D013D71559A017F50AA4861487226C523959D1579B93F3FDF71C08B980FD3130062B03D3DE115C4B84E7AC46AEF5E192A40E7457D5F3A08F66CEAB71143807F2C3CB0DA5E23B38F0559769978406F6E5D30CEADD7985FC73A5A609A8B74A1DF0A29399074A003A226C943D480FEC96DBEC7106A87896539AD")]
[assembly: InternalsVisibleTo("DynamicProxyGenAssembly2, PublicKey=0024000004800000940000000602000000240000525341310004000001000100c547cac37abd99c8db225ef2f6c8a3602f3b3606cc9891605d02baa56104f4cfc0734aa39b93bf7852f7d9266654753cc297e7d2edfe0bac1cdcf9f717241550e0a7b191195b7667bb4f64bcb8e2121380fd1d9d46ad2d92d2d15605093924cceaf74c4861eff62abf69b9291ed0a340e113be11e6a7d3113e92484cf7045cc7")]
Original file line number Diff line number Diff line change
@@ -1 +1,8 @@
#nullable enable
Microsoft.Identity.Web.OidcFic.OidcIdpSignedAssertionLoader.Logger
Microsoft.Identity.Web.OidcFic.OidcIdpSignedAssertionLoader.OidcIdpSignedAssertionLoader(Microsoft.Extensions.Logging.ILogger<Microsoft.Identity.Web.OidcFic.OidcIdpSignedAssertionLoader!>! logger, Microsoft.Extensions.Options.IOptionsMonitor<Microsoft.Identity.Abstractions.MicrosoftIdentityApplicationOptions!>! options, System.IServiceProvider! serviceProvider, Microsoft.Identity.Abstractions.ITokenAcquirerFactory! tokenAcquirerFactory) -> void
static Microsoft.Identity.Web.OidcFic.OidcIdpSignedAssertionLoader.Logger.ConfigurationNotRegistered(Microsoft.Extensions.Logging.ILogger! logger, string! troubleshootingLink) -> void
static Microsoft.Identity.Web.OidcFic.OidcIdpSignedAssertionLoader.Logger.ConfigurationBinding(Microsoft.Extensions.Logging.ILogger! logger, string! sectionName) -> void
static Microsoft.Identity.Web.OidcFic.OidcIdpSignedAssertionLoader.Logger.CustomSignedAssertionProviderDataNull(Microsoft.Extensions.Logging.ILogger! logger) -> void
static Microsoft.Identity.Web.OidcFic.OidcIdpSignedAssertionLoader.Logger.ConfigurationSectionNull(Microsoft.Extensions.Logging.ILogger! logger) -> void
static Microsoft.Identity.Web.OidcFic.OidcIdpSignedAssertionLoader.Logger.SignedAssertionProviderFailed(Microsoft.Extensions.Logging.ILogger! logger, string! providerName, string! message) -> void
Original file line number Diff line number Diff line change
@@ -1 +1,8 @@
#nullable enable
Microsoft.Identity.Web.OidcFic.OidcIdpSignedAssertionLoader.Logger
Microsoft.Identity.Web.OidcFic.OidcIdpSignedAssertionLoader.OidcIdpSignedAssertionLoader(Microsoft.Extensions.Logging.ILogger<Microsoft.Identity.Web.OidcFic.OidcIdpSignedAssertionLoader!>! logger, Microsoft.Extensions.Options.IOptionsMonitor<Microsoft.Identity.Abstractions.MicrosoftIdentityApplicationOptions!>! options, System.IServiceProvider! serviceProvider, Microsoft.Identity.Abstractions.ITokenAcquirerFactory! tokenAcquirerFactory) -> void
static Microsoft.Identity.Web.OidcFic.OidcIdpSignedAssertionLoader.Logger.ConfigurationNotRegistered(Microsoft.Extensions.Logging.ILogger! logger, string! troubleshootingLink) -> void
static Microsoft.Identity.Web.OidcFic.OidcIdpSignedAssertionLoader.Logger.ConfigurationBinding(Microsoft.Extensions.Logging.ILogger! logger, string! sectionName) -> void
static Microsoft.Identity.Web.OidcFic.OidcIdpSignedAssertionLoader.Logger.CustomSignedAssertionProviderDataNull(Microsoft.Extensions.Logging.ILogger! logger) -> void
static Microsoft.Identity.Web.OidcFic.OidcIdpSignedAssertionLoader.Logger.ConfigurationSectionNull(Microsoft.Extensions.Logging.ILogger! logger) -> void
static Microsoft.Identity.Web.OidcFic.OidcIdpSignedAssertionLoader.Logger.SignedAssertionProviderFailed(Microsoft.Extensions.Logging.ILogger! logger, string! providerName, string! message) -> void
Original file line number Diff line number Diff line change
@@ -1 +1,8 @@
#nullable enable
Microsoft.Identity.Web.OidcFic.OidcIdpSignedAssertionLoader.Logger
Microsoft.Identity.Web.OidcFic.OidcIdpSignedAssertionLoader.OidcIdpSignedAssertionLoader(Microsoft.Extensions.Logging.ILogger<Microsoft.Identity.Web.OidcFic.OidcIdpSignedAssertionLoader!>! logger, Microsoft.Extensions.Options.IOptionsMonitor<Microsoft.Identity.Abstractions.MicrosoftIdentityApplicationOptions!>! options, System.IServiceProvider! serviceProvider, Microsoft.Identity.Abstractions.ITokenAcquirerFactory! tokenAcquirerFactory) -> void
static Microsoft.Identity.Web.OidcFic.OidcIdpSignedAssertionLoader.Logger.ConfigurationNotRegistered(Microsoft.Extensions.Logging.ILogger! logger, string! troubleshootingLink) -> void
static Microsoft.Identity.Web.OidcFic.OidcIdpSignedAssertionLoader.Logger.ConfigurationBinding(Microsoft.Extensions.Logging.ILogger! logger, string! sectionName) -> void
static Microsoft.Identity.Web.OidcFic.OidcIdpSignedAssertionLoader.Logger.CustomSignedAssertionProviderDataNull(Microsoft.Extensions.Logging.ILogger! logger) -> void
static Microsoft.Identity.Web.OidcFic.OidcIdpSignedAssertionLoader.Logger.ConfigurationSectionNull(Microsoft.Extensions.Logging.ILogger! logger) -> void
static Microsoft.Identity.Web.OidcFic.OidcIdpSignedAssertionLoader.Logger.SignedAssertionProviderFailed(Microsoft.Extensions.Logging.ILogger! logger, string! providerName, string! message) -> void
Original file line number Diff line number Diff line change
@@ -1 +1,8 @@
#nullable enable
Microsoft.Identity.Web.OidcFic.OidcIdpSignedAssertionLoader.Logger
Microsoft.Identity.Web.OidcFic.OidcIdpSignedAssertionLoader.OidcIdpSignedAssertionLoader(Microsoft.Extensions.Logging.ILogger<Microsoft.Identity.Web.OidcFic.OidcIdpSignedAssertionLoader!>! logger, Microsoft.Extensions.Options.IOptionsMonitor<Microsoft.Identity.Abstractions.MicrosoftIdentityApplicationOptions!>! options, System.IServiceProvider! serviceProvider, Microsoft.Identity.Abstractions.ITokenAcquirerFactory! tokenAcquirerFactory) -> void
static Microsoft.Identity.Web.OidcFic.OidcIdpSignedAssertionLoader.Logger.ConfigurationNotRegistered(Microsoft.Extensions.Logging.ILogger! logger, string! troubleshootingLink) -> void
static Microsoft.Identity.Web.OidcFic.OidcIdpSignedAssertionLoader.Logger.ConfigurationBinding(Microsoft.Extensions.Logging.ILogger! logger, string! sectionName) -> void
static Microsoft.Identity.Web.OidcFic.OidcIdpSignedAssertionLoader.Logger.CustomSignedAssertionProviderDataNull(Microsoft.Extensions.Logging.ILogger! logger) -> void
static Microsoft.Identity.Web.OidcFic.OidcIdpSignedAssertionLoader.Logger.ConfigurationSectionNull(Microsoft.Extensions.Logging.ILogger! logger) -> void
static Microsoft.Identity.Web.OidcFic.OidcIdpSignedAssertionLoader.Logger.SignedAssertionProviderFailed(Microsoft.Extensions.Logging.ILogger! logger, string! providerName, string! message) -> void
Original file line number Diff line number Diff line change
@@ -1 +1,8 @@
#nullable enable
Microsoft.Identity.Web.OidcFic.OidcIdpSignedAssertionLoader.Logger
Microsoft.Identity.Web.OidcFic.OidcIdpSignedAssertionLoader.OidcIdpSignedAssertionLoader(Microsoft.Extensions.Logging.ILogger<Microsoft.Identity.Web.OidcFic.OidcIdpSignedAssertionLoader!>! logger, Microsoft.Extensions.Options.IOptionsMonitor<Microsoft.Identity.Abstractions.MicrosoftIdentityApplicationOptions!>! options, System.IServiceProvider! serviceProvider, Microsoft.Identity.Abstractions.ITokenAcquirerFactory! tokenAcquirerFactory) -> void
static Microsoft.Identity.Web.OidcFic.OidcIdpSignedAssertionLoader.Logger.ConfigurationNotRegistered(Microsoft.Extensions.Logging.ILogger! logger, string! troubleshootingLink) -> void
static Microsoft.Identity.Web.OidcFic.OidcIdpSignedAssertionLoader.Logger.ConfigurationBinding(Microsoft.Extensions.Logging.ILogger! logger, string! sectionName) -> void
static Microsoft.Identity.Web.OidcFic.OidcIdpSignedAssertionLoader.Logger.CustomSignedAssertionProviderDataNull(Microsoft.Extensions.Logging.ILogger! logger) -> void
static Microsoft.Identity.Web.OidcFic.OidcIdpSignedAssertionLoader.Logger.ConfigurationSectionNull(Microsoft.Extensions.Logging.ILogger! logger) -> void
static Microsoft.Identity.Web.OidcFic.OidcIdpSignedAssertionLoader.Logger.SignedAssertionProviderFailed(Microsoft.Extensions.Logging.ILogger! logger, string! providerName, string! message) -> void
Original file line number Diff line number Diff line change
@@ -1 +1,8 @@
#nullable enable
Microsoft.Identity.Web.OidcFic.OidcIdpSignedAssertionLoader.Logger
Microsoft.Identity.Web.OidcFic.OidcIdpSignedAssertionLoader.OidcIdpSignedAssertionLoader(Microsoft.Extensions.Logging.ILogger<Microsoft.Identity.Web.OidcFic.OidcIdpSignedAssertionLoader!>! logger, Microsoft.Extensions.Options.IOptionsMonitor<Microsoft.Identity.Abstractions.MicrosoftIdentityApplicationOptions!>! options, System.IServiceProvider! serviceProvider, Microsoft.Identity.Abstractions.ITokenAcquirerFactory! tokenAcquirerFactory) -> void
static Microsoft.Identity.Web.OidcFic.OidcIdpSignedAssertionLoader.Logger.ConfigurationNotRegistered(Microsoft.Extensions.Logging.ILogger! logger, string! troubleshootingLink) -> void
static Microsoft.Identity.Web.OidcFic.OidcIdpSignedAssertionLoader.Logger.ConfigurationBinding(Microsoft.Extensions.Logging.ILogger! logger, string! sectionName) -> void
static Microsoft.Identity.Web.OidcFic.OidcIdpSignedAssertionLoader.Logger.CustomSignedAssertionProviderDataNull(Microsoft.Extensions.Logging.ILogger! logger) -> void
static Microsoft.Identity.Web.OidcFic.OidcIdpSignedAssertionLoader.Logger.ConfigurationSectionNull(Microsoft.Extensions.Logging.ILogger! logger) -> void
static Microsoft.Identity.Web.OidcFic.OidcIdpSignedAssertionLoader.Logger.SignedAssertionProviderFailed(Microsoft.Extensions.Logging.ILogger! logger, string! providerName, string! message) -> void
Loading
Loading