From e3e897353c904799306db48e3d9d1c5e0dc03c48 Mon Sep 17 00:00:00 2001 From: Yvan Duhamel Date: Thu, 30 Dec 2021 15:21:23 +0100 Subject: [PATCH 01/19] add support for oidc --- .../MSFT_SPTrustedIdentityTokenIssuer.psm1 | 247 ++++++++++++++++-- ...FT_SPTrustedIdentityTokenIssuer.schema.mof | 8 +- 2 files changed, 234 insertions(+), 21 deletions(-) diff --git a/SharePointDsc/DSCResources/MSFT_SPTrustedIdentityTokenIssuer/MSFT_SPTrustedIdentityTokenIssuer.psm1 b/SharePointDsc/DSCResources/MSFT_SPTrustedIdentityTokenIssuer/MSFT_SPTrustedIdentityTokenIssuer.psm1 index 697a5a64c..0309d740d 100644 --- a/SharePointDsc/DSCResources/MSFT_SPTrustedIdentityTokenIssuer/MSFT_SPTrustedIdentityTokenIssuer.psm1 +++ b/SharePointDsc/DSCResources/MSFT_SPTrustedIdentityTokenIssuer/MSFT_SPTrustedIdentityTokenIssuer.psm1 @@ -12,14 +12,36 @@ function Get-TargetResource [String] $Description, - [Parameter(Mandatory = $true)] + # SAML-specific + [Parameter(Mandatory = $false)] [String] $Realm, - [Parameter(Mandatory = $true)] + # SAML-specific + [Parameter(Mandatory = $false)] [String] $SignInUrl, + # OIDC-specific + [Parameter(Mandatory = $false)] + [String] + $RegisteredIssuerName, + + # OIDC-specific + [Parameter(Mandatory = $false)] + [String] + $AuthorizationEndPointUri, + + # OIDC-specific + [Parameter(Mandatory = $false)] + [String] + $DefaultClientIdentifier, + + # OIDC-specific + [Parameter(Mandatory = $false)] + [String] + $SignOutUrl, + [Parameter(Mandatory = $true)] [String] $IdentifierClaim, @@ -49,6 +71,7 @@ function Get-TargetResource [String] $ProviderSignOutUri, + # SAML-specific [Parameter()] [System.Boolean] $UseWReplyParameter = $false @@ -68,11 +91,21 @@ function Get-TargetResource $description = $spTrust.Description $realm = $spTrust.DefaultProviderRealm $signInUrl = $spTrust.ProviderUri.OriginalString + $registeredIssuerName = $spTrust.RegisteredIssuerName + if ($false -eq [String]::IsNullOrWhiteSpace($params.AuthorizationEndPointUri)) + { + $authorizationEndPointUri = $spTrust.AuthorizationEndPointUri.ToString() + } + $defaultClientIdentifier = $spTrust.DefaultClientIdentifier + $signOutUrl = $spTrust.SignOutUrl $identifierClaim = $spTrust.IdentityClaimTypeInformation.InputClaimType $SigningCertificateThumbprint = $spTrust.SigningCertificate.Thumbprint $currentState = "Present" $claimProviderName = $sptrust.ClaimProviderName - $providerSignOutUri = $sptrust.ProviderSignOutUri.OriginalString + if ($false -eq [String]::IsNullOrWhiteSpace($params.ProviderSignOutUri)) + { + $providerSignOutUri = $sptrust.ProviderSignOutUri.OriginalString + } $useWReplyParameter = $sptrust.UseWReplyParameter $spTrust.ClaimTypeInformation | ForEach-Object -Process { @@ -88,6 +121,10 @@ function Get-TargetResource $description = "" $realm = "" $signInUrl = "" + $registeredIssuerName = "" + $authorizationEndPointUri = "" + $defaultClientIdentifier = "" + $signOutUrl = "" $identifierClaim = "" $SigningCertificateThumbprint = "" $currentState = "Absent" @@ -101,6 +138,10 @@ function Get-TargetResource Description = $description Realm = $realm SignInUrl = $signInUrl + RegisteredIssuerName = $registeredIssuerName + AuthorizationEndPointUri = $authorizationEndPointUri + DefaultClientIdentifier = $defaultClientIdentifier + SignOutUrl = $signOutUrl IdentifierClaim = $identifierClaim ClaimsMappings = $claimsMappings SigningCertificateThumbprint = $SigningCertificateThumbprint @@ -127,14 +168,36 @@ function Set-TargetResource [String] $Description, - [Parameter(Mandatory = $true)] + # SAML-specific + [Parameter(Mandatory = $false)] [String] $Realm, - [Parameter(Mandatory = $true)] + # SAML-specific + [Parameter(Mandatory = $false)] [String] $SignInUrl, + # OIDC-specific + [Parameter(Mandatory = $false)] + [String] + $RegisteredIssuerName, + + # OIDC-specific + [Parameter(Mandatory = $false)] + [String] + $AuthorizationEndPointUri, + + # OIDC-specific + [Parameter(Mandatory = $false)] + [String] + $DefaultClientIdentifier, + + # OIDC-specific + [Parameter(Mandatory = $false)] + [String] + $SignOutUrl, + [Parameter(Mandatory = $true)] [String] $IdentifierClaim, @@ -164,6 +227,7 @@ function Set-TargetResource [String] $ProviderSignOutUri, + # SAML-specific [Parameter()] [System.Boolean] $UseWReplyParameter = $false @@ -177,8 +241,8 @@ function Set-TargetResource { if ($CurrentValues.Ensure -eq "Absent") { - if ($PSBoundParameters.ContainsKey("SigningCertificateThumbprint") -and ` - $PSBoundParameters.ContainsKey("SigningCertificateFilePath")) + if ($true -eq $PSBoundParameters.ContainsKey("SigningCertificateThumbprint") -and + $true -eq $PSBoundParameters.ContainsKey("SigningCertificateFilePath")) { $message = ("Cannot use both parameters SigningCertificateThumbprint and SigningCertificateFilePath at the same time.") Add-SPDscEvent -Message $message ` @@ -188,8 +252,8 @@ function Set-TargetResource throw $message } - if (!$PSBoundParameters.ContainsKey("SigningCertificateThumbprint") -and ` - !$PSBoundParameters.ContainsKey("SigningCertificateFilePath")) + if ($false -eq $PSBoundParameters.ContainsKey("SigningCertificateThumbprint") -and + $false -eq $PSBoundParameters.ContainsKey("SigningCertificateFilePath")) { $message = ("At least one of the following parameters must be specified: " + ` "SigningCertificateThumbprint, SigningCertificateFilePath.") @@ -200,6 +264,59 @@ function Set-TargetResource throw $message } + # Ensure that at least one parameter is specified between Realm (SAML trust) or RegisteredIssuerName (OIDC trust) + if ($false -eq $PSBoundParameters.ContainsKey("Realm") -and + $false -eq $PSBoundParameters.ContainsKey("RegisteredIssuerName")) + { + $message = ("At least one of the following parameters must be specified: " + ` + "Realm (for SAML trust), RegisteredIssuerName (for OIDC trust).") + Add-SPDscEvent -Message $message ` + -EntryType 'Error' ` + -EventID 100 ` + -Source $MyInvocation.MyCommand.Source + throw $message + } + + # Ensure that parameters Realm (SAML trust) or RegisteredIssuerName (OIDC trust) are not both set + if ($true -eq $PSBoundParameters.ContainsKey("Realm") -and + $true -eq $PSBoundParameters.ContainsKey("RegisteredIssuerName")) + { + $message = ("Parameters Realm (for SAML trust) and RegisteredIssuerName (for OIDC trust) cannot be both set.") + Add-SPDscEvent -Message $message ` + -EntryType 'Error' ` + -EventID 100 ` + -Source $MyInvocation.MyCommand.Source + throw $message + } + + # SAML trust: If parameter Realm is set, then parameter SignInUrl is required + if ($true -eq $PSBoundParameters.ContainsKey("Realm") -and + $false -eq $PSBoundParameters.ContainsKey("SignInUrl")) + { + $message = ("Parameter Realm was set but SignInUrl is not set. Parameter SignInUrl required when Realm is set.") + Add-SPDscEvent -Message $message ` + -EntryType 'Error' ` + -EventID 100 ` + -Source $MyInvocation.MyCommand.Source + throw $message + } + + # OIDC trust: If parameter RegisteredIssuerName is set, + # then parameters AuthorizationEndPointUri, DefaultClientIdentifier and SignOutUrl are required + if ($true -eq $PSBoundParameters.ContainsKey("RegisteredIssuerName") -and ( + $false -eq $PSBoundParameters.ContainsKey("AuthorizationEndPointUri") -or + $false -eq $PSBoundParameters.ContainsKey("DefaultClientIdentifier") -or + $false -eq $PSBoundParameters.ContainsKey("SignOutUrl") )) + { + $message = ("Parameter RegisteredIssuerName was set but AuthorizationEndPointUri, DefaultClientIdentifier and SignOutUrl are not set." + ` + "Parameters AuthorizationEndPointUri, DefaultClientIdentifier and SignOutUrl are required when RegisteredIssuerName is set") + Add-SPDscEvent -Message $message ` + -EntryType 'Error' ` + -EventID 100 ` + -Source $MyInvocation.MyCommand.Source + throw $message + } + Write-Verbose -Message "Creating SPTrustedIdentityTokenIssuer '$Name'" $null = Invoke-SPDscCommand -Arguments @($PSBoundParameters, $MyInvocation.MyCommand.Source) ` -ScriptBlock { @@ -298,15 +415,31 @@ function Set-TargetResource throw $message } + $oidcSetup = $false + if ($false -eq [String]::IsNullOrWhiteSpace($params.RegisteredIssuerName)) + { + $oidcSetup = $true + } + $runParams = @{ } $runParams.Add("ImportTrustCertificate", $cert) $runParams.Add("Name", $params.Name) $runParams.Add("Description", $params.Description) - $runParams.Add("Realm", $params.Realm) - $runParams.Add("SignInUrl", $params.SignInUrl) + + if ($true -eq $oidcSetup) + { + $runParams.Add("RegisteredIssuerName", $params.RegisteredIssuerName) + $runParams.Add("AuthorizationEndPointUri", $params.AuthorizationEndPointUri) + $runParams.Add("DefaultClientIdentifier", $params.DefaultClientIdentifier) + $runParams.Add("SignOutUrl", $params.SignOutUrl) + } else { + $runParams.Add("Realm", $params.Realm) + $runParams.Add("SignInUrl", $params.SignInUrl) + $runParams.Add("UseWReply", $params.UseWReplyParameter) + } + $runParams.Add("IdentifierClaim", $params.IdentifierClaim) $runParams.Add("ClaimsMappings", $claimsMappingsArray) - $runParams.Add("UseWReply", $params.UseWReplyParameter) $trust = New-SPTrustedIdentityTokenIssuer @runParams if ($null -eq $trust) @@ -330,7 +463,7 @@ function Set-TargetResource } } - if ($params.ProviderSignOutUri) + if ($params.ProviderSignOutUri -and $false -eq $oidcSetup) { $installedVersion = Get-SPDscInstalledProductVersion # This property does not exist in SharePoint 2013 @@ -408,14 +541,36 @@ function Test-TargetResource [String] $Description, - [Parameter(Mandatory = $true)] + # SAML-specific + [Parameter(Mandatory = $false)] [String] $Realm, - [Parameter(Mandatory = $true)] + # SAML-specific + [Parameter(Mandatory = $false)] [String] $SignInUrl, + # OIDC-specific + [Parameter(Mandatory = $false)] + [String] + $RegisteredIssuerName, + + # OIDC-specific + [Parameter(Mandatory = $false)] + [String] + $AuthorizationEndPointUri, + + # OIDC-specific + [Parameter(Mandatory = $false)] + [String] + $DefaultClientIdentifier, + + # OIDC-specific + [Parameter(Mandatory = $false)] + [String] + $SignOutUrl, + [Parameter(Mandatory = $true)] [String] $IdentifierClaim, @@ -445,6 +600,7 @@ function Test-TargetResource [String] $ProviderSignOutUri, + # SAML-specific [Parameter()] [System.Boolean] $UseWReplyParameter = $false @@ -452,8 +608,8 @@ function Test-TargetResource Write-Verbose -Message "Testing SPTrustedIdentityTokenIssuer '$Name' settings" - if ($PSBoundParameters.ContainsKey("SigningCertificateThumbprint") -and ` - $PSBoundParameters.ContainsKey("SigningCertificateFilePath")) + if ($true -eq $PSBoundParameters.ContainsKey("SigningCertificateThumbprint") -and + $true -eq $PSBoundParameters.ContainsKey("SigningCertificateFilePath")) { $message = ("Cannot use both parameters SigningCertificateThumbprint and SigningCertificateFilePath at the same time.") Add-SPDscEvent -Message $message ` @@ -463,8 +619,8 @@ function Test-TargetResource throw $message } - if ($PSBoundParameters.ContainsKey("SigningCertificateThumbprint") -eq $false -and ` - $PSBoundParameters.ContainsKey("SigningCertificateFilePath") -eq $false) + if ($false -eq $PSBoundParameters.ContainsKey("SigningCertificateThumbprint") -and + $false -eq $PSBoundParameters.ContainsKey("SigningCertificateFilePath")) { $message = ("At least one of the following parameters must be specified: " + ` "SigningCertificateThumbprint, SigningCertificateFilePath.") @@ -475,6 +631,59 @@ function Test-TargetResource throw $message } + # Ensure that at least one parameter is specified between Realm (SAML trust) or RegisteredIssuerName (OIDC trust) + if ($false -eq $PSBoundParameters.ContainsKey("Realm") -and + $false -eq $PSBoundParameters.ContainsKey("RegisteredIssuerName")) + { + $message = ("At least one of the following parameters must be specified: " + ` + "Realm (for SAML trust), RegisteredIssuerName (for OIDC trust).") + Add-SPDscEvent -Message $message ` + -EntryType 'Error' ` + -EventID 100 ` + -Source $MyInvocation.MyCommand.Source + throw $message + } + + # Ensure that parameters Realm (SAML trust) or RegisteredIssuerName (OIDC trust) are not both set + if ($true -eq $PSBoundParameters.ContainsKey("Realm") -and + $true -eq $PSBoundParameters.ContainsKey("RegisteredIssuerName")) + { + $message = ("Parameters Realm (for SAML trust) and RegisteredIssuerName (for OIDC trust) cannot be both set.") + Add-SPDscEvent -Message $message ` + -EntryType 'Error' ` + -EventID 100 ` + -Source $MyInvocation.MyCommand.Source + throw $message + } + + # SAML trust: If parameter Realm is set, then parameter SignInUrl is required + if ($true -eq $PSBoundParameters.ContainsKey("Realm") -and + $false -eq $PSBoundParameters.ContainsKey("SignInUrl")) + { + $message = ("Parameter Realm was set but SignInUrl is not set. Parameter SignInUrl required when Realm is set.") + Add-SPDscEvent -Message $message ` + -EntryType 'Error' ` + -EventID 100 ` + -Source $MyInvocation.MyCommand.Source + throw $message + } + + # OIDC trust: If parameter RegisteredIssuerName is set, + # then parameters AuthorizationEndPointUri, DefaultClientIdentifier and SignOutUrl are required + if ($true -eq $PSBoundParameters.ContainsKey("RegisteredIssuerName") -and ( + $false -eq $PSBoundParameters.ContainsKey("AuthorizationEndPointUri") -or + $false -eq $PSBoundParameters.ContainsKey("DefaultClientIdentifier") -or + $false -eq $PSBoundParameters.ContainsKey("SignOutUrl") )) + { + $message = ("Parameter RegisteredIssuerName was set but AuthorizationEndPointUri, DefaultClientIdentifier and SignOutUrl are not set." + ` + "Parameters AuthorizationEndPointUri, DefaultClientIdentifier and SignOutUrl are required when RegisteredIssuerName is set") + Add-SPDscEvent -Message $message ` + -EntryType 'Error' ` + -EventID 100 ` + -Source $MyInvocation.MyCommand.Source + throw $message + } + $CurrentValues = Get-TargetResource @PSBoundParameters Write-Verbose -Message "Current Values: $(Convert-SPDscHashtableToString -Hashtable $CurrentValues)" diff --git a/SharePointDsc/DSCResources/MSFT_SPTrustedIdentityTokenIssuer/MSFT_SPTrustedIdentityTokenIssuer.schema.mof b/SharePointDsc/DSCResources/MSFT_SPTrustedIdentityTokenIssuer/MSFT_SPTrustedIdentityTokenIssuer.schema.mof index 289b50cf1..9696bb092 100644 --- a/SharePointDsc/DSCResources/MSFT_SPTrustedIdentityTokenIssuer/MSFT_SPTrustedIdentityTokenIssuer.schema.mof +++ b/SharePointDsc/DSCResources/MSFT_SPTrustedIdentityTokenIssuer/MSFT_SPTrustedIdentityTokenIssuer.schema.mof @@ -13,8 +13,12 @@ class MSFT_SPTrustedIdentityTokenIssuer : OMI_BaseResource { [Key, Description("Name of the SPTrustedIdentityTokenIssuer")] String Name; [Required, Description("Description of the SPTrustedIdentityTokenIssuer")] String Description; - [Required, Description("Default Realm that is passed to identity provider")] String Realm; - [Required, Description("URL of the identity provider where user is redirected to for authentication")] String SignInUrl; + [Write, Description("Default Realm that is passed to identity provider")] String Realm; + [Write, Description("URL of the identity provider where user is redirected to for authentication")] String SignInUrl; + [Write, Description("Required for OIDC trust: specify the identity of the issuer")] String RegisteredIssuerName; + [Write, Description("Required for OIDC trust: specify the sign-in URL of the issuer")] String AuthorizationEndPointUri; + [Write, Description("Required for OIDC trust: specify the client identifier of the issuer")] String DefaultClientIdentifier; + [Write, Description("Required for OIDC trust: specify the sign-out URL of the issuer")] String SignOutUrl; [Required, Description("Identity claim type that uniquely identifies the user")] String IdentifierClaim; [Required, Description("Array of MSFT_SPClaimTypeMapping to use with cmdlet New-SPClaimTypeMapping"), EmbeddedInstance("MSFT_SPClaimTypeMapping")] String ClaimsMappings[]; [Write, Description("Specify the thumbprint of the signing certificate, which must be located in certificate store LocalMachine\\My")] String SigningCertificateThumbprint; From 8d9b3e180bfc5c8b03fc2ab5c87d59fcd5179163 Mon Sep 17 00:00:00 2001 From: Yvan Duhamel Date: Mon, 3 Jan 2022 08:41:11 +0100 Subject: [PATCH 02/19] Update MSFT_SPTrustedIdentityTokenIssuer.psm1 --- .../MSFT_SPTrustedIdentityTokenIssuer.psm1 | 88 ++++++++++--------- 1 file changed, 45 insertions(+), 43 deletions(-) diff --git a/SharePointDsc/DSCResources/MSFT_SPTrustedIdentityTokenIssuer/MSFT_SPTrustedIdentityTokenIssuer.psm1 b/SharePointDsc/DSCResources/MSFT_SPTrustedIdentityTokenIssuer/MSFT_SPTrustedIdentityTokenIssuer.psm1 index 0309d740d..55b9abaa0 100644 --- a/SharePointDsc/DSCResources/MSFT_SPTrustedIdentityTokenIssuer/MSFT_SPTrustedIdentityTokenIssuer.psm1 +++ b/SharePointDsc/DSCResources/MSFT_SPTrustedIdentityTokenIssuer/MSFT_SPTrustedIdentityTokenIssuer.psm1 @@ -13,32 +13,32 @@ function Get-TargetResource $Description, # SAML-specific - [Parameter(Mandatory = $false)] + [Parameter()] [String] $Realm, # SAML-specific - [Parameter(Mandatory = $false)] + [Parameter()] [String] $SignInUrl, # OIDC-specific - [Parameter(Mandatory = $false)] + [Parameter()] [String] $RegisteredIssuerName, # OIDC-specific - [Parameter(Mandatory = $false)] + [Parameter()] [String] $AuthorizationEndPointUri, # OIDC-specific - [Parameter(Mandatory = $false)] + [Parameter()] [String] $DefaultClientIdentifier, # OIDC-specific - [Parameter(Mandatory = $false)] + [Parameter()] [String] $SignOutUrl, @@ -169,32 +169,32 @@ function Set-TargetResource $Description, # SAML-specific - [Parameter(Mandatory = $false)] + [Parameter()] [String] $Realm, # SAML-specific - [Parameter(Mandatory = $false)] + [Parameter()] [String] $SignInUrl, # OIDC-specific - [Parameter(Mandatory = $false)] + [Parameter()] [String] $RegisteredIssuerName, # OIDC-specific - [Parameter(Mandatory = $false)] + [Parameter()] [String] $AuthorizationEndPointUri, # OIDC-specific - [Parameter(Mandatory = $false)] + [Parameter()] [String] $DefaultClientIdentifier, # OIDC-specific - [Parameter(Mandatory = $false)] + [Parameter()] [String] $SignOutUrl, @@ -241,7 +241,7 @@ function Set-TargetResource { if ($CurrentValues.Ensure -eq "Absent") { - if ($true -eq $PSBoundParameters.ContainsKey("SigningCertificateThumbprint") -and + if ($true -eq $PSBoundParameters.ContainsKey("SigningCertificateThumbprint") -and $true -eq $PSBoundParameters.ContainsKey("SigningCertificateFilePath")) { $message = ("Cannot use both parameters SigningCertificateThumbprint and SigningCertificateFilePath at the same time.") @@ -252,7 +252,7 @@ function Set-TargetResource throw $message } - if ($false -eq $PSBoundParameters.ContainsKey("SigningCertificateThumbprint") -and + if ($false -eq $PSBoundParameters.ContainsKey("SigningCertificateThumbprint") -and $false -eq $PSBoundParameters.ContainsKey("SigningCertificateFilePath")) { $message = ("At least one of the following parameters must be specified: " + ` @@ -265,7 +265,7 @@ function Set-TargetResource } # Ensure that at least one parameter is specified between Realm (SAML trust) or RegisteredIssuerName (OIDC trust) - if ($false -eq $PSBoundParameters.ContainsKey("Realm") -and + if ($false -eq $PSBoundParameters.ContainsKey("Realm") -and $false -eq $PSBoundParameters.ContainsKey("RegisteredIssuerName")) { $message = ("At least one of the following parameters must be specified: " + ` @@ -278,7 +278,7 @@ function Set-TargetResource } # Ensure that parameters Realm (SAML trust) or RegisteredIssuerName (OIDC trust) are not both set - if ($true -eq $PSBoundParameters.ContainsKey("Realm") -and + if ($true -eq $PSBoundParameters.ContainsKey("Realm") -and $true -eq $PSBoundParameters.ContainsKey("RegisteredIssuerName")) { $message = ("Parameters Realm (for SAML trust) and RegisteredIssuerName (for OIDC trust) cannot be both set.") @@ -290,7 +290,7 @@ function Set-TargetResource } # SAML trust: If parameter Realm is set, then parameter SignInUrl is required - if ($true -eq $PSBoundParameters.ContainsKey("Realm") -and + if ($true -eq $PSBoundParameters.ContainsKey("Realm") -and $false -eq $PSBoundParameters.ContainsKey("SignInUrl")) { $message = ("Parameter Realm was set but SignInUrl is not set. Parameter SignInUrl required when Realm is set.") @@ -301,16 +301,16 @@ function Set-TargetResource throw $message } - # OIDC trust: If parameter RegisteredIssuerName is set, + # OIDC trust: If parameter RegisteredIssuerName is set, # then parameters AuthorizationEndPointUri, DefaultClientIdentifier and SignOutUrl are required if ($true -eq $PSBoundParameters.ContainsKey("RegisteredIssuerName") -and ( - $false -eq $PSBoundParameters.ContainsKey("AuthorizationEndPointUri") -or - $false -eq $PSBoundParameters.ContainsKey("DefaultClientIdentifier") -or - $false -eq $PSBoundParameters.ContainsKey("SignOutUrl") )) + $false -eq $PSBoundParameters.ContainsKey("AuthorizationEndPointUri") -or + $false -eq $PSBoundParameters.ContainsKey("DefaultClientIdentifier") -or + $false -eq $PSBoundParameters.ContainsKey("SignOutUrl") )) { $message = ("Parameter RegisteredIssuerName was set but AuthorizationEndPointUri, DefaultClientIdentifier and SignOutUrl are not set." + ` - "Parameters AuthorizationEndPointUri, DefaultClientIdentifier and SignOutUrl are required when RegisteredIssuerName is set") - Add-SPDscEvent -Message $message ` + "Parameters AuthorizationEndPointUri, DefaultClientIdentifier and SignOutUrl are required when RegisteredIssuerName is set") + Add-SPDscEvent -Message $message ` -EntryType 'Error' ` -EventID 100 ` -Source $MyInvocation.MyCommand.Source @@ -432,12 +432,14 @@ function Set-TargetResource $runParams.Add("AuthorizationEndPointUri", $params.AuthorizationEndPointUri) $runParams.Add("DefaultClientIdentifier", $params.DefaultClientIdentifier) $runParams.Add("SignOutUrl", $params.SignOutUrl) - } else { + } + else + { $runParams.Add("Realm", $params.Realm) $runParams.Add("SignInUrl", $params.SignInUrl) $runParams.Add("UseWReply", $params.UseWReplyParameter) - } - + } + $runParams.Add("IdentifierClaim", $params.IdentifierClaim) $runParams.Add("ClaimsMappings", $claimsMappingsArray) $trust = New-SPTrustedIdentityTokenIssuer @runParams @@ -542,32 +544,32 @@ function Test-TargetResource $Description, # SAML-specific - [Parameter(Mandatory = $false)] + [Parameter()] [String] $Realm, # SAML-specific - [Parameter(Mandatory = $false)] + [Parameter()] [String] $SignInUrl, # OIDC-specific - [Parameter(Mandatory = $false)] + [Parameter()] [String] $RegisteredIssuerName, # OIDC-specific - [Parameter(Mandatory = $false)] + [Parameter()] [String] $AuthorizationEndPointUri, # OIDC-specific - [Parameter(Mandatory = $false)] + [Parameter()] [String] $DefaultClientIdentifier, # OIDC-specific - [Parameter(Mandatory = $false)] + [Parameter()] [String] $SignOutUrl, @@ -608,7 +610,7 @@ function Test-TargetResource Write-Verbose -Message "Testing SPTrustedIdentityTokenIssuer '$Name' settings" - if ($true -eq $PSBoundParameters.ContainsKey("SigningCertificateThumbprint") -and + if ($true -eq $PSBoundParameters.ContainsKey("SigningCertificateThumbprint") -and $true -eq $PSBoundParameters.ContainsKey("SigningCertificateFilePath")) { $message = ("Cannot use both parameters SigningCertificateThumbprint and SigningCertificateFilePath at the same time.") @@ -619,7 +621,7 @@ function Test-TargetResource throw $message } - if ($false -eq $PSBoundParameters.ContainsKey("SigningCertificateThumbprint") -and + if ($false -eq $PSBoundParameters.ContainsKey("SigningCertificateThumbprint") -and $false -eq $PSBoundParameters.ContainsKey("SigningCertificateFilePath")) { $message = ("At least one of the following parameters must be specified: " + ` @@ -632,7 +634,7 @@ function Test-TargetResource } # Ensure that at least one parameter is specified between Realm (SAML trust) or RegisteredIssuerName (OIDC trust) - if ($false -eq $PSBoundParameters.ContainsKey("Realm") -and + if ($false -eq $PSBoundParameters.ContainsKey("Realm") -and $false -eq $PSBoundParameters.ContainsKey("RegisteredIssuerName")) { $message = ("At least one of the following parameters must be specified: " + ` @@ -645,7 +647,7 @@ function Test-TargetResource } # Ensure that parameters Realm (SAML trust) or RegisteredIssuerName (OIDC trust) are not both set - if ($true -eq $PSBoundParameters.ContainsKey("Realm") -and + if ($true -eq $PSBoundParameters.ContainsKey("Realm") -and $true -eq $PSBoundParameters.ContainsKey("RegisteredIssuerName")) { $message = ("Parameters Realm (for SAML trust) and RegisteredIssuerName (for OIDC trust) cannot be both set.") @@ -657,7 +659,7 @@ function Test-TargetResource } # SAML trust: If parameter Realm is set, then parameter SignInUrl is required - if ($true -eq $PSBoundParameters.ContainsKey("Realm") -and + if ($true -eq $PSBoundParameters.ContainsKey("Realm") -and $false -eq $PSBoundParameters.ContainsKey("SignInUrl")) { $message = ("Parameter Realm was set but SignInUrl is not set. Parameter SignInUrl required when Realm is set.") @@ -668,16 +670,16 @@ function Test-TargetResource throw $message } - # OIDC trust: If parameter RegisteredIssuerName is set, + # OIDC trust: If parameter RegisteredIssuerName is set, # then parameters AuthorizationEndPointUri, DefaultClientIdentifier and SignOutUrl are required if ($true -eq $PSBoundParameters.ContainsKey("RegisteredIssuerName") -and ( - $false -eq $PSBoundParameters.ContainsKey("AuthorizationEndPointUri") -or - $false -eq $PSBoundParameters.ContainsKey("DefaultClientIdentifier") -or - $false -eq $PSBoundParameters.ContainsKey("SignOutUrl") )) + $false -eq $PSBoundParameters.ContainsKey("AuthorizationEndPointUri") -or + $false -eq $PSBoundParameters.ContainsKey("DefaultClientIdentifier") -or + $false -eq $PSBoundParameters.ContainsKey("SignOutUrl") )) { $message = ("Parameter RegisteredIssuerName was set but AuthorizationEndPointUri, DefaultClientIdentifier and SignOutUrl are not set." + ` - "Parameters AuthorizationEndPointUri, DefaultClientIdentifier and SignOutUrl are required when RegisteredIssuerName is set") - Add-SPDscEvent -Message $message ` + "Parameters AuthorizationEndPointUri, DefaultClientIdentifier and SignOutUrl are required when RegisteredIssuerName is set") + Add-SPDscEvent -Message $message ` -EntryType 'Error' ` -EventID 100 ` -Source $MyInvocation.MyCommand.Source From 4d6c0effe4ce2b276a18472568cdcaf47cbf7d5f Mon Sep 17 00:00:00 2001 From: Yvan Duhamel Date: Mon, 3 Jan 2022 08:41:15 +0100 Subject: [PATCH 03/19] Update CHANGELOG.md --- CHANGELOG.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index d2cda8803..74a9f455b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] +- SPTrustedIdentityTokenIssuer + - Added parameters to support OIDC authentication in SharePoint Server Subscription Edition + ## [5.0.0] - 2021-12-17 ### Added From d42e54ab8495398a479df0574fd8d5a2cbfc3f99 Mon Sep 17 00:00:00 2001 From: Yvan Duhamel Date: Tue, 4 Jan 2022 11:35:36 +0100 Subject: [PATCH 04/19] RegisteredIssuerName is not an OIDC-specific parameter --- .../MSFT_SPTrustedIdentityTokenIssuer.psm1 | 89 +++++++++---------- ...FT_SPTrustedIdentityTokenIssuer.schema.mof | 2 +- 2 files changed, 42 insertions(+), 49 deletions(-) diff --git a/SharePointDsc/DSCResources/MSFT_SPTrustedIdentityTokenIssuer/MSFT_SPTrustedIdentityTokenIssuer.psm1 b/SharePointDsc/DSCResources/MSFT_SPTrustedIdentityTokenIssuer/MSFT_SPTrustedIdentityTokenIssuer.psm1 index 55b9abaa0..03b95c158 100644 --- a/SharePointDsc/DSCResources/MSFT_SPTrustedIdentityTokenIssuer/MSFT_SPTrustedIdentityTokenIssuer.psm1 +++ b/SharePointDsc/DSCResources/MSFT_SPTrustedIdentityTokenIssuer/MSFT_SPTrustedIdentityTokenIssuer.psm1 @@ -22,7 +22,6 @@ function Get-TargetResource [String] $SignInUrl, - # OIDC-specific [Parameter()] [String] $RegisteredIssuerName, @@ -178,7 +177,6 @@ function Set-TargetResource [String] $SignInUrl, - # OIDC-specific [Parameter()] [String] $RegisteredIssuerName, @@ -241,7 +239,7 @@ function Set-TargetResource { if ($CurrentValues.Ensure -eq "Absent") { - if ($true -eq $PSBoundParameters.ContainsKey("SigningCertificateThumbprint") -and + if ($true -eq $PSBoundParameters.ContainsKey("SigningCertificateThumbprint") -and $true -eq $PSBoundParameters.ContainsKey("SigningCertificateFilePath")) { $message = ("Cannot use both parameters SigningCertificateThumbprint and SigningCertificateFilePath at the same time.") @@ -252,7 +250,7 @@ function Set-TargetResource throw $message } - if ($false -eq $PSBoundParameters.ContainsKey("SigningCertificateThumbprint") -and + if ($false -eq $PSBoundParameters.ContainsKey("SigningCertificateThumbprint") -and $false -eq $PSBoundParameters.ContainsKey("SigningCertificateFilePath")) { $message = ("At least one of the following parameters must be specified: " + ` @@ -264,12 +262,12 @@ function Set-TargetResource throw $message } - # Ensure that at least one parameter is specified between Realm (SAML trust) or RegisteredIssuerName (OIDC trust) - if ($false -eq $PSBoundParameters.ContainsKey("Realm") -and - $false -eq $PSBoundParameters.ContainsKey("RegisteredIssuerName")) + # Ensure that at least one parameter is specified between Realm (SAML trust) or DefaultClientIdentifier (OIDC trust) + if ($false -eq $PSBoundParameters.ContainsKey("Realm") -and + $false -eq $PSBoundParameters.ContainsKey("DefaultClientIdentifier")) { $message = ("At least one of the following parameters must be specified: " + ` - "Realm (for SAML trust), RegisteredIssuerName (for OIDC trust).") + "Realm (for SAML trust), DefaultClientIdentifier (for OIDC trust).") Add-SPDscEvent -Message $message ` -EntryType 'Error' ` -EventID 100 ` @@ -277,11 +275,11 @@ function Set-TargetResource throw $message } - # Ensure that parameters Realm (SAML trust) or RegisteredIssuerName (OIDC trust) are not both set - if ($true -eq $PSBoundParameters.ContainsKey("Realm") -and - $true -eq $PSBoundParameters.ContainsKey("RegisteredIssuerName")) + # Ensure that parameters Realm (SAML trust) or DefaultClientIdentifier (OIDC trust) are not both set + if ($true -eq $PSBoundParameters.ContainsKey("Realm") -and + $true -eq $PSBoundParameters.ContainsKey("DefaultClientIdentifier")) { - $message = ("Parameters Realm (for SAML trust) and RegisteredIssuerName (for OIDC trust) cannot be both set.") + $message = ("Parameters Realm (for SAML trust) and DefaultClientIdentifier (for OIDC trust) cannot be both set.") Add-SPDscEvent -Message $message ` -EntryType 'Error' ` -EventID 100 ` @@ -290,7 +288,7 @@ function Set-TargetResource } # SAML trust: If parameter Realm is set, then parameter SignInUrl is required - if ($true -eq $PSBoundParameters.ContainsKey("Realm") -and + if ($true -eq $PSBoundParameters.ContainsKey("Realm") -and $false -eq $PSBoundParameters.ContainsKey("SignInUrl")) { $message = ("Parameter Realm was set but SignInUrl is not set. Parameter SignInUrl required when Realm is set.") @@ -301,16 +299,15 @@ function Set-TargetResource throw $message } - # OIDC trust: If parameter RegisteredIssuerName is set, - # then parameters AuthorizationEndPointUri, DefaultClientIdentifier and SignOutUrl are required - if ($true -eq $PSBoundParameters.ContainsKey("RegisteredIssuerName") -and ( - $false -eq $PSBoundParameters.ContainsKey("AuthorizationEndPointUri") -or - $false -eq $PSBoundParameters.ContainsKey("DefaultClientIdentifier") -or - $false -eq $PSBoundParameters.ContainsKey("SignOutUrl") )) + # OIDC trust: If parameter DefaultClientIdentifier is set, + # then parameters AuthorizationEndPointUri and SignOutUrl are required + if ($true -eq $PSBoundParameters.ContainsKey("DefaultClientIdentifier") -and ( + $false -eq $PSBoundParameters.ContainsKey("AuthorizationEndPointUri") -or + $false -eq $PSBoundParameters.ContainsKey("SignOutUrl") )) { - $message = ("Parameter RegisteredIssuerName was set but AuthorizationEndPointUri, DefaultClientIdentifier and SignOutUrl are not set." + ` - "Parameters AuthorizationEndPointUri, DefaultClientIdentifier and SignOutUrl are required when RegisteredIssuerName is set") - Add-SPDscEvent -Message $message ` + $message = ("Parameter DefaultClientIdentifier was set but AuthorizationEndPointUri or SignOutUrl are not set." + ` + "Parameters AuthorizationEndPointUri, DefaultClientIdentifier and SignOutUrl are required when DefaultClientIdentifier is set") + Add-SPDscEvent -Message $message ` -EntryType 'Error' ` -EventID 100 ` -Source $MyInvocation.MyCommand.Source @@ -432,14 +429,12 @@ function Set-TargetResource $runParams.Add("AuthorizationEndPointUri", $params.AuthorizationEndPointUri) $runParams.Add("DefaultClientIdentifier", $params.DefaultClientIdentifier) $runParams.Add("SignOutUrl", $params.SignOutUrl) - } - else - { + } else { $runParams.Add("Realm", $params.Realm) $runParams.Add("SignInUrl", $params.SignInUrl) $runParams.Add("UseWReply", $params.UseWReplyParameter) - } - + } + $runParams.Add("IdentifierClaim", $params.IdentifierClaim) $runParams.Add("ClaimsMappings", $claimsMappingsArray) $trust = New-SPTrustedIdentityTokenIssuer @runParams @@ -553,7 +548,6 @@ function Test-TargetResource [String] $SignInUrl, - # OIDC-specific [Parameter()] [String] $RegisteredIssuerName, @@ -610,7 +604,7 @@ function Test-TargetResource Write-Verbose -Message "Testing SPTrustedIdentityTokenIssuer '$Name' settings" - if ($true -eq $PSBoundParameters.ContainsKey("SigningCertificateThumbprint") -and + if ($true -eq $PSBoundParameters.ContainsKey("SigningCertificateThumbprint") -and $true -eq $PSBoundParameters.ContainsKey("SigningCertificateFilePath")) { $message = ("Cannot use both parameters SigningCertificateThumbprint and SigningCertificateFilePath at the same time.") @@ -621,7 +615,7 @@ function Test-TargetResource throw $message } - if ($false -eq $PSBoundParameters.ContainsKey("SigningCertificateThumbprint") -and + if ($false -eq $PSBoundParameters.ContainsKey("SigningCertificateThumbprint") -and $false -eq $PSBoundParameters.ContainsKey("SigningCertificateFilePath")) { $message = ("At least one of the following parameters must be specified: " + ` @@ -633,12 +627,12 @@ function Test-TargetResource throw $message } - # Ensure that at least one parameter is specified between Realm (SAML trust) or RegisteredIssuerName (OIDC trust) - if ($false -eq $PSBoundParameters.ContainsKey("Realm") -and - $false -eq $PSBoundParameters.ContainsKey("RegisteredIssuerName")) + # Ensure that at least one parameter is specified between Realm (SAML trust) or DefaultClientIdentifier (OIDC trust) + if ($false -eq $PSBoundParameters.ContainsKey("Realm") -and + $false -eq $PSBoundParameters.ContainsKey("DefaultClientIdentifier")) { $message = ("At least one of the following parameters must be specified: " + ` - "Realm (for SAML trust), RegisteredIssuerName (for OIDC trust).") + "Realm (for SAML trust), DefaultClientIdentifier (for OIDC trust).") Add-SPDscEvent -Message $message ` -EntryType 'Error' ` -EventID 100 ` @@ -646,11 +640,11 @@ function Test-TargetResource throw $message } - # Ensure that parameters Realm (SAML trust) or RegisteredIssuerName (OIDC trust) are not both set - if ($true -eq $PSBoundParameters.ContainsKey("Realm") -and - $true -eq $PSBoundParameters.ContainsKey("RegisteredIssuerName")) + # Ensure that parameters Realm (SAML trust) or DefaultClientIdentifier (OIDC trust) are not both set + if ($true -eq $PSBoundParameters.ContainsKey("Realm") -and + $true -eq $PSBoundParameters.ContainsKey("DefaultClientIdentifier")) { - $message = ("Parameters Realm (for SAML trust) and RegisteredIssuerName (for OIDC trust) cannot be both set.") + $message = ("Parameters Realm (for SAML trust) and DefaultClientIdentifier (for OIDC trust) cannot be both set.") Add-SPDscEvent -Message $message ` -EntryType 'Error' ` -EventID 100 ` @@ -659,7 +653,7 @@ function Test-TargetResource } # SAML trust: If parameter Realm is set, then parameter SignInUrl is required - if ($true -eq $PSBoundParameters.ContainsKey("Realm") -and + if ($true -eq $PSBoundParameters.ContainsKey("Realm") -and $false -eq $PSBoundParameters.ContainsKey("SignInUrl")) { $message = ("Parameter Realm was set but SignInUrl is not set. Parameter SignInUrl required when Realm is set.") @@ -670,16 +664,15 @@ function Test-TargetResource throw $message } - # OIDC trust: If parameter RegisteredIssuerName is set, - # then parameters AuthorizationEndPointUri, DefaultClientIdentifier and SignOutUrl are required - if ($true -eq $PSBoundParameters.ContainsKey("RegisteredIssuerName") -and ( - $false -eq $PSBoundParameters.ContainsKey("AuthorizationEndPointUri") -or - $false -eq $PSBoundParameters.ContainsKey("DefaultClientIdentifier") -or - $false -eq $PSBoundParameters.ContainsKey("SignOutUrl") )) + # OIDC trust: If parameter DefaultClientIdentifier is set, + # then parameters AuthorizationEndPointUri and SignOutUrl are required + if ($true -eq $PSBoundParameters.ContainsKey("DefaultClientIdentifier") -and ( + $false -eq $PSBoundParameters.ContainsKey("AuthorizationEndPointUri") -or + $false -eq $PSBoundParameters.ContainsKey("SignOutUrl") )) { - $message = ("Parameter RegisteredIssuerName was set but AuthorizationEndPointUri, DefaultClientIdentifier and SignOutUrl are not set." + ` - "Parameters AuthorizationEndPointUri, DefaultClientIdentifier and SignOutUrl are required when RegisteredIssuerName is set") - Add-SPDscEvent -Message $message ` + $message = ("Parameter DefaultClientIdentifier was set but AuthorizationEndPointUri or SignOutUrl are not set." + ` + "Parameters AuthorizationEndPointUri, DefaultClientIdentifier and SignOutUrl are required when DefaultClientIdentifier is set") + Add-SPDscEvent -Message $message ` -EntryType 'Error' ` -EventID 100 ` -Source $MyInvocation.MyCommand.Source diff --git a/SharePointDsc/DSCResources/MSFT_SPTrustedIdentityTokenIssuer/MSFT_SPTrustedIdentityTokenIssuer.schema.mof b/SharePointDsc/DSCResources/MSFT_SPTrustedIdentityTokenIssuer/MSFT_SPTrustedIdentityTokenIssuer.schema.mof index 9696bb092..1c6f67b7d 100644 --- a/SharePointDsc/DSCResources/MSFT_SPTrustedIdentityTokenIssuer/MSFT_SPTrustedIdentityTokenIssuer.schema.mof +++ b/SharePointDsc/DSCResources/MSFT_SPTrustedIdentityTokenIssuer/MSFT_SPTrustedIdentityTokenIssuer.schema.mof @@ -15,7 +15,7 @@ class MSFT_SPTrustedIdentityTokenIssuer : OMI_BaseResource [Required, Description("Description of the SPTrustedIdentityTokenIssuer")] String Description; [Write, Description("Default Realm that is passed to identity provider")] String Realm; [Write, Description("URL of the identity provider where user is redirected to for authentication")] String SignInUrl; - [Write, Description("Required for OIDC trust: specify the identity of the issuer")] String RegisteredIssuerName; + [Write, Description("Specify the identity of the issuer")] String RegisteredIssuerName; [Write, Description("Required for OIDC trust: specify the sign-in URL of the issuer")] String AuthorizationEndPointUri; [Write, Description("Required for OIDC trust: specify the client identifier of the issuer")] String DefaultClientIdentifier; [Write, Description("Required for OIDC trust: specify the sign-out URL of the issuer")] String SignOutUrl; From 2ebe9f2680ee1aac38db1a2f611e79d898ea37a8 Mon Sep 17 00:00:00 2001 From: Yvan Duhamel Date: Tue, 4 Jan 2022 11:35:39 +0100 Subject: [PATCH 05/19] Update readme.md --- .../MSFT_SPTrustedIdentityTokenIssuer/readme.md | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/SharePointDsc/DSCResources/MSFT_SPTrustedIdentityTokenIssuer/readme.md b/SharePointDsc/DSCResources/MSFT_SPTrustedIdentityTokenIssuer/readme.md index 00d1bcec6..8b28a4dc9 100644 --- a/SharePointDsc/DSCResources/MSFT_SPTrustedIdentityTokenIssuer/readme.md +++ b/SharePointDsc/DSCResources/MSFT_SPTrustedIdentityTokenIssuer/readme.md @@ -6,6 +6,12 @@ This resource is used to create or remove SPTrustedIdentityTokenIssuer in a SharePoint farm. +In SharePoint 2013 / 2016 / 2019, it can only be a SAML trust. +In SharePoint Subscription, it can be a SAML trust or an OIDC trust. + +For a SAML trust, the specific mandatory parameters are Realm, SignInUrl, +and either SigningCertificateThumbPrint or SigningCertificateFilePath. + Either parameter SigningCertificateThumbPrint or SigningCertificateFilePath must be set. If specifying both SigningCertificateThumbPrint and SigningCertificateFilePath, the certificate thumbprint will be verified @@ -21,6 +27,9 @@ certiificate store because SharePoint does not accept it. The SigningCertificateFilePath must be the file path to the public key of the signing certificate. +For an OIDC trust, the specific mandatory parameters are +AuthorizationEndPointUri, DefaultClientIdentifier and SignOutUrl. + The ClaimsMappings property is an array of MSFT_SPClaimTypeMapping to use with cmdlet New-SPClaimTypeMapping. Each MSFT_SPClaimTypeMapping requires properties Name and IncomingClaimType. Property LocalClaimType is not From 9c4c7d3133dca9ed406f9e3724e1d4a9b727296e Mon Sep 17 00:00:00 2001 From: Yvan Duhamel Date: Tue, 4 Jan 2022 17:23:42 +0100 Subject: [PATCH 06/19] RegisteredIssuerName is required for OIDC --- .../MSFT_SPTrustedIdentityTokenIssuer.psm1 | 14 ++++++++------ .../MSFT_SPTrustedIdentityTokenIssuer.schema.mof | 2 +- .../MSFT_SPTrustedIdentityTokenIssuer/readme.md | 2 +- 3 files changed, 10 insertions(+), 8 deletions(-) diff --git a/SharePointDsc/DSCResources/MSFT_SPTrustedIdentityTokenIssuer/MSFT_SPTrustedIdentityTokenIssuer.psm1 b/SharePointDsc/DSCResources/MSFT_SPTrustedIdentityTokenIssuer/MSFT_SPTrustedIdentityTokenIssuer.psm1 index 03b95c158..9364dab1c 100644 --- a/SharePointDsc/DSCResources/MSFT_SPTrustedIdentityTokenIssuer/MSFT_SPTrustedIdentityTokenIssuer.psm1 +++ b/SharePointDsc/DSCResources/MSFT_SPTrustedIdentityTokenIssuer/MSFT_SPTrustedIdentityTokenIssuer.psm1 @@ -300,13 +300,14 @@ function Set-TargetResource } # OIDC trust: If parameter DefaultClientIdentifier is set, - # then parameters AuthorizationEndPointUri and SignOutUrl are required + # then parameters AuthorizationEndPointUri, RegisteredIssuerName and SignOutUrl are required if ($true -eq $PSBoundParameters.ContainsKey("DefaultClientIdentifier") -and ( $false -eq $PSBoundParameters.ContainsKey("AuthorizationEndPointUri") -or + $false -eq $PSBoundParameters.ContainsKey("RegisteredIssuerName") -or $false -eq $PSBoundParameters.ContainsKey("SignOutUrl") )) { - $message = ("Parameter DefaultClientIdentifier was set but AuthorizationEndPointUri or SignOutUrl are not set." + ` - "Parameters AuthorizationEndPointUri, DefaultClientIdentifier and SignOutUrl are required when DefaultClientIdentifier is set") + $message = ("Parameter DefaultClientIdentifier was set but AuthorizationEndPointUri, RegisteredIssuerName or SignOutUrl are not set." + ` + "Parameters AuthorizationEndPointUri, RegisteredIssuerName, DefaultClientIdentifier and SignOutUrl are required when DefaultClientIdentifier is set") Add-SPDscEvent -Message $message ` -EntryType 'Error' ` -EventID 100 ` @@ -665,13 +666,14 @@ function Test-TargetResource } # OIDC trust: If parameter DefaultClientIdentifier is set, - # then parameters AuthorizationEndPointUri and SignOutUrl are required + # then parameters AuthorizationEndPointUri, RegisteredIssuerName and SignOutUrl are required if ($true -eq $PSBoundParameters.ContainsKey("DefaultClientIdentifier") -and ( $false -eq $PSBoundParameters.ContainsKey("AuthorizationEndPointUri") -or + $false -eq $PSBoundParameters.ContainsKey("RegisteredIssuerName") -or $false -eq $PSBoundParameters.ContainsKey("SignOutUrl") )) { - $message = ("Parameter DefaultClientIdentifier was set but AuthorizationEndPointUri or SignOutUrl are not set." + ` - "Parameters AuthorizationEndPointUri, DefaultClientIdentifier and SignOutUrl are required when DefaultClientIdentifier is set") + $message = ("Parameter DefaultClientIdentifier was set but AuthorizationEndPointUri, RegisteredIssuerName or SignOutUrl are not set." + ` + "Parameters AuthorizationEndPointUri, RegisteredIssuerName, DefaultClientIdentifier and SignOutUrl are required when DefaultClientIdentifier is set") Add-SPDscEvent -Message $message ` -EntryType 'Error' ` -EventID 100 ` diff --git a/SharePointDsc/DSCResources/MSFT_SPTrustedIdentityTokenIssuer/MSFT_SPTrustedIdentityTokenIssuer.schema.mof b/SharePointDsc/DSCResources/MSFT_SPTrustedIdentityTokenIssuer/MSFT_SPTrustedIdentityTokenIssuer.schema.mof index 1c6f67b7d..804bf2a2e 100644 --- a/SharePointDsc/DSCResources/MSFT_SPTrustedIdentityTokenIssuer/MSFT_SPTrustedIdentityTokenIssuer.schema.mof +++ b/SharePointDsc/DSCResources/MSFT_SPTrustedIdentityTokenIssuer/MSFT_SPTrustedIdentityTokenIssuer.schema.mof @@ -15,7 +15,7 @@ class MSFT_SPTrustedIdentityTokenIssuer : OMI_BaseResource [Required, Description("Description of the SPTrustedIdentityTokenIssuer")] String Description; [Write, Description("Default Realm that is passed to identity provider")] String Realm; [Write, Description("URL of the identity provider where user is redirected to for authentication")] String SignInUrl; - [Write, Description("Specify the identity of the issuer")] String RegisteredIssuerName; + [Write, Description("Required for OIDC trust: Specify the identity of the issuer")] String RegisteredIssuerName; [Write, Description("Required for OIDC trust: specify the sign-in URL of the issuer")] String AuthorizationEndPointUri; [Write, Description("Required for OIDC trust: specify the client identifier of the issuer")] String DefaultClientIdentifier; [Write, Description("Required for OIDC trust: specify the sign-out URL of the issuer")] String SignOutUrl; diff --git a/SharePointDsc/DSCResources/MSFT_SPTrustedIdentityTokenIssuer/readme.md b/SharePointDsc/DSCResources/MSFT_SPTrustedIdentityTokenIssuer/readme.md index 8b28a4dc9..6719035cd 100644 --- a/SharePointDsc/DSCResources/MSFT_SPTrustedIdentityTokenIssuer/readme.md +++ b/SharePointDsc/DSCResources/MSFT_SPTrustedIdentityTokenIssuer/readme.md @@ -27,7 +27,7 @@ certiificate store because SharePoint does not accept it. The SigningCertificateFilePath must be the file path to the public key of the signing certificate. -For an OIDC trust, the specific mandatory parameters are +For an OIDC trust, the specific mandatory parameters are RegisteredIssuerName, AuthorizationEndPointUri, DefaultClientIdentifier and SignOutUrl. The ClaimsMappings property is an array of MSFT_SPClaimTypeMapping to use From 06575b64351ef7376447d56b9db92d0f584bbbb7 Mon Sep 17 00:00:00 2001 From: Yvan Duhamel Date: Wed, 5 Jan 2022 10:20:36 +0100 Subject: [PATCH 07/19] Update SharePointDsc.SPTrustedIdentityTokenIssuer.Tests.ps1 --- ...Dsc.SPTrustedIdentityTokenIssuer.Tests.ps1 | 400 ++++++++++++++---- 1 file changed, 323 insertions(+), 77 deletions(-) diff --git a/tests/Unit/SharePointDsc/SharePointDsc.SPTrustedIdentityTokenIssuer.Tests.ps1 b/tests/Unit/SharePointDsc/SharePointDsc.SPTrustedIdentityTokenIssuer.Tests.ps1 index 693c41dc0..c66ab1bcb 100644 --- a/tests/Unit/SharePointDsc/SharePointDsc.SPTrustedIdentityTokenIssuer.Tests.ps1 +++ b/tests/Unit/SharePointDsc/SharePointDsc.SPTrustedIdentityTokenIssuer.Tests.ps1 @@ -133,7 +133,7 @@ try } # Test contexts - Context -Name "The SPTrustedLoginProvider does not exist but should, using a signing certificate in the certificate store" -Fixture { + Context -Name "The SAML SPTrustedLoginProvider does not exist but should, using a signing certificate in the certificate store" -Fixture { BeforeAll { $testParams = @{ Name = "Contoso" @@ -143,14 +143,14 @@ try IdentifierClaim = "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/emailaddress" ClaimsMappings = @( (New-CimInstance -ClassName MSFT_SPClaimTypeMapping -Property @{ - Name = "Email" - IncomingClaimType = "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/emailaddress" - } -ClientOnly) + Name = "Email" + IncomingClaimType = "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/emailaddress" + } -ClientOnly) (New-CimInstance -ClassName MSFT_SPClaimTypeMapping -Property @{ - Name = "Role" - IncomingClaimType = "http://schemas.xmlsoap.org/ExternalSTSGroupType" - LocalClaimType = "http://schemas.microsoft.com/ws/2008/06/identity/claims/role" - } -ClientOnly) + Name = "Role" + IncomingClaimType = "http://schemas.xmlsoap.org/ExternalSTSGroupType" + LocalClaimType = "http://schemas.microsoft.com/ws/2008/06/identity/claims/role" + } -ClientOnly) ) SigningCertificateThumbprint = "123ABCFACE123ABCFACE123ABCFACE123ABCFACE" ClaimProviderName = "LDAPCP" @@ -174,7 +174,7 @@ try } } - Context -Name "The SPTrustedLoginProvider does not exist but should, using a signing certificate in the file path" -Fixture { + Context -Name "The SAML SPTrustedLoginProvider does not exist but should, using a signing certificate in the file path" -Fixture { BeforeAll { $testParams = @{ Name = "Contoso" @@ -184,14 +184,14 @@ try IdentifierClaim = "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/emailaddress" ClaimsMappings = @( (New-CimInstance -ClassName MSFT_SPClaimTypeMapping -Property @{ - Name = "Email" - IncomingClaimType = "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/emailaddress" - } -ClientOnly) + Name = "Email" + IncomingClaimType = "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/emailaddress" + } -ClientOnly) (New-CimInstance -ClassName MSFT_SPClaimTypeMapping -Property @{ - Name = "Role" - IncomingClaimType = "http://schemas.xmlsoap.org/ExternalSTSGroupType" - LocalClaimType = "http://schemas.microsoft.com/ws/2008/06/identity/claims/role" - } -ClientOnly) + Name = "Role" + IncomingClaimType = "http://schemas.xmlsoap.org/ExternalSTSGroupType" + LocalClaimType = "http://schemas.microsoft.com/ws/2008/06/identity/claims/role" + } -ClientOnly) ) SigningCertificateFilePath = "F:\Data\DSC\FakeSigning.cer" ClaimProviderName = "LDAPCP" @@ -233,14 +233,14 @@ try IdentifierClaim = "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/emailaddress" ClaimsMappings = @( (New-CimInstance -ClassName MSFT_SPClaimTypeMapping -Property @{ - Name = "Email" - IncomingClaimType = "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/emailaddress" - } -ClientOnly) + Name = "Email" + IncomingClaimType = "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/emailaddress" + } -ClientOnly) (New-CimInstance -ClassName MSFT_SPClaimTypeMapping -Property @{ - Name = "Role" - IncomingClaimType = "http://schemas.xmlsoap.org/ExternalSTSGroupType" - LocalClaimType = "http://schemas.microsoft.com/ws/2008/06/identity/claims/role" - } -ClientOnly) + Name = "Role" + IncomingClaimType = "http://schemas.xmlsoap.org/ExternalSTSGroupType" + LocalClaimType = "http://schemas.microsoft.com/ws/2008/06/identity/claims/role" + } -ClientOnly) ) SigningCertificateThumbprint = "123ABCFACE123ABCFACE123ABCFACE123ABCFACE" SigningCertificateFilePath = "F:\Data\DSC\FakeSigning.cer" @@ -265,14 +265,14 @@ try IdentifierClaim = "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/emailaddress" ClaimsMappings = @( (New-CimInstance -ClassName MSFT_SPClaimTypeMapping -Property @{ - Name = "Email" - IncomingClaimType = "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/emailaddress" - } -ClientOnly) + Name = "Email" + IncomingClaimType = "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/emailaddress" + } -ClientOnly) (New-CimInstance -ClassName MSFT_SPClaimTypeMapping -Property @{ - Name = "Role" - IncomingClaimType = "http://schemas.xmlsoap.org/ExternalSTSGroupType" - LocalClaimType = "http://schemas.microsoft.com/ws/2008/06/identity/claims/role" - } -ClientOnly) + Name = "Role" + IncomingClaimType = "http://schemas.xmlsoap.org/ExternalSTSGroupType" + LocalClaimType = "http://schemas.microsoft.com/ws/2008/06/identity/claims/role" + } -ClientOnly) ) ClaimProviderName = "LDAPCP" ProviderSignOutUri = "https://adfs.contoso.com/adfs/ls/" @@ -295,14 +295,14 @@ try IdentifierClaim = "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/emailaddress" ClaimsMappings = @( (New-CimInstance -ClassName MSFT_SPClaimTypeMapping -Property @{ - Name = "Email" - IncomingClaimType = "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/emailaddress" - } -ClientOnly) + Name = "Email" + IncomingClaimType = "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/emailaddress" + } -ClientOnly) (New-CimInstance -ClassName MSFT_SPClaimTypeMapping -Property @{ - Name = "Role" - IncomingClaimType = "http://schemas.xmlsoap.org/ExternalSTSGroupType" - LocalClaimType = "http://schemas.microsoft.com/ws/2008/06/identity/claims/role" - } -ClientOnly) + Name = "Role" + IncomingClaimType = "http://schemas.xmlsoap.org/ExternalSTSGroupType" + LocalClaimType = "http://schemas.microsoft.com/ws/2008/06/identity/claims/role" + } -ClientOnly) ) SigningCertificateThumbprint = "XX123ABCFACEXX" ClaimProviderName = "LDAPCP" @@ -326,14 +326,14 @@ try IdentifierClaim = "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/emailaddress" ClaimsMappings = @( (New-CimInstance -ClassName MSFT_SPClaimTypeMapping -Property @{ - Name = "Email" - IncomingClaimType = "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/emailaddress" - } -ClientOnly) + Name = "Email" + IncomingClaimType = "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/emailaddress" + } -ClientOnly) (New-CimInstance -ClassName MSFT_SPClaimTypeMapping -Property @{ - Name = "Role" - IncomingClaimType = "http://schemas.xmlsoap.org/ExternalSTSGroupType" - LocalClaimType = "http://schemas.microsoft.com/ws/2008/06/identity/claims/role" - } -ClientOnly) + Name = "Role" + IncomingClaimType = "http://schemas.xmlsoap.org/ExternalSTSGroupType" + LocalClaimType = "http://schemas.microsoft.com/ws/2008/06/identity/claims/role" + } -ClientOnly) ) SigningCertificateThumbprint = "123ABCFACE123ABCFACE123ABCFACE123ABCFACE" ClaimProviderName = "LDAPCP" @@ -356,24 +356,147 @@ try } } - Context -Name "The SPTrustedLoginProvider does not exist but should, with a claims provider that exists on the farm" -Fixture { + Context -Name "A SAML SPTrustedLoginProvider is desired, but parameters for both OIDC and SAML trusts are set" -Fixture { BeforeAll { $testParams = @{ Name = "Contoso" Description = "Contoso" Realm = "https://sharepoint.contoso.com" + $DefaultClientIdentifier = "fae5bd07-be63-4a64-a28c-7931a4ebf62b" SignInUrl = "https://adfs.contoso.com/adfs/ls/" IdentifierClaim = "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/emailaddress" ClaimsMappings = @( (New-CimInstance -ClassName MSFT_SPClaimTypeMapping -Property @{ - Name = "Email" - IncomingClaimType = "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/emailaddress" - } -ClientOnly) + Name = "Email" + IncomingClaimType = "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/emailaddress" + } -ClientOnly) (New-CimInstance -ClassName MSFT_SPClaimTypeMapping -Property @{ - Name = "Role" - IncomingClaimType = "http://schemas.xmlsoap.org/ExternalSTSGroupType" - LocalClaimType = "http://schemas.microsoft.com/ws/2008/06/identity/claims/role" - } -ClientOnly) + Name = "Role" + IncomingClaimType = "http://schemas.xmlsoap.org/ExternalSTSGroupType" + LocalClaimType = "http://schemas.microsoft.com/ws/2008/06/identity/claims/role" + } -ClientOnly) + ) + SigningCertificateThumbprint = "123ABCFACE123ABCFACE123ABCFACE123ABCFACE" + ClaimProviderName = "LDAPCP" + ProviderSignOutUri = "https://adfs.contoso.com/adfs/ls/" + Ensure = "Present" + } + } + + It "should fail validation of certificate in the set method" { + { Set-TargetResource @testParams } | Should -Throw "Parameters Realm (for SAML trust) and DefaultClientIdentifier (for OIDC trust) cannot be both set." + } + } + + Context -Name "A SPTrustedLoginProvider is desired, but neither property Realm nor DefaultClientIdentifier set" -Fixture { + BeforeAll { + $testParams = @{ + Name = "Contoso" + Description = "Contoso" + IdentifierClaim = "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/emailaddress" + ClaimsMappings = @( + (New-CimInstance -ClassName MSFT_SPClaimTypeMapping -Property @{ + Name = "Email" + IncomingClaimType = "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/emailaddress" + } -ClientOnly) + (New-CimInstance -ClassName MSFT_SPClaimTypeMapping -Property @{ + Name = "Role" + IncomingClaimType = "http://schemas.xmlsoap.org/ExternalSTSGroupType" + LocalClaimType = "http://schemas.microsoft.com/ws/2008/06/identity/claims/role" + } -ClientOnly) + ) + SigningCertificateThumbprint = "123ABCFACE123ABCFACE123ABCFACE123ABCFACE" + ClaimProviderName = "LDAPCP" + ProviderSignOutUri = "https://adfs.contoso.com/adfs/ls/" + Ensure = "Present" + } + } + + It "should fail validation of certificate in the set method" { + { Set-TargetResource @testParams } | Should -Throw "At least one of the following parameters must be specified: " + ` + "Realm (for SAML trust), DefaultClientIdentifier (for OIDC trust)." + } + } + + Context -Name "A SAML SPTrustedLoginProvider is desired, but property SignInUrl is not set" -Fixture { + BeforeAll { + $testParams = @{ + Name = "Contoso" + Description = "Contoso" + Realm = "https://sharepoint.contoso.com" + IdentifierClaim = "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/emailaddress" + ClaimsMappings = @( + (New-CimInstance -ClassName MSFT_SPClaimTypeMapping -Property @{ + Name = "Email" + IncomingClaimType = "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/emailaddress" + } -ClientOnly) + (New-CimInstance -ClassName MSFT_SPClaimTypeMapping -Property @{ + Name = "Role" + IncomingClaimType = "http://schemas.xmlsoap.org/ExternalSTSGroupType" + LocalClaimType = "http://schemas.microsoft.com/ws/2008/06/identity/claims/role" + } -ClientOnly) + ) + SigningCertificateThumbprint = "123ABCFACE123ABCFACE123ABCFACE123ABCFACE" + ClaimProviderName = "LDAPCP" + ProviderSignOutUri = "https://adfs.contoso.com/adfs/ls/" + Ensure = "Present" + } + } + + It "should fail validation of certificate in the set method" { + { Set-TargetResource @testParams } | Should -Throw "Parameter Realm was set but SignInUrl is not set. Parameter SignInUrl required when Realm is set." + } + } + + Context -Name "A OIDC SPTrustedLoginProvider is desired, but not all required OIDC properties are set" -Fixture { + BeforeAll { + $testParams = @{ + Name = "Contoso" + Description = "Contoso" + $DefaultClientIdentifier = "fae5bd07-be63-4a64-a28c-7931a4ebf62b" + $SignOutUrl = "https://adfs.contoso.com/adfs/oauth2/logout" + IdentifierClaim = "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/emailaddress" + ClaimsMappings = @( + (New-CimInstance -ClassName MSFT_SPClaimTypeMapping -Property @{ + Name = "Email" + IncomingClaimType = "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/emailaddress" + } -ClientOnly) + (New-CimInstance -ClassName MSFT_SPClaimTypeMapping -Property @{ + Name = "Role" + IncomingClaimType = "http://schemas.xmlsoap.org/ExternalSTSGroupType" + LocalClaimType = "http://schemas.microsoft.com/ws/2008/06/identity/claims/role" + } -ClientOnly) + ) + SigningCertificateThumbprint = "123ABCFACE123ABCFACE123ABCFACE123ABCFACE" + ClaimProviderName = "LDAPCP" + Ensure = "Present" + } + } + + It "should fail validation of certificate in the set method" { + { Set-TargetResource @testParams } | Should -Throw "Parameter DefaultClientIdentifier was set but AuthorizationEndPointUri, RegisteredIssuerName or SignOutUrl are not set." + ` + "Parameters AuthorizationEndPointUri, RegisteredIssuerName, DefaultClientIdentifier and SignOutUrl are required when DefaultClientIdentifier is set" + } + } + + Context -Name "The SAML SPTrustedLoginProvider does not exist but should, with a claims provider that exists on the farm" -Fixture { + BeforeAll { + $testParams = @{ + Name = "Contoso" + Description = "Contoso" + Realm = "https://sharepoint.contoso.com" + SignInUrl = "https://adfs.contoso.com/adfs/ls/" + IdentifierClaim = "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/emailaddress" + ClaimsMappings = @( + (New-CimInstance -ClassName MSFT_SPClaimTypeMapping -Property @{ + Name = "Email" + IncomingClaimType = "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/emailaddress" + } -ClientOnly) + (New-CimInstance -ClassName MSFT_SPClaimTypeMapping -Property @{ + Name = "Role" + IncomingClaimType = "http://schemas.xmlsoap.org/ExternalSTSGroupType" + LocalClaimType = "http://schemas.microsoft.com/ws/2008/06/identity/claims/role" + } -ClientOnly) ) SigningCertificateThumbprint = "123ABCFACE123ABCFACE123ABCFACE123ABCFACE" ClaimProviderName = "LDAPCP" @@ -398,7 +521,49 @@ try } } - Context -Name "The SPTrustedLoginProvider already exists and should not be changed" -Fixture { + Context -Name "The OIDC SPTrustedLoginProvider does not exist but should, with a claims provider that exists on the farm" -Fixture { + BeforeAll { + $testParams = @{ + Name = "Contoso" + Description = "Contoso" + $DefaultClientIdentifier = "fae5bd07-be63-4a64-a28c-7931a4ebf62b" + $AuthorizationEndPointUri = "https://adfs.contoso.com/adfs/oauth2/authorize" + $SignOutUrl = "https://adfs.contoso.com/adfs/oauth2/logout" + IdentifierClaim = "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/emailaddress" + ClaimsMappings = @( + (New-CimInstance -ClassName MSFT_SPClaimTypeMapping -Property @{ + Name = "Email" + IncomingClaimType = "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/emailaddress" + } -ClientOnly) + (New-CimInstance -ClassName MSFT_SPClaimTypeMapping -Property @{ + Name = "Role" + IncomingClaimType = "http://schemas.xmlsoap.org/ExternalSTSGroupType" + LocalClaimType = "http://schemas.microsoft.com/ws/2008/06/identity/claims/role" + } -ClientOnly) + ) + SigningCertificateThumbprint = "123ABCFACE123ABCFACE123ABCFACE123ABCFACE" + ClaimProviderName = "LDAPCP" + Ensure = "Present" + } + + Mock -CommandName Get-SPTrustedIdentityTokenIssuer -MockWith { + $sptrust = [pscustomobject]@{ + Name = $testParams.Name + ClaimProviderName = $testParams.ClaimProviderName + } + $sptrust | Add-Member -Name Update -MemberType ScriptMethod -Value { } + return $sptrust + } + } + + It "Should create the SPTrustedLoginProvider with claims provider set" { + Set-TargetResource @testParams + $getResults = Get-TargetResource @testParams + $getResults.ClaimProviderName | Should -Be $testParams.ClaimProviderName + } + } + + Context -Name "The SAML SPTrustedLoginProvider already exists and should not be changed" -Fixture { BeforeAll { $testParams = @{ Name = "Contoso" @@ -408,14 +573,14 @@ try IdentifierClaim = "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/emailaddress" ClaimsMappings = @( (New-CimInstance -ClassName MSFT_SPClaimTypeMapping -Property @{ - Name = "Email" - IncomingClaimType = "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/emailaddress" - } -ClientOnly) + Name = "Email" + IncomingClaimType = "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/emailaddress" + } -ClientOnly) (New-CimInstance -ClassName MSFT_SPClaimTypeMapping -Property @{ - Name = "Role" - IncomingClaimType = "http://schemas.xmlsoap.org/ExternalSTSGroupType" - LocalClaimType = "http://schemas.microsoft.com/ws/2008/06/identity/claims/role" - } -ClientOnly) + Name = "Role" + IncomingClaimType = "http://schemas.xmlsoap.org/ExternalSTSGroupType" + LocalClaimType = "http://schemas.microsoft.com/ws/2008/06/identity/claims/role" + } -ClientOnly) ) SigningCertificateThumbprint = "123ABCFACE123ABCFACE123ABCFACE123ABCFACE" ClaimProviderName = "LDAPCP" @@ -442,24 +607,68 @@ try } } + Context -Name "The OIDC SPTrustedLoginProvider already exists and should not be changed" -Fixture { + BeforeAll { + $testParams = @{ + Name = "Contoso" + Description = "Contoso" + $DefaultClientIdentifier = "fae5bd07-be63-4a64-a28c-7931a4ebf62b" + $AuthorizationEndPointUri = "https://adfs.contoso.com/adfs/oauth2/authorize" + $SignOutUrl = "https://adfs.contoso.com/adfs/oauth2/logout" + IdentifierClaim = "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/emailaddress" + ClaimsMappings = @( + (New-CimInstance -ClassName MSFT_SPClaimTypeMapping -Property @{ + Name = "Email" + IncomingClaimType = "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/emailaddress" + } -ClientOnly) + (New-CimInstance -ClassName MSFT_SPClaimTypeMapping -Property @{ + Name = "Role" + IncomingClaimType = "http://schemas.xmlsoap.org/ExternalSTSGroupType" + LocalClaimType = "http://schemas.microsoft.com/ws/2008/06/identity/claims/role" + } -ClientOnly) + ) + SigningCertificateThumbprint = "123ABCFACE123ABCFACE123ABCFACE123ABCFACE" + ClaimProviderName = "LDAPCP" + Ensure = "Present" + } + + Mock -CommandName Get-SPTrustedIdentityTokenIssuer -MockWith { + $sptrust = [pscustomobject]@{ + Name = $testParams.Name + ClaimProviderName = $testParams.ClaimProviderName + } + return $sptrust + } + } + + It "Should return present from the get method" { + $getResults = Get-TargetResource @testParams + $getResults.Ensure | Should -Be "Present" + } + + It "Should return true from the test method" { + Test-TargetResource @testParams | Should -Be $true + } + } + Context -Name "The SPTrustedLoginProvider already exists but should be removed" -Fixture { BeforeAll { $testParams = @{ Name = "Contoso" Description = "Contoso" - Realm = "https://sharepoint.contoso.com" - SignInUrl = "https://adfs.contoso.com/adfs/ls/" + # Realm = "https://sharepoint.contoso.com" + # SignInUrl = "https://adfs.contoso.com/adfs/ls/" IdentifierClaim = "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/emailaddress" ClaimsMappings = @( (New-CimInstance -ClassName MSFT_SPClaimTypeMapping -Property @{ - Name = "Email" - IncomingClaimType = "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/emailaddress" - } -ClientOnly) + Name = "Email" + IncomingClaimType = "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/emailaddress" + } -ClientOnly) (New-CimInstance -ClassName MSFT_SPClaimTypeMapping -Property @{ - Name = "Role" - IncomingClaimType = "http://schemas.xmlsoap.org/ExternalSTSGroupType" - LocalClaimType = "http://schemas.microsoft.com/ws/2008/06/identity/claims/role" - } -ClientOnly) + Name = "Role" + IncomingClaimType = "http://schemas.xmlsoap.org/ExternalSTSGroupType" + LocalClaimType = "http://schemas.microsoft.com/ws/2008/06/identity/claims/role" + } -ClientOnly) ) SigningCertificateThumbprint = "123ABCFACE123ABCFACE123ABCFACE123ABCFACE" ClaimProviderName = "LDAPCP" @@ -516,7 +725,7 @@ try } } - Context -Name "The SPTrustedLoginProvider is desired, but the IdentifierClaim parameter does not match a claim type in ClaimsMappings" -Fixture { + Context -Name "The SAML SPTrustedLoginProvider is desired, but the IdentifierClaim parameter does not match a claim type in ClaimsMappings" -Fixture { BeforeAll { $testParams = @{ Name = "Contoso" @@ -526,14 +735,14 @@ try IdentifierClaim = "IdentityClaimTypeNotSpecifiedInClaimsMappings" ClaimsMappings = @( (New-CimInstance -ClassName MSFT_SPClaimTypeMapping -Property @{ - Name = "Email" - IncomingClaimType = "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/emailaddress" - } -ClientOnly) + Name = "Email" + IncomingClaimType = "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/emailaddress" + } -ClientOnly) (New-CimInstance -ClassName MSFT_SPClaimTypeMapping -Property @{ - Name = "Role" - IncomingClaimType = "http://schemas.xmlsoap.org/ExternalSTSGroupType" - LocalClaimType = "http://schemas.microsoft.com/ws/2008/06/identity/claims/role" - } -ClientOnly) + Name = "Role" + IncomingClaimType = "http://schemas.xmlsoap.org/ExternalSTSGroupType" + LocalClaimType = "http://schemas.microsoft.com/ws/2008/06/identity/claims/role" + } -ClientOnly) ) SigningCertificateThumbprint = "123ABCFACE123ABCFACE123ABCFACE123ABCFACE" ClaimProviderName = "LDAPCP" @@ -553,6 +762,43 @@ try } } + Context -Name "The OIDC SPTrustedLoginProvider is desired, but the IdentifierClaim parameter does not match a claim type in ClaimsMappings" -Fixture { + BeforeAll { + $testParams = @{ + Name = "Contoso" + Description = "Contoso" + $DefaultClientIdentifier = "fae5bd07-be63-4a64-a28c-7931a4ebf62b" + $AuthorizationEndPointUri = "https://adfs.contoso.com/adfs/oauth2/authorize" + $SignOutUrl = "https://adfs.contoso.com/adfs/oauth2/logout" + IdentifierClaim = "IdentityClaimTypeNotSpecifiedInClaimsMappings" + ClaimsMappings = @( + (New-CimInstance -ClassName MSFT_SPClaimTypeMapping -Property @{ + Name = "Email" + IncomingClaimType = "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/emailaddress" + } -ClientOnly) + (New-CimInstance -ClassName MSFT_SPClaimTypeMapping -Property @{ + Name = "Role" + IncomingClaimType = "http://schemas.xmlsoap.org/ExternalSTSGroupType" + LocalClaimType = "http://schemas.microsoft.com/ws/2008/06/identity/claims/role" + } -ClientOnly) + ) + SigningCertificateThumbprint = "123ABCFACE123ABCFACE123ABCFACE123ABCFACE" + ClaimProviderName = "LDAPCP" + Ensure = "Present" + } + + Mock -CommandName New-SPClaimTypeMapping -MockWith { + return [pscustomobject]@{ + InputClaimType = "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/emailaddress" + } + } + } + + It "should fail validation of IdentifierClaim in the set method" { + { Set-TargetResource @testParams } | Should -Throw "IdentifierClaim does not match any claim type specified in ClaimsMappings." + } + } + Context -Name "Running ReverseDsc Export" -Fixture { BeforeAll { Import-Module (Join-Path -Path (Split-Path -Path (Get-Module SharePointDsc -ListAvailable).Path -Parent) -ChildPath "Modules\SharePointDSC.Reverse\SharePointDSC.Reverse.psm1") From 1a3811b79c3677c8960ad942bd4ddccce9276166 Mon Sep 17 00:00:00 2001 From: Yvan Duhamel Date: Wed, 5 Jan 2022 13:23:53 +0100 Subject: [PATCH 08/19] fix typos --- ...Dsc.SPTrustedIdentityTokenIssuer.Tests.ps1 | 32 +++++++++---------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/tests/Unit/SharePointDsc/SharePointDsc.SPTrustedIdentityTokenIssuer.Tests.ps1 b/tests/Unit/SharePointDsc/SharePointDsc.SPTrustedIdentityTokenIssuer.Tests.ps1 index c66ab1bcb..1440bf26d 100644 --- a/tests/Unit/SharePointDsc/SharePointDsc.SPTrustedIdentityTokenIssuer.Tests.ps1 +++ b/tests/Unit/SharePointDsc/SharePointDsc.SPTrustedIdentityTokenIssuer.Tests.ps1 @@ -362,7 +362,7 @@ try Name = "Contoso" Description = "Contoso" Realm = "https://sharepoint.contoso.com" - $DefaultClientIdentifier = "fae5bd07-be63-4a64-a28c-7931a4ebf62b" + DefaultClientIdentifier = "fae5bd07-be63-4a64-a28c-7931a4ebf62b" SignInUrl = "https://adfs.contoso.com/adfs/ls/" IdentifierClaim = "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/emailaddress" ClaimsMappings = @( @@ -383,7 +383,7 @@ try } } - It "should fail validation of certificate in the set method" { + It "should fail validation of parameters" { { Set-TargetResource @testParams } | Should -Throw "Parameters Realm (for SAML trust) and DefaultClientIdentifier (for OIDC trust) cannot be both set." } } @@ -412,7 +412,7 @@ try } } - It "should fail validation of certificate in the set method" { + It "should fail validation of parameters" { { Set-TargetResource @testParams } | Should -Throw "At least one of the following parameters must be specified: " + ` "Realm (for SAML trust), DefaultClientIdentifier (for OIDC trust)." } @@ -443,7 +443,7 @@ try } } - It "should fail validation of certificate in the set method" { + It "should fail validation of parameters" { { Set-TargetResource @testParams } | Should -Throw "Parameter Realm was set but SignInUrl is not set. Parameter SignInUrl required when Realm is set." } } @@ -453,8 +453,8 @@ try $testParams = @{ Name = "Contoso" Description = "Contoso" - $DefaultClientIdentifier = "fae5bd07-be63-4a64-a28c-7931a4ebf62b" - $SignOutUrl = "https://adfs.contoso.com/adfs/oauth2/logout" + DefaultClientIdentifier = "fae5bd07-be63-4a64-a28c-7931a4ebf62b" + SignOutUrl = "https://adfs.contoso.com/adfs/oauth2/logout" IdentifierClaim = "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/emailaddress" ClaimsMappings = @( (New-CimInstance -ClassName MSFT_SPClaimTypeMapping -Property @{ @@ -473,7 +473,7 @@ try } } - It "should fail validation of certificate in the set method" { + It "should fail validation of parameters" { { Set-TargetResource @testParams } | Should -Throw "Parameter DefaultClientIdentifier was set but AuthorizationEndPointUri, RegisteredIssuerName or SignOutUrl are not set." + ` "Parameters AuthorizationEndPointUri, RegisteredIssuerName, DefaultClientIdentifier and SignOutUrl are required when DefaultClientIdentifier is set" } @@ -526,9 +526,9 @@ try $testParams = @{ Name = "Contoso" Description = "Contoso" - $DefaultClientIdentifier = "fae5bd07-be63-4a64-a28c-7931a4ebf62b" - $AuthorizationEndPointUri = "https://adfs.contoso.com/adfs/oauth2/authorize" - $SignOutUrl = "https://adfs.contoso.com/adfs/oauth2/logout" + DefaultClientIdentifier = "fae5bd07-be63-4a64-a28c-7931a4ebf62b" + AuthorizationEndPointUri = "https://adfs.contoso.com/adfs/oauth2/authorize" + SignOutUrl = "https://adfs.contoso.com/adfs/oauth2/logout" IdentifierClaim = "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/emailaddress" ClaimsMappings = @( (New-CimInstance -ClassName MSFT_SPClaimTypeMapping -Property @{ @@ -612,9 +612,9 @@ try $testParams = @{ Name = "Contoso" Description = "Contoso" - $DefaultClientIdentifier = "fae5bd07-be63-4a64-a28c-7931a4ebf62b" - $AuthorizationEndPointUri = "https://adfs.contoso.com/adfs/oauth2/authorize" - $SignOutUrl = "https://adfs.contoso.com/adfs/oauth2/logout" + DefaultClientIdentifier = "fae5bd07-be63-4a64-a28c-7931a4ebf62b" + AuthorizationEndPointUri = "https://adfs.contoso.com/adfs/oauth2/authorize" + SignOutUrl = "https://adfs.contoso.com/adfs/oauth2/logout" IdentifierClaim = "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/emailaddress" ClaimsMappings = @( (New-CimInstance -ClassName MSFT_SPClaimTypeMapping -Property @{ @@ -767,9 +767,9 @@ try $testParams = @{ Name = "Contoso" Description = "Contoso" - $DefaultClientIdentifier = "fae5bd07-be63-4a64-a28c-7931a4ebf62b" - $AuthorizationEndPointUri = "https://adfs.contoso.com/adfs/oauth2/authorize" - $SignOutUrl = "https://adfs.contoso.com/adfs/oauth2/logout" + DefaultClientIdentifier = "fae5bd07-be63-4a64-a28c-7931a4ebf62b" + AuthorizationEndPointUri = "https://adfs.contoso.com/adfs/oauth2/authorize" + SignOutUrl = "https://adfs.contoso.com/adfs/oauth2/logout" IdentifierClaim = "IdentityClaimTypeNotSpecifiedInClaimsMappings" ClaimsMappings = @( (New-CimInstance -ClassName MSFT_SPClaimTypeMapping -Property @{ From f3d77163e94530e8b076ef008c1dfe6878af9011 Mon Sep 17 00:00:00 2001 From: Yvan Duhamel Date: Wed, 5 Jan 2022 16:13:43 +0100 Subject: [PATCH 09/19] Update SharePointDsc.SPTrustedIdentityTokenIssuer.Tests.ps1 --- .../SharePointDsc.SPTrustedIdentityTokenIssuer.Tests.ps1 | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/tests/Unit/SharePointDsc/SharePointDsc.SPTrustedIdentityTokenIssuer.Tests.ps1 b/tests/Unit/SharePointDsc/SharePointDsc.SPTrustedIdentityTokenIssuer.Tests.ps1 index 1440bf26d..ed31a16e3 100644 --- a/tests/Unit/SharePointDsc/SharePointDsc.SPTrustedIdentityTokenIssuer.Tests.ps1 +++ b/tests/Unit/SharePointDsc/SharePointDsc.SPTrustedIdentityTokenIssuer.Tests.ps1 @@ -527,6 +527,7 @@ try Name = "Contoso" Description = "Contoso" DefaultClientIdentifier = "fae5bd07-be63-4a64-a28c-7931a4ebf62b" + RegisteredIssuerName = "https://adfs.contoso.com/adfs" AuthorizationEndPointUri = "https://adfs.contoso.com/adfs/oauth2/authorize" SignOutUrl = "https://adfs.contoso.com/adfs/oauth2/logout" IdentifierClaim = "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/emailaddress" @@ -613,6 +614,7 @@ try Name = "Contoso" Description = "Contoso" DefaultClientIdentifier = "fae5bd07-be63-4a64-a28c-7931a4ebf62b" + RegisteredIssuerName = "https://adfs.contoso.com/adfs" AuthorizationEndPointUri = "https://adfs.contoso.com/adfs/oauth2/authorize" SignOutUrl = "https://adfs.contoso.com/adfs/oauth2/logout" IdentifierClaim = "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/emailaddress" @@ -651,13 +653,13 @@ try } } - Context -Name "The SPTrustedLoginProvider already exists but should be removed" -Fixture { + Context -Name "The SAML SPTrustedLoginProvider already exists but should be removed" -Fixture { BeforeAll { $testParams = @{ Name = "Contoso" Description = "Contoso" - # Realm = "https://sharepoint.contoso.com" - # SignInUrl = "https://adfs.contoso.com/adfs/ls/" + Realm = "https://sharepoint.contoso.com" + SignInUrl = "https://adfs.contoso.com/adfs/ls/" IdentifierClaim = "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/emailaddress" ClaimsMappings = @( (New-CimInstance -ClassName MSFT_SPClaimTypeMapping -Property @{ @@ -768,6 +770,7 @@ try Name = "Contoso" Description = "Contoso" DefaultClientIdentifier = "fae5bd07-be63-4a64-a28c-7931a4ebf62b" + RegisteredIssuerName = "https://adfs.contoso.com/adfs" AuthorizationEndPointUri = "https://adfs.contoso.com/adfs/oauth2/authorize" SignOutUrl = "https://adfs.contoso.com/adfs/oauth2/logout" IdentifierClaim = "IdentityClaimTypeNotSpecifiedInClaimsMappings" From 819f54d0ae399bc2e268f245e7e47fe51a1b1dc6 Mon Sep 17 00:00:00 2001 From: Yvan Duhamel Date: Wed, 5 Jan 2022 17:30:00 +0100 Subject: [PATCH 10/19] Ensure that OIDC parameters are used with SharePoint Subscription --- .../MSFT_SPTrustedIdentityTokenIssuer.psm1 | 76 +++++++++++++------ 1 file changed, 51 insertions(+), 25 deletions(-) diff --git a/SharePointDsc/DSCResources/MSFT_SPTrustedIdentityTokenIssuer/MSFT_SPTrustedIdentityTokenIssuer.psm1 b/SharePointDsc/DSCResources/MSFT_SPTrustedIdentityTokenIssuer/MSFT_SPTrustedIdentityTokenIssuer.psm1 index 9364dab1c..dec2c56ac 100644 --- a/SharePointDsc/DSCResources/MSFT_SPTrustedIdentityTokenIssuer/MSFT_SPTrustedIdentityTokenIssuer.psm1 +++ b/SharePointDsc/DSCResources/MSFT_SPTrustedIdentityTokenIssuer/MSFT_SPTrustedIdentityTokenIssuer.psm1 @@ -239,7 +239,7 @@ function Set-TargetResource { if ($CurrentValues.Ensure -eq "Absent") { - if ($true -eq $PSBoundParameters.ContainsKey("SigningCertificateThumbprint") -and + if ($true -eq $PSBoundParameters.ContainsKey("SigningCertificateThumbprint") -and $true -eq $PSBoundParameters.ContainsKey("SigningCertificateFilePath")) { $message = ("Cannot use both parameters SigningCertificateThumbprint and SigningCertificateFilePath at the same time.") @@ -250,7 +250,7 @@ function Set-TargetResource throw $message } - if ($false -eq $PSBoundParameters.ContainsKey("SigningCertificateThumbprint") -and + if ($false -eq $PSBoundParameters.ContainsKey("SigningCertificateThumbprint") -and $false -eq $PSBoundParameters.ContainsKey("SigningCertificateFilePath")) { $message = ("At least one of the following parameters must be specified: " + ` @@ -263,7 +263,7 @@ function Set-TargetResource } # Ensure that at least one parameter is specified between Realm (SAML trust) or DefaultClientIdentifier (OIDC trust) - if ($false -eq $PSBoundParameters.ContainsKey("Realm") -and + if ($false -eq $PSBoundParameters.ContainsKey("Realm") -and $false -eq $PSBoundParameters.ContainsKey("DefaultClientIdentifier")) { $message = ("At least one of the following parameters must be specified: " + ` @@ -276,7 +276,7 @@ function Set-TargetResource } # Ensure that parameters Realm (SAML trust) or DefaultClientIdentifier (OIDC trust) are not both set - if ($true -eq $PSBoundParameters.ContainsKey("Realm") -and + if ($true -eq $PSBoundParameters.ContainsKey("Realm") -and $true -eq $PSBoundParameters.ContainsKey("DefaultClientIdentifier")) { $message = ("Parameters Realm (for SAML trust) and DefaultClientIdentifier (for OIDC trust) cannot be both set.") @@ -288,7 +288,7 @@ function Set-TargetResource } # SAML trust: If parameter Realm is set, then parameter SignInUrl is required - if ($true -eq $PSBoundParameters.ContainsKey("Realm") -and + if ($true -eq $PSBoundParameters.ContainsKey("Realm") -and $false -eq $PSBoundParameters.ContainsKey("SignInUrl")) { $message = ("Parameter Realm was set but SignInUrl is not set. Parameter SignInUrl required when Realm is set.") @@ -299,16 +299,28 @@ function Set-TargetResource throw $message } - # OIDC trust: If parameter DefaultClientIdentifier is set, + # OIDC trust: If parameter DefaultClientIdentifier is set, # then parameters AuthorizationEndPointUri, RegisteredIssuerName and SignOutUrl are required if ($true -eq $PSBoundParameters.ContainsKey("DefaultClientIdentifier") -and ( - $false -eq $PSBoundParameters.ContainsKey("AuthorizationEndPointUri") -or - $false -eq $PSBoundParameters.ContainsKey("RegisteredIssuerName") -or - $false -eq $PSBoundParameters.ContainsKey("SignOutUrl") )) + $false -eq $PSBoundParameters.ContainsKey("AuthorizationEndPointUri") -or + $false -eq $PSBoundParameters.ContainsKey("RegisteredIssuerName") -or + $false -eq $PSBoundParameters.ContainsKey("SignOutUrl") )) { $message = ("Parameter DefaultClientIdentifier was set but AuthorizationEndPointUri, RegisteredIssuerName or SignOutUrl are not set." + ` - "Parameters AuthorizationEndPointUri, RegisteredIssuerName, DefaultClientIdentifier and SignOutUrl are required when DefaultClientIdentifier is set") - Add-SPDscEvent -Message $message ` + "Parameters AuthorizationEndPointUri, RegisteredIssuerName, DefaultClientIdentifier and SignOutUrl are required when DefaultClientIdentifier is set") + Add-SPDscEvent -Message $message ` + -EntryType 'Error' ` + -EventID 100 ` + -Source $MyInvocation.MyCommand.Source + throw $message + } + + $productVersion = Get-SPDscInstalledProductVersion + if ($true -eq $PSBoundParameters.ContainsKey("DefaultClientIdentifier") -and + $productVersion.FileMajorPart -eq 16 -and $productVersion.FileBuildPart -gt 13000) + { + $message = ("OIDC parameters can only be used with SharePoint Server Subscription Edition.") + Add-SPDscEvent -Message $message ` -EntryType 'Error' ` -EventID 100 ` -Source $MyInvocation.MyCommand.Source @@ -430,12 +442,14 @@ function Set-TargetResource $runParams.Add("AuthorizationEndPointUri", $params.AuthorizationEndPointUri) $runParams.Add("DefaultClientIdentifier", $params.DefaultClientIdentifier) $runParams.Add("SignOutUrl", $params.SignOutUrl) - } else { + } + else + { $runParams.Add("Realm", $params.Realm) $runParams.Add("SignInUrl", $params.SignInUrl) $runParams.Add("UseWReply", $params.UseWReplyParameter) - } - + } + $runParams.Add("IdentifierClaim", $params.IdentifierClaim) $runParams.Add("ClaimsMappings", $claimsMappingsArray) $trust = New-SPTrustedIdentityTokenIssuer @runParams @@ -605,7 +619,7 @@ function Test-TargetResource Write-Verbose -Message "Testing SPTrustedIdentityTokenIssuer '$Name' settings" - if ($true -eq $PSBoundParameters.ContainsKey("SigningCertificateThumbprint") -and + if ($true -eq $PSBoundParameters.ContainsKey("SigningCertificateThumbprint") -and $true -eq $PSBoundParameters.ContainsKey("SigningCertificateFilePath")) { $message = ("Cannot use both parameters SigningCertificateThumbprint and SigningCertificateFilePath at the same time.") @@ -616,7 +630,7 @@ function Test-TargetResource throw $message } - if ($false -eq $PSBoundParameters.ContainsKey("SigningCertificateThumbprint") -and + if ($false -eq $PSBoundParameters.ContainsKey("SigningCertificateThumbprint") -and $false -eq $PSBoundParameters.ContainsKey("SigningCertificateFilePath")) { $message = ("At least one of the following parameters must be specified: " + ` @@ -629,7 +643,7 @@ function Test-TargetResource } # Ensure that at least one parameter is specified between Realm (SAML trust) or DefaultClientIdentifier (OIDC trust) - if ($false -eq $PSBoundParameters.ContainsKey("Realm") -and + if ($false -eq $PSBoundParameters.ContainsKey("Realm") -and $false -eq $PSBoundParameters.ContainsKey("DefaultClientIdentifier")) { $message = ("At least one of the following parameters must be specified: " + ` @@ -642,7 +656,7 @@ function Test-TargetResource } # Ensure that parameters Realm (SAML trust) or DefaultClientIdentifier (OIDC trust) are not both set - if ($true -eq $PSBoundParameters.ContainsKey("Realm") -and + if ($true -eq $PSBoundParameters.ContainsKey("Realm") -and $true -eq $PSBoundParameters.ContainsKey("DefaultClientIdentifier")) { $message = ("Parameters Realm (for SAML trust) and DefaultClientIdentifier (for OIDC trust) cannot be both set.") @@ -654,7 +668,7 @@ function Test-TargetResource } # SAML trust: If parameter Realm is set, then parameter SignInUrl is required - if ($true -eq $PSBoundParameters.ContainsKey("Realm") -and + if ($true -eq $PSBoundParameters.ContainsKey("Realm") -and $false -eq $PSBoundParameters.ContainsKey("SignInUrl")) { $message = ("Parameter Realm was set but SignInUrl is not set. Parameter SignInUrl required when Realm is set.") @@ -665,16 +679,28 @@ function Test-TargetResource throw $message } - # OIDC trust: If parameter DefaultClientIdentifier is set, + # OIDC trust: If parameter DefaultClientIdentifier is set, # then parameters AuthorizationEndPointUri, RegisteredIssuerName and SignOutUrl are required if ($true -eq $PSBoundParameters.ContainsKey("DefaultClientIdentifier") -and ( - $false -eq $PSBoundParameters.ContainsKey("AuthorizationEndPointUri") -or - $false -eq $PSBoundParameters.ContainsKey("RegisteredIssuerName") -or - $false -eq $PSBoundParameters.ContainsKey("SignOutUrl") )) + $false -eq $PSBoundParameters.ContainsKey("AuthorizationEndPointUri") -or + $false -eq $PSBoundParameters.ContainsKey("RegisteredIssuerName") -or + $false -eq $PSBoundParameters.ContainsKey("SignOutUrl") )) { $message = ("Parameter DefaultClientIdentifier was set but AuthorizationEndPointUri, RegisteredIssuerName or SignOutUrl are not set." + ` - "Parameters AuthorizationEndPointUri, RegisteredIssuerName, DefaultClientIdentifier and SignOutUrl are required when DefaultClientIdentifier is set") - Add-SPDscEvent -Message $message ` + "Parameters AuthorizationEndPointUri, RegisteredIssuerName, DefaultClientIdentifier and SignOutUrl are required when DefaultClientIdentifier is set") + Add-SPDscEvent -Message $message ` + -EntryType 'Error' ` + -EventID 100 ` + -Source $MyInvocation.MyCommand.Source + throw $message + } + + $productVersion = Get-SPDscInstalledProductVersion + if ($true -eq $PSBoundParameters.ContainsKey("DefaultClientIdentifier") -and + $productVersion.FileMajorPart -eq 16 -and $productVersion.FileBuildPart -gt 13000) + { + $message = ("OIDC parameters can only be used with SharePoint Server Subscription Edition.") + Add-SPDscEvent -Message $message ` -EntryType 'Error' ` -EventID 100 ` -Source $MyInvocation.MyCommand.Source From 585d789ba07b827500a3b3afc3c06146be8f96f8 Mon Sep 17 00:00:00 2001 From: Yvan Duhamel Date: Wed, 5 Jan 2022 17:42:24 +0100 Subject: [PATCH 11/19] fix test for SharePoint Subscription --- .../MSFT_SPTrustedIdentityTokenIssuer.psm1 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/SharePointDsc/DSCResources/MSFT_SPTrustedIdentityTokenIssuer/MSFT_SPTrustedIdentityTokenIssuer.psm1 b/SharePointDsc/DSCResources/MSFT_SPTrustedIdentityTokenIssuer/MSFT_SPTrustedIdentityTokenIssuer.psm1 index dec2c56ac..b976d9dbe 100644 --- a/SharePointDsc/DSCResources/MSFT_SPTrustedIdentityTokenIssuer/MSFT_SPTrustedIdentityTokenIssuer.psm1 +++ b/SharePointDsc/DSCResources/MSFT_SPTrustedIdentityTokenIssuer/MSFT_SPTrustedIdentityTokenIssuer.psm1 @@ -697,7 +697,7 @@ function Test-TargetResource $productVersion = Get-SPDscInstalledProductVersion if ($true -eq $PSBoundParameters.ContainsKey("DefaultClientIdentifier") -and - $productVersion.FileMajorPart -eq 16 -and $productVersion.FileBuildPart -gt 13000) + ($productVersion.FileMajorPart -ne 16 -or $productVersion.FileBuildPart -le 13000)) { $message = ("OIDC parameters can only be used with SharePoint Server Subscription Edition.") Add-SPDscEvent -Message $message ` From 103f8c14e4e6acf567c3b0ce9dbbe7769442b07f Mon Sep 17 00:00:00 2001 From: Yvan Duhamel Date: Wed, 5 Jan 2022 17:43:36 +0100 Subject: [PATCH 12/19] fix test for SharePoint Subscription --- .../MSFT_SPTrustedIdentityTokenIssuer.psm1 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/SharePointDsc/DSCResources/MSFT_SPTrustedIdentityTokenIssuer/MSFT_SPTrustedIdentityTokenIssuer.psm1 b/SharePointDsc/DSCResources/MSFT_SPTrustedIdentityTokenIssuer/MSFT_SPTrustedIdentityTokenIssuer.psm1 index b976d9dbe..97b897b66 100644 --- a/SharePointDsc/DSCResources/MSFT_SPTrustedIdentityTokenIssuer/MSFT_SPTrustedIdentityTokenIssuer.psm1 +++ b/SharePointDsc/DSCResources/MSFT_SPTrustedIdentityTokenIssuer/MSFT_SPTrustedIdentityTokenIssuer.psm1 @@ -317,7 +317,7 @@ function Set-TargetResource $productVersion = Get-SPDscInstalledProductVersion if ($true -eq $PSBoundParameters.ContainsKey("DefaultClientIdentifier") -and - $productVersion.FileMajorPart -eq 16 -and $productVersion.FileBuildPart -gt 13000) + ($productVersion.FileMajorPart -ne 16 -or $productVersion.FileBuildPart -le 13000)) { $message = ("OIDC parameters can only be used with SharePoint Server Subscription Edition.") Add-SPDscEvent -Message $message ` From 9f4c8704482d2f6f69d022509d3864ad6e94d81d Mon Sep 17 00:00:00 2001 From: Yvan Duhamel Date: Thu, 6 Jan 2022 08:34:51 +0100 Subject: [PATCH 13/19] fix null ref in pester tests --- .../MSFT_SPTrustedIdentityTokenIssuer.psm1 | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/SharePointDsc/DSCResources/MSFT_SPTrustedIdentityTokenIssuer/MSFT_SPTrustedIdentityTokenIssuer.psm1 b/SharePointDsc/DSCResources/MSFT_SPTrustedIdentityTokenIssuer/MSFT_SPTrustedIdentityTokenIssuer.psm1 index 97b897b66..0a7354d00 100644 --- a/SharePointDsc/DSCResources/MSFT_SPTrustedIdentityTokenIssuer/MSFT_SPTrustedIdentityTokenIssuer.psm1 +++ b/SharePointDsc/DSCResources/MSFT_SPTrustedIdentityTokenIssuer/MSFT_SPTrustedIdentityTokenIssuer.psm1 @@ -91,7 +91,7 @@ function Get-TargetResource $realm = $spTrust.DefaultProviderRealm $signInUrl = $spTrust.ProviderUri.OriginalString $registeredIssuerName = $spTrust.RegisteredIssuerName - if ($false -eq [String]::IsNullOrWhiteSpace($params.AuthorizationEndPointUri)) + if ($false -eq [String]::IsNullOrWhiteSpace($spTrust.AuthorizationEndPointUri)) { $authorizationEndPointUri = $spTrust.AuthorizationEndPointUri.ToString() } @@ -101,7 +101,7 @@ function Get-TargetResource $SigningCertificateThumbprint = $spTrust.SigningCertificate.Thumbprint $currentState = "Present" $claimProviderName = $sptrust.ClaimProviderName - if ($false -eq [String]::IsNullOrWhiteSpace($params.ProviderSignOutUri)) + if ($false -eq [String]::IsNullOrWhiteSpace($spTrust.ProviderSignOutUri)) { $providerSignOutUri = $sptrust.ProviderSignOutUri.OriginalString } From 03d45357524fcbdca2d861e3c2f2dac642b6fb1e Mon Sep 17 00:00:00 2001 From: Yvan Duhamel Date: Thu, 6 Jan 2022 11:44:02 +0100 Subject: [PATCH 14/19] run OIDC tests in SharePoint Subscription only --- ...Dsc.SPTrustedIdentityTokenIssuer.Tests.ps1 | 210 +++++++++--------- 1 file changed, 111 insertions(+), 99 deletions(-) diff --git a/tests/Unit/SharePointDsc/SharePointDsc.SPTrustedIdentityTokenIssuer.Tests.ps1 b/tests/Unit/SharePointDsc/SharePointDsc.SPTrustedIdentityTokenIssuer.Tests.ps1 index ed31a16e3..1d44a0895 100644 --- a/tests/Unit/SharePointDsc/SharePointDsc.SPTrustedIdentityTokenIssuer.Tests.ps1 +++ b/tests/Unit/SharePointDsc/SharePointDsc.SPTrustedIdentityTokenIssuer.Tests.ps1 @@ -50,7 +50,7 @@ try InModuleScope -ModuleName $script:DSCResourceFullName -ScriptBlock { Describe -Name $Global:SPDscHelper.DescribeHeader -Fixture { BeforeAll { - Invoke-Command -ScriptBlock $Global:SPDscHelper.InitializeScript -NoNewScope + Invoke-Command -Scriptblock $Global:SPDscHelper.InitializeScript -NoNewScope # Mocks for all contexts Mock -CommandName Get-ChildItem -MockWith { @@ -521,46 +521,50 @@ try } } - Context -Name "The OIDC SPTrustedLoginProvider does not exist but should, with a claims provider that exists on the farm" -Fixture { - BeforeAll { - $testParams = @{ - Name = "Contoso" - Description = "Contoso" - DefaultClientIdentifier = "fae5bd07-be63-4a64-a28c-7931a4ebf62b" - RegisteredIssuerName = "https://adfs.contoso.com/adfs" - AuthorizationEndPointUri = "https://adfs.contoso.com/adfs/oauth2/authorize" - SignOutUrl = "https://adfs.contoso.com/adfs/oauth2/logout" - IdentifierClaim = "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/emailaddress" - ClaimsMappings = @( + if ($Global:SPDscHelper.CurrentStubBuildNumber.Major -eq 16 -and + $Global:SPDscHelper.CurrentStubBuildNumber.Build -gt 13000) + { + Context -Name "The OIDC SPTrustedLoginProvider does not exist but should, with a claims provider that exists on the farm" -Fixture { + BeforeAll { + $testParams = @{ + Name = "Contoso" + Description = "Contoso" + DefaultClientIdentifier = "fae5bd07-be63-4a64-a28c-7931a4ebf62b" + RegisteredIssuerName = "https://adfs.contoso.com/adfs" + AuthorizationEndPointUri = "https://adfs.contoso.com/adfs/oauth2/authorize" + SignOutUrl = "https://adfs.contoso.com/adfs/oauth2/logout" + IdentifierClaim = "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/emailaddress" + ClaimsMappings = @( (New-CimInstance -ClassName MSFT_SPClaimTypeMapping -Property @{ - Name = "Email" - IncomingClaimType = "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/emailaddress" - } -ClientOnly) + Name = "Email" + IncomingClaimType = "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/emailaddress" + } -ClientOnly) (New-CimInstance -ClassName MSFT_SPClaimTypeMapping -Property @{ - Name = "Role" - IncomingClaimType = "http://schemas.xmlsoap.org/ExternalSTSGroupType" - LocalClaimType = "http://schemas.microsoft.com/ws/2008/06/identity/claims/role" - } -ClientOnly) - ) - SigningCertificateThumbprint = "123ABCFACE123ABCFACE123ABCFACE123ABCFACE" - ClaimProviderName = "LDAPCP" - Ensure = "Present" - } + Name = "Role" + IncomingClaimType = "http://schemas.xmlsoap.org/ExternalSTSGroupType" + LocalClaimType = "http://schemas.microsoft.com/ws/2008/06/identity/claims/role" + } -ClientOnly) + ) + SigningCertificateThumbprint = "123ABCFACE123ABCFACE123ABCFACE123ABCFACE" + ClaimProviderName = "LDAPCP" + Ensure = "Present" + } - Mock -CommandName Get-SPTrustedIdentityTokenIssuer -MockWith { - $sptrust = [pscustomobject]@{ - Name = $testParams.Name - ClaimProviderName = $testParams.ClaimProviderName + Mock -CommandName Get-SPTrustedIdentityTokenIssuer -MockWith { + $sptrust = [pscustomobject]@{ + Name = $testParams.Name + ClaimProviderName = $testParams.ClaimProviderName + } + $sptrust | Add-Member -Name Update -MemberType ScriptMethod -Value { } + return $sptrust } - $sptrust | Add-Member -Name Update -MemberType ScriptMethod -Value { } - return $sptrust } - } - It "Should create the SPTrustedLoginProvider with claims provider set" { - Set-TargetResource @testParams - $getResults = Get-TargetResource @testParams - $getResults.ClaimProviderName | Should -Be $testParams.ClaimProviderName + It "Should create the SPTrustedLoginProvider with claims provider set" { + Set-TargetResource @testParams + $getResults = Get-TargetResource @testParams + $getResults.ClaimProviderName | Should -Be $testParams.ClaimProviderName + } } } @@ -608,48 +612,52 @@ try } } - Context -Name "The OIDC SPTrustedLoginProvider already exists and should not be changed" -Fixture { - BeforeAll { - $testParams = @{ - Name = "Contoso" - Description = "Contoso" - DefaultClientIdentifier = "fae5bd07-be63-4a64-a28c-7931a4ebf62b" - RegisteredIssuerName = "https://adfs.contoso.com/adfs" - AuthorizationEndPointUri = "https://adfs.contoso.com/adfs/oauth2/authorize" - SignOutUrl = "https://adfs.contoso.com/adfs/oauth2/logout" - IdentifierClaim = "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/emailaddress" - ClaimsMappings = @( + if ($Global:SPDscHelper.CurrentStubBuildNumber.Major -eq 16 -and + $Global:SPDscHelper.CurrentStubBuildNumber.Build -gt 13000) + { + Context -Name "The OIDC SPTrustedLoginProvider already exists and should not be changed" -Fixture { + BeforeAll { + $testParams = @{ + Name = "Contoso" + Description = "Contoso" + DefaultClientIdentifier = "fae5bd07-be63-4a64-a28c-7931a4ebf62b" + RegisteredIssuerName = "https://adfs.contoso.com/adfs" + AuthorizationEndPointUri = "https://adfs.contoso.com/adfs/oauth2/authorize" + SignOutUrl = "https://adfs.contoso.com/adfs/oauth2/logout" + IdentifierClaim = "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/emailaddress" + ClaimsMappings = @( (New-CimInstance -ClassName MSFT_SPClaimTypeMapping -Property @{ - Name = "Email" - IncomingClaimType = "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/emailaddress" - } -ClientOnly) + Name = "Email" + IncomingClaimType = "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/emailaddress" + } -ClientOnly) (New-CimInstance -ClassName MSFT_SPClaimTypeMapping -Property @{ - Name = "Role" - IncomingClaimType = "http://schemas.xmlsoap.org/ExternalSTSGroupType" - LocalClaimType = "http://schemas.microsoft.com/ws/2008/06/identity/claims/role" - } -ClientOnly) - ) - SigningCertificateThumbprint = "123ABCFACE123ABCFACE123ABCFACE123ABCFACE" - ClaimProviderName = "LDAPCP" - Ensure = "Present" - } + Name = "Role" + IncomingClaimType = "http://schemas.xmlsoap.org/ExternalSTSGroupType" + LocalClaimType = "http://schemas.microsoft.com/ws/2008/06/identity/claims/role" + } -ClientOnly) + ) + SigningCertificateThumbprint = "123ABCFACE123ABCFACE123ABCFACE123ABCFACE" + ClaimProviderName = "LDAPCP" + Ensure = "Present" + } - Mock -CommandName Get-SPTrustedIdentityTokenIssuer -MockWith { - $sptrust = [pscustomobject]@{ - Name = $testParams.Name - ClaimProviderName = $testParams.ClaimProviderName + Mock -CommandName Get-SPTrustedIdentityTokenIssuer -MockWith { + $sptrust = [pscustomobject]@{ + Name = $testParams.Name + ClaimProviderName = $testParams.ClaimProviderName + } + return $sptrust } - return $sptrust } - } - It "Should return present from the get method" { - $getResults = Get-TargetResource @testParams - $getResults.Ensure | Should -Be "Present" - } + It "Should return present from the get method" { + $getResults = Get-TargetResource @testParams + $getResults.Ensure | Should -Be "Present" + } - It "Should return true from the test method" { - Test-TargetResource @testParams | Should -Be $true + It "Should return true from the test method" { + Test-TargetResource @testParams | Should -Be $true + } } } @@ -764,41 +772,45 @@ try } } - Context -Name "The OIDC SPTrustedLoginProvider is desired, but the IdentifierClaim parameter does not match a claim type in ClaimsMappings" -Fixture { - BeforeAll { - $testParams = @{ - Name = "Contoso" - Description = "Contoso" - DefaultClientIdentifier = "fae5bd07-be63-4a64-a28c-7931a4ebf62b" - RegisteredIssuerName = "https://adfs.contoso.com/adfs" - AuthorizationEndPointUri = "https://adfs.contoso.com/adfs/oauth2/authorize" - SignOutUrl = "https://adfs.contoso.com/adfs/oauth2/logout" - IdentifierClaim = "IdentityClaimTypeNotSpecifiedInClaimsMappings" - ClaimsMappings = @( + if ($Global:SPDscHelper.CurrentStubBuildNumber.Major -eq 16 -and + $Global:SPDscHelper.CurrentStubBuildNumber.Build -gt 13000) + { + Context -Name "The OIDC SPTrustedLoginProvider is desired, but the IdentifierClaim parameter does not match a claim type in ClaimsMappings" -Fixture { + BeforeAll { + $testParams = @{ + Name = "Contoso" + Description = "Contoso" + DefaultClientIdentifier = "fae5bd07-be63-4a64-a28c-7931a4ebf62b" + RegisteredIssuerName = "https://adfs.contoso.com/adfs" + AuthorizationEndPointUri = "https://adfs.contoso.com/adfs/oauth2/authorize" + SignOutUrl = "https://adfs.contoso.com/adfs/oauth2/logout" + IdentifierClaim = "IdentityClaimTypeNotSpecifiedInClaimsMappings" + ClaimsMappings = @( (New-CimInstance -ClassName MSFT_SPClaimTypeMapping -Property @{ - Name = "Email" - IncomingClaimType = "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/emailaddress" - } -ClientOnly) + Name = "Email" + IncomingClaimType = "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/emailaddress" + } -ClientOnly) (New-CimInstance -ClassName MSFT_SPClaimTypeMapping -Property @{ - Name = "Role" - IncomingClaimType = "http://schemas.xmlsoap.org/ExternalSTSGroupType" - LocalClaimType = "http://schemas.microsoft.com/ws/2008/06/identity/claims/role" - } -ClientOnly) - ) - SigningCertificateThumbprint = "123ABCFACE123ABCFACE123ABCFACE123ABCFACE" - ClaimProviderName = "LDAPCP" - Ensure = "Present" - } + Name = "Role" + IncomingClaimType = "http://schemas.xmlsoap.org/ExternalSTSGroupType" + LocalClaimType = "http://schemas.microsoft.com/ws/2008/06/identity/claims/role" + } -ClientOnly) + ) + SigningCertificateThumbprint = "123ABCFACE123ABCFACE123ABCFACE123ABCFACE" + ClaimProviderName = "LDAPCP" + Ensure = "Present" + } - Mock -CommandName New-SPClaimTypeMapping -MockWith { - return [pscustomobject]@{ - InputClaimType = "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/emailaddress" + Mock -CommandName New-SPClaimTypeMapping -MockWith { + return [pscustomobject]@{ + InputClaimType = "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/emailaddress" + } } } - } - It "should fail validation of IdentifierClaim in the set method" { - { Set-TargetResource @testParams } | Should -Throw "IdentifierClaim does not match any claim type specified in ClaimsMappings." + It "should fail validation of IdentifierClaim in the set method" { + { Set-TargetResource @testParams } | Should -Throw "IdentifierClaim does not match any claim type specified in ClaimsMappings." + } } } From 54a2961fd6e3cbaa0cf7762c9e396ae61a92f29d Mon Sep 17 00:00:00 2001 From: Yvan Duhamel Date: Fri, 7 Jan 2022 09:10:59 +0100 Subject: [PATCH 15/19] Update SharePointDsc.SPTrustedIdentityTokenIssuer.Tests.ps1 --- .../SharePointDsc.SPTrustedIdentityTokenIssuer.Tests.ps1 | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/tests/Unit/SharePointDsc/SharePointDsc.SPTrustedIdentityTokenIssuer.Tests.ps1 b/tests/Unit/SharePointDsc/SharePointDsc.SPTrustedIdentityTokenIssuer.Tests.ps1 index 1d44a0895..48a4c299d 100644 --- a/tests/Unit/SharePointDsc/SharePointDsc.SPTrustedIdentityTokenIssuer.Tests.ps1 +++ b/tests/Unit/SharePointDsc/SharePointDsc.SPTrustedIdentityTokenIssuer.Tests.ps1 @@ -413,8 +413,7 @@ try } It "should fail validation of parameters" { - { Set-TargetResource @testParams } | Should -Throw "At least one of the following parameters must be specified: " + ` - "Realm (for SAML trust), DefaultClientIdentifier (for OIDC trust)." + { Set-TargetResource @testParams } | Should -Throw "At least one of the following parameters must be specified: Realm (for SAML trust), DefaultClientIdentifier (for OIDC trust)." } } @@ -474,8 +473,7 @@ try } It "should fail validation of parameters" { - { Set-TargetResource @testParams } | Should -Throw "Parameter DefaultClientIdentifier was set but AuthorizationEndPointUri, RegisteredIssuerName or SignOutUrl are not set." + ` - "Parameters AuthorizationEndPointUri, RegisteredIssuerName, DefaultClientIdentifier and SignOutUrl are required when DefaultClientIdentifier is set" + { Set-TargetResource @testParams } | Should -Throw "Parameter DefaultClientIdentifier was set but AuthorizationEndPointUri, RegisteredIssuerName or SignOutUrl are not set. Parameters AuthorizationEndPointUri, RegisteredIssuerName, DefaultClientIdentifier and SignOutUrl are required when DefaultClientIdentifier is set" } } From 329ad63732106fb2ae7753020e112ff6c3a4b94c Mon Sep 17 00:00:00 2001 From: Yvan Duhamel Date: Fri, 7 Jan 2022 09:26:36 +0100 Subject: [PATCH 16/19] fix typo --- .../SharePointDsc.SPTrustedIdentityTokenIssuer.Tests.ps1 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/Unit/SharePointDsc/SharePointDsc.SPTrustedIdentityTokenIssuer.Tests.ps1 b/tests/Unit/SharePointDsc/SharePointDsc.SPTrustedIdentityTokenIssuer.Tests.ps1 index 48a4c299d..bef8b40e2 100644 --- a/tests/Unit/SharePointDsc/SharePointDsc.SPTrustedIdentityTokenIssuer.Tests.ps1 +++ b/tests/Unit/SharePointDsc/SharePointDsc.SPTrustedIdentityTokenIssuer.Tests.ps1 @@ -473,7 +473,7 @@ try } It "should fail validation of parameters" { - { Set-TargetResource @testParams } | Should -Throw "Parameter DefaultClientIdentifier was set but AuthorizationEndPointUri, RegisteredIssuerName or SignOutUrl are not set. Parameters AuthorizationEndPointUri, RegisteredIssuerName, DefaultClientIdentifier and SignOutUrl are required when DefaultClientIdentifier is set" + { Set-TargetResource @testParams } | Should -Throw "Parameter DefaultClientIdentifier was set but AuthorizationEndPointUri, RegisteredIssuerName or SignOutUrl are not set.Parameters AuthorizationEndPointUri, RegisteredIssuerName, DefaultClientIdentifier and SignOutUrl are required when DefaultClientIdentifier is set" } } From 798ed138acdd5988d9e83f979c5ba71983ba4f15 Mon Sep 17 00:00:00 2001 From: Yvan Duhamel Date: Mon, 10 Jan 2022 09:20:08 +0100 Subject: [PATCH 17/19] Add more tests --- ...Dsc.SPTrustedIdentityTokenIssuer.Tests.ps1 | 145 ++++++++++++++++++ 1 file changed, 145 insertions(+) diff --git a/tests/Unit/SharePointDsc/SharePointDsc.SPTrustedIdentityTokenIssuer.Tests.ps1 b/tests/Unit/SharePointDsc/SharePointDsc.SPTrustedIdentityTokenIssuer.Tests.ps1 index bef8b40e2..8e4685901 100644 --- a/tests/Unit/SharePointDsc/SharePointDsc.SPTrustedIdentityTokenIssuer.Tests.ps1 +++ b/tests/Unit/SharePointDsc/SharePointDsc.SPTrustedIdentityTokenIssuer.Tests.ps1 @@ -477,6 +477,72 @@ try } } + Context -Name "A OIDC SPTrustedLoginProvider is desired, but not all required OIDC properties are set" -Fixture { + BeforeAll { + $testParams = @{ + Name = "Contoso" + Description = "Contoso" + DefaultClientIdentifier = "fae5bd07-be63-4a64-a28c-7931a4ebf62b" + SignOutUrl = "https://adfs.contoso.com/adfs/oauth2/logout" + IdentifierClaim = "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/emailaddress" + ClaimsMappings = @( + (New-CimInstance -ClassName MSFT_SPClaimTypeMapping -Property @{ + Name = "Email" + IncomingClaimType = "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/emailaddress" + } -ClientOnly) + (New-CimInstance -ClassName MSFT_SPClaimTypeMapping -Property @{ + Name = "Role" + IncomingClaimType = "http://schemas.xmlsoap.org/ExternalSTSGroupType" + LocalClaimType = "http://schemas.microsoft.com/ws/2008/06/identity/claims/role" + } -ClientOnly) + ) + SigningCertificateThumbprint = "123ABCFACE123ABCFACE123ABCFACE123ABCFACE" + ClaimProviderName = "LDAPCP" + Ensure = "Present" + } + } + + It "should fail validation of parameters" { + { Set-TargetResource @testParams } | Should -Throw "Parameter DefaultClientIdentifier was set but AuthorizationEndPointUri, RegisteredIssuerName or SignOutUrl are not set.Parameters AuthorizationEndPointUri, RegisteredIssuerName, DefaultClientIdentifier and SignOutUrl are required when DefaultClientIdentifier is set" + } + } + + if ($Global:SPDscHelper.CurrentStubBuildNumber.Major -ne 16 -or + $Global:SPDscHelper.CurrentStubBuildNumber.Build -le 13000) + { + Context -Name "A OIDC SPTrustedLoginProvider is desired, but current version is not SharePoint Subscription" -Fixture { + BeforeAll { + $testParams = @{ + Name = "Contoso" + Description = "Contoso" + DefaultClientIdentifier = "fae5bd07-be63-4a64-a28c-7931a4ebf62b" + RegisteredIssuerName = "https://adfs.contoso.com/adfs" + AuthorizationEndPointUri = "https://adfs.contoso.com/adfs/oauth2/authorize" + SignOutUrl = "https://adfs.contoso.com/adfs/oauth2/logout" + IdentifierClaim = "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/emailaddress" + ClaimsMappings = @( + (New-CimInstance -ClassName MSFT_SPClaimTypeMapping -Property @{ + Name = "Email" + IncomingClaimType = "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/emailaddress" + } -ClientOnly) + (New-CimInstance -ClassName MSFT_SPClaimTypeMapping -Property @{ + Name = "Role" + IncomingClaimType = "http://schemas.xmlsoap.org/ExternalSTSGroupType" + LocalClaimType = "http://schemas.microsoft.com/ws/2008/06/identity/claims/role" + } -ClientOnly) + ) + SigningCertificateThumbprint = "123ABCFACE123ABCFACE123ABCFACE123ABCFACE" + ClaimProviderName = "LDAPCP" + Ensure = "Present" + } + } + + It "should fail validation of current version of SharePoint" { + { Set-TargetResource @testParams } | Should -Throw "OIDC parameters can only be used with SharePoint Server Subscription Edition." + } + } + } + Context -Name "The SAML SPTrustedLoginProvider does not exist but should, with a claims provider that exists on the farm" -Fixture { BeforeAll { $testParams = @{ @@ -733,6 +799,85 @@ try } } + if ($Global:SPDscHelper.CurrentStubBuildNumber.Major -eq 16 -and + $Global:SPDscHelper.CurrentStubBuildNumber.Build -gt 13000) + { + Context -Name "The OIDC SPTrustedLoginProvider already exists but should be removed" -Fixture { + BeforeAll { + $testParams = @{ + Name = "Contoso" + Description = "Contoso" + DefaultClientIdentifier = "fae5bd07-be63-4a64-a28c-7931a4ebf62b" + RegisteredIssuerName = "https://adfs.contoso.com/adfs" + AuthorizationEndPointUri = "https://adfs.contoso.com/adfs/oauth2/authorize" + SignOutUrl = "https://adfs.contoso.com/adfs/oauth2/logout" + IdentifierClaim = "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/emailaddress" + ClaimsMappings = @( + (New-CimInstance -ClassName MSFT_SPClaimTypeMapping -Property @{ + Name = "Email" + IncomingClaimType = "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/emailaddress" + } -ClientOnly) + (New-CimInstance -ClassName MSFT_SPClaimTypeMapping -Property @{ + Name = "Role" + IncomingClaimType = "http://schemas.xmlsoap.org/ExternalSTSGroupType" + LocalClaimType = "http://schemas.microsoft.com/ws/2008/06/identity/claims/role" + } -ClientOnly) + ) + SigningCertificateThumbprint = "123ABCFACE123ABCFACE123ABCFACE123ABCFACE" + ClaimProviderName = "LDAPCP" + Ensure = "Absent" + } + + Mock -CommandName Get-SPTrustedIdentityTokenIssuer -MockWith { + $sptrust = [pscustomobject]@{ + Name = $testParams.Name + } + $sptrust | Add-Member -Name Update -MemberType ScriptMethod -Value { } + return $sptrust + } + + Mock -CommandName Get-SPWebApplication -MockWith { + $spWebApp = [pscustomobject]@{ + Url = "http://webAppUrl" + } + $spWebApp | Add-Member -Name Update -MemberType ScriptMethod -Value { } + $spWebApp | Add-Member -Name GetIisSettingsWithFallback -MemberType ScriptMethod -Value { } + return $spWebApp + } + + Mock -CommandName Get-SPAuthenticationProvider -MockWith { + $spAP = [pscustomobject]@{ + LoginProviderName = "" + } + $spAP | Add-Member -Name Update -MemberType ScriptMethod -Value { } + $spAP | Add-Member -MemberType ScriptMethod ` + -Name GetType ` + -Value { + return @{ + FullName = "Microsoft.SharePoint.Administration.SPTrustedAuthenticationProvider" + } + } -PassThru -Force + return $spAP + } + + Mock -CommandName Remove-SPTrustedIdentityTokenIssuer -MockWith { } + } + + It "Should return absent from the get method" { + (Get-TargetResource @testParams).Ensure | Should -Be "Present" + } + + It "Should return true from the test method" { + Test-TargetResource @testParams | Should -Be $false + } + + It "Should remove the SPTrustedIdentityTokenIssuer" { + Set-TargetResource @testParams + Assert-MockCalled Remove-SPTrustedIdentityTokenIssuer + } + } + } + Context -Name "The SAML SPTrustedLoginProvider is desired, but the IdentifierClaim parameter does not match a claim type in ClaimsMappings" -Fixture { BeforeAll { $testParams = @{ From 47b2d9f8a00bee75cc14f35ea770c9f12f33be38 Mon Sep 17 00:00:00 2001 From: Yvan Duhamel Date: Fri, 14 Jan 2022 11:38:37 +0100 Subject: [PATCH 18/19] increase code coverage --- ...harePointDsc.SPTrustedIdentityTokenIssuer.Tests.ps1 | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/tests/Unit/SharePointDsc/SharePointDsc.SPTrustedIdentityTokenIssuer.Tests.ps1 b/tests/Unit/SharePointDsc/SharePointDsc.SPTrustedIdentityTokenIssuer.Tests.ps1 index 8e4685901..cdcbe35c6 100644 --- a/tests/Unit/SharePointDsc/SharePointDsc.SPTrustedIdentityTokenIssuer.Tests.ps1 +++ b/tests/Unit/SharePointDsc/SharePointDsc.SPTrustedIdentityTokenIssuer.Tests.ps1 @@ -659,8 +659,9 @@ try Mock -CommandName Get-SPTrustedIdentityTokenIssuer -MockWith { $sptrust = [pscustomobject]@{ - Name = $testParams.Name - ClaimProviderName = $testParams.ClaimProviderName + Name = $testParams.Name + ProviderSignOutUri = $testParams.ProviderSignOutUri + ClaimProviderName = $testParams.ClaimProviderName } return $sptrust } @@ -707,8 +708,9 @@ try Mock -CommandName Get-SPTrustedIdentityTokenIssuer -MockWith { $sptrust = [pscustomobject]@{ - Name = $testParams.Name - ClaimProviderName = $testParams.ClaimProviderName + Name = $testParams.Name + AuthorizationEndPointUri = $testParams.AuthorizationEndPointUri + ClaimProviderName = $testParams.ClaimProviderName } return $sptrust } From d58282a35e3a8d5f649457ae2173ebc95352bf4e Mon Sep 17 00:00:00 2001 From: Yvan Duhamel Date: Fri, 14 Jan 2022 16:52:33 +0100 Subject: [PATCH 19/19] improve tests and increase code coverage --- ...Dsc.SPTrustedIdentityTokenIssuer.Tests.ps1 | 42 ++++++++++++++----- 1 file changed, 32 insertions(+), 10 deletions(-) diff --git a/tests/Unit/SharePointDsc/SharePointDsc.SPTrustedIdentityTokenIssuer.Tests.ps1 b/tests/Unit/SharePointDsc/SharePointDsc.SPTrustedIdentityTokenIssuer.Tests.ps1 index cdcbe35c6..f375c790b 100644 --- a/tests/Unit/SharePointDsc/SharePointDsc.SPTrustedIdentityTokenIssuer.Tests.ps1 +++ b/tests/Unit/SharePointDsc/SharePointDsc.SPTrustedIdentityTokenIssuer.Tests.ps1 @@ -569,19 +569,30 @@ try } Mock -CommandName Get-SPTrustedIdentityTokenIssuer -MockWith { + return $null + } + + Mock -CommandName New-SPTrustedIdentityTokenIssuer -MockWith { $sptrust = [pscustomobject]@{ - Name = $testParams.Name - ClaimProviderName = $testParams.ClaimProviderName + ImportTrustCertificate = $null + Name = "" + Description = "" + Realm = "" + SignInUrl = "" + UseWReply = "" + ProviderSignOutUri = "" + IdentifierClaim = "" + ClaimsMappings = $null + ClaimProviderName = "" } $sptrust | Add-Member -Name Update -MemberType ScriptMethod -Value { } return $sptrust } } - It "Should create the SPTrustedLoginProvider with claims provider set" { + It "Should call cmdlet New-SPTrustedIdentityTokenIssuer" { Set-TargetResource @testParams - $getResults = Get-TargetResource @testParams - $getResults.ClaimProviderName | Should -Be $testParams.ClaimProviderName + Assert-MockCalled New-SPTrustedIdentityTokenIssuer } } @@ -615,19 +626,30 @@ try } Mock -CommandName Get-SPTrustedIdentityTokenIssuer -MockWith { + return $null + } + + Mock -CommandName New-SPTrustedIdentityTokenIssuer -MockWith { $sptrust = [pscustomobject]@{ - Name = $testParams.Name - ClaimProviderName = $testParams.ClaimProviderName + ImportTrustCertificate = $null + Name = "" + Description = "" + RegisteredIssuerName = "" + AuthorizationEndPointUri = "" + DefaultClientIdentifier = "" + SignOutUrl = "" + IdentifierClaim = "" + ClaimsMappings = $null + ClaimProviderName = "" } $sptrust | Add-Member -Name Update -MemberType ScriptMethod -Value { } return $sptrust } } - It "Should create the SPTrustedLoginProvider with claims provider set" { + It "Should call cmdlet New-SPTrustedIdentityTokenIssuer" { Set-TargetResource @testParams - $getResults = Get-TargetResource @testParams - $getResults.ClaimProviderName | Should -Be $testParams.ClaimProviderName + Assert-MockCalled New-SPTrustedIdentityTokenIssuer } } }