Skip to content
Merged
Show file tree
Hide file tree
Changes from all 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
2 changes: 1 addition & 1 deletion README-uptov12.md
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ You'll need to configure these settings based on the values in Azure:
| Domain | The value in Primary domain in the Microsoft Entra ID Directory Overview |
| TenantId | The value in Directory (tenant) ID on the App Registration Overview |
| ClientId | The value in Application (Client) ID on the App Registration Overview |
| ClientSecret | The client secret created for the App Registration (not required when using a [managed or workload identity](README.md#managed-identity--workload-identity)) |
| ClientSecret | The client secret created for the App Registration (not required when using a [managed identity, workload identity or certificate](README.md#managed-identity--workload-identity)) |

You can also customise the configuration by setting these settings:

Expand Down
2 changes: 1 addition & 1 deletion README-v13.md
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ You'll need to configure these settings based on the values in Azure:
| Domain | The value in Primary domain in the Microsoft Entra ID Directory Overview |
| TenantId | The value in Directory (tenant) ID on the App Registration Overview |
| ClientId | The value in Application (Client) ID on the App Registration Overview |
| ClientSecret | The client secret created for the App Registration (not required when using a [managed or workload identity](README.md#managed-identity--workload-identity)) |
| ClientSecret | The client secret created for the App Registration (not required when using a [managed identity, workload identity or certificate](README.md#managed-identity--workload-identity)) |

You can also customise the configuration by setting these settings:

Expand Down
2 changes: 1 addition & 1 deletion README-v14plus.md
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ You'll need to configure these settings based on the values in Azure:
| Domain | The value in Primary domain in the Microsoft Entra ID Directory Overview |
| TenantId | The value in Directory (tenant) ID on the App Registration Overview |
| ClientId | The value in Application (Client) ID on the App Registration Overview |
| ClientSecret | The client secret created for the App Registration (not required when using a [managed or workload identity](README.md#managed-identity--workload-identity)) |
| ClientSecret | The client secret created for the App Registration (not required when using a [managed identity, workload identity or certificate](README.md#managed-identity--workload-identity)) |

You can also customise the configuration by setting these settings:

Expand Down
2 changes: 1 addition & 1 deletion README-v15plus.md
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ You'll need to configure these settings based on the values in Azure:
| Domain | The value in Primary domain in the Microsoft Entra ID Directory Overview |
| TenantId | The value in Directory (tenant) ID on the App Registration Overview |
| ClientId | The value in Application (Client) ID on the App Registration Overview |
| ClientSecret | The client secret created for the App Registration (not required when using a [managed or workload identity](README.md#managed-identity--workload-identity)) |
| ClientSecret | The client secret created for the App Registration (not required when using a [managed identity, workload identity or certificate](README.md#managed-identity--workload-identity)) |

You can also customise the configuration by setting these settings:

Expand Down
12 changes: 9 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ In which case you'll need to add AddMicrosoftAccountAuthentication() to your Con

### Managed Identity / Workload Identity

By default the package authenticates against the App Registration using a client secret. Alternatively you can authenticate using an Azure Managed Identity or a Workload Identity (federated credentials, e.g. on AKS), which removes the need to store a client secret, by setting `CredentialType` in the `Credentials` section:
By default the package authenticates against the App Registration using a client secret. Alternatively you can authenticate using an Azure Managed Identity, a Workload Identity (federated credentials, e.g. on AKS) or a certificate, which removes the need to store a client secret, by setting `CredentialType` in the `Credentials` section:

```
"AzureSSO": {
Expand All @@ -73,10 +73,12 @@ By default the package authenticates against the App Registration using a client

| Setting | Description |
| ----------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| CredentialType | How the application authenticates to Entra ID: `Secret` (the default, uses ClientSecret), `ManagedIdentity` or `WorkloadIdentity` |
| CredentialType | How the application authenticates to Entra ID: `Secret` (the default, uses ClientSecret), `ManagedIdentity`, `WorkloadIdentity` or `Certificate` |
| ManagedIdentityClientId | Only used when CredentialType is `ManagedIdentity`. Set to the client ID of a user-assigned managed identity, or leave empty to use the system-assigned managed identity |
| CertificateThumbprint | Only used when CredentialType is `Certificate`. The thumbprint of the certificate to use |
| CertificateStorePath | Only used when CredentialType is `Certificate`. The certificate store to load the certificate from, in `StoreLocation/StoreName` format. Defaults to `CurrentUser/My` |

When `CredentialType` is `ManagedIdentity` or `WorkloadIdentity`, `ClientSecret` is not required and is ignored.
When `CredentialType` is `ManagedIdentity`, `WorkloadIdentity` or `Certificate`, `ClientSecret` is not required and is ignored.

#### Managed Identity

Expand All @@ -86,6 +88,10 @@ The managed identity is used as a federated identity credential for the App Regi

Workload identity authenticates using the federated token file issued by the Azure Workload Identity webhook. The `AZURE_FEDERATED_TOKEN_FILE` environment variable must be set — on AKS this means the workload identity webhook is enabled and the pod has the `azure.workload.identity/use: "true"` label. The App Registration needs a federated credential trusting the Kubernetes service account, and `TenantId` and `ClientId` must be set explicitly in the configuration. If the environment variable is missing the site will throw an error on startup.

#### Certificate

The certificate must be uploaded to the App Registration (Certificates & secrets) and installed in a certificate store the application can read, identified by `CertificateThumbprint`. `CertificateStorePath` selects which store to load it from (e.g. `CurrentUser/My` or `LocalMachine/My`) and defaults to `CurrentUser/My` if not set.

### Debugging

LogUnmappedRolesAsWarning
Expand Down
5 changes: 5 additions & 0 deletions src/Umbraco.Community.AzureSSO/AzureSSOConfiguration.cs
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,8 @@ public class AzureSSOCredentials
public string ClientId { get; set; } = "";
public string ManagedIdentityClientId { get; set; } = "";
public string ClientSecret { get; set; } = "";
public string CertificateThumbprint { get; set; } = "";
public string CertificateStorePath { get; set; } = "";
public string CallbackPath { get; set; } = "";
public string SignedOutCallbackPath { get; set; } = "";

Expand All @@ -91,6 +93,8 @@ public class AzureSSOCredentials
/// ManagedIdentity uses Azure Managed Identity; for a user-assigned identity set ManagedIdentityClientId,
/// for system-assigned leave it empty.
/// WorkloadIdentity uses federated credentials (e.g. AKS); TenantId and ClientId must be provided explicitly.
/// Certificate uses a certificate from a local certificate store, identified by CertificateThumbprint
/// (and optionally CertificateStorePath, which defaults to "CurrentUser/My").
/// </summary>
public CredentialType CredentialType { get; set; } = CredentialType.Secret;

Expand All @@ -101,6 +105,7 @@ public bool IsValid()
!string.IsNullOrEmpty(TenantId) &&
!string.IsNullOrEmpty(ClientId) &&
(CredentialType != CredentialType.Secret || !string.IsNullOrEmpty(ClientSecret)) &&
(CredentialType != CredentialType.Certificate || !string.IsNullOrEmpty(CertificateThumbprint)) &&
!string.IsNullOrEmpty(CallbackPath) &&
Comment on lines 107 to 109
!string.IsNullOrEmpty(SignedOutCallbackPath);
}
Expand Down
3 changes: 2 additions & 1 deletion src/Umbraco.Community.AzureSSO/CredentialType.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ public enum CredentialType
{
Secret = 0,
ManagedIdentity = 1,
WorkloadIdentity = 2
WorkloadIdentity = 2,
Certificate = 3
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,17 @@ private static void CopyCredentials(MicrosoftIdentityOptions options, AzureSsoCr
}
};
break;
case CredentialType.Certificate:
options.ClientCredentials = new[]
{
new CredentialDescription
{
SourceType = CredentialSource.StoreWithThumbprint,
CertificateStorePath = string.IsNullOrEmpty(settings.CertificateStorePath) ? "CurrentUser/My" : settings.CertificateStorePath,
CertificateThumbprint = settings.CertificateThumbprint,
}
};
break;
Comment on lines +142 to +152
case CredentialType.Secret:
default:
options.ClientSecret = settings.ClientSecret;
Expand Down
2 changes: 2 additions & 0 deletions src/Umbraco.Community.AzureSSO/Settings/AzureSSOSettings.cs
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,8 @@ public class AzureSsoCredentialSettings(AzureSSOCredentials credentials)
public string ClientId => credentials.ClientId;
public string ManagedIdentityClientId => credentials.ManagedIdentityClientId;
public string ClientSecret => credentials.ClientSecret;
public string CertificateThumbprint => credentials.CertificateThumbprint;
public string CertificateStorePath => credentials.CertificateStorePath;
public string CallbackPath => credentials.CallbackPath;
public string SignedOutCallbackPath => credentials.SignedOutCallbackPath;
public CredentialType CredentialType => credentials.CredentialType;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,14 @@
"type": "string",
"description": "The client secret created for the app registration. Only required when CredentialType is Secret."
},
"CertificateThumbprint": {
"type": "string",
"description": "The thumbprint of a certificate in the certificate store to use when CredentialType is Certificate."
},
"CertificateStorePath": {
"type": "string",
"description": "The certificate store to load the certificate from when CredentialType is Certificate, in \"StoreLocation/StoreName\" format. Defaults to \"CurrentUser/My\"."
},
"CredentialType": {
"description": "How the application authenticates to Entra ID (defaults to Secret)",
"default": "Secret",
Expand Down Expand Up @@ -161,16 +169,18 @@
},
"CredentialType": {
"type": "string",
"description": "How the application authenticates to Entra ID. Secret uses ClientSecret. ManagedIdentity uses Azure Managed Identity (set ManagedIdentityClientId for user-assigned, leave empty for system-assigned). WorkloadIdentity uses federated credentials (e.g. AKS) via the AZURE_FEDERATED_TOKEN_FILE environment variable.",
"description": "How the application authenticates to Entra ID. Secret uses ClientSecret. ManagedIdentity uses Azure Managed Identity (set ManagedIdentityClientId for user-assigned, leave empty for system-assigned). WorkloadIdentity uses federated credentials (e.g. AKS) via the AZURE_FEDERATED_TOKEN_FILE environment variable. Certificate uses a certificate from a local certificate store, identified by CertificateThumbprint and CertificateStorePath.",
"x-enumNames": [
"Secret",
"ManagedIdentity",
"WorkloadIdentity"
"WorkloadIdentity",
"Certificate"
],
"enum": [
"Secret",
"ManagedIdentity",
"WorkloadIdentity"
"WorkloadIdentity",
"Certificate"
]
}

Expand Down
Loading