Tuesday, September 29, 2020

 AD FS claims and cross-forest domain local group membership


Domain Local security groups are by defualt omitted from AD FS claims. In a two-way forest trust scenario where users reside in Forest A but the AD FS server and security groups reside in Forest B this may pose a problem if you want to pass along the security group membership (from Forest B) as a claim. 

To solve this, you can create a rule which translates SIDs to Name. The first rule will take the SIDs from the groupsid claim type and match it against the Forest B domain SID (to only query groups from the local domain). It will then use the SID and request the Name attribute as response. The group name will then be added to the claim flow. 

The next rule will take the groups the previous rule added to the flow and compare it to a defined prefix (in my example, group names beginning with "Prefix_"). If it finds a match, it will only issue the matching group names as a claim. 

If run on the AD FS server, the below code will automatically retrieve the AD FS service account name and domain SID and output the constructed claim rules. 



Add-Type -AssemblyName System.Security.Principal
$AdfsServiceAccount = (Get-WmiObject -Query "Select StartName From Win32_Service Where Name='adfssrv'").StartName
$NTAccount = [System.Security.Principal.NTAccount]::new($AdfsServiceAccount)
$NTAccountSecurityIdentifier = $NTAccount.Translate([System.Security.Principal.SecurityIdentifier])
$AccountDomainSid = $NTAccountSecurityIdentifier.AccountDomainSid

$RegEx = "^$($AccountDomainSid.Value)-[0-9]{4,}$"

$IssuanceTransformRules = @"
@RuleName = "Add group Name from SID as Group"
c:[Type == "http://schemas.microsoft.com/ws/2008/06/identity/claims/groupsid", Value =~ "$RegEx"]
 => add(store = "Active Directory", types = ("http://schemas.xmlsoap.org/claims/Group"), query = "objectSid={0};Name;$($NTAccount.Value)", param = c.Value);

@RuleName = "Issue Prefix_ groups from Group"
c:[Type == "http://schemas.xmlsoap.org/claims/Group", Value =~ "^Prefix_"]
 => issue(claim = c);
"@

Write-Output $IssuanceTransformRules