Active-Directory

Office 365 ADFS 身份驗證不適用於子域

  • August 12, 2016

一家公司正在使用帶有 ADFS 身份驗證的 Office 365;AD Connect用於目錄同步,ADFS是Windows server 2012 R2版本。

該公司有多個 Active Directory 域:

parent1.com
   child1.parent1.com
   child2.parent1.com
   child3.parent1.com
parent2.com
   ...
...

根域在 Office 365 中配置為聯合域(公共域名和 AD 域名相同);這很好用,使用者可以使用他們的 UPN(例如user1@parent1.com)和他們的 AD 密碼登錄到 Office 365。

我需要添加對子域的支持;因此,我child1.parent1.com通過執行以下命令添加到 Office 365(在使用管理員帳戶連接到 Office 365 之後Connect-MsolService):

New-MsolFederatedDomain -DomainName child1.parent1.com -SupportMultipleDomain

(注意如果我不使用該SupportMultipleDomain參數,PowerShell 會給出一個錯誤,說明它是必需的)。

然後我繼續在私有和公共 DNS 中添加所有必需的 DNS 記錄;DNS 記錄的 Office 365 驗證報告一切正常。

然後將子域添加到 AD Connect,並執行同步;來自子域的使用者因此出現在 Office 365 中,使用者名如user1@child1.parent1.com. 我為他們分配了適當的許可證並嘗試登錄 Office 365 門戶。

但是,子域的使用者無法登錄;他們收到“無效請求”錯誤,並附有以下附加詳細資訊:

Correlation ID: b1e47d45-b21c-42e9-9758-265804db7171 
Timestamp: 2016-08-10 20:27:48Z 
AADSTS50107: Requested federation realm
object 'http://child1.parent1.com/adfs/services/trust/' does not exist. 

ADFS 方面顯然有問題,但我不是這方面的專家,也不是我設置它的人;如何解決此問題,以便子域中的使用者可以成功登錄 Office 365?

該問題幾乎沒有記錄(Technet 部落格文章Azure AD 的一些文件),但它確實存在,這是由於 ADFS 在某些特定情況下行為不正確(多個頂級聯合域和在混合); 該解決方案涉及編輯 ADFS 聲明規則中的正則表達式,該規則用於建構與使用者的 UPN 關聯的 IssuerUri。引用第二篇文章:

So lets say for example that I have bmcontoso.com and then add
corp.bmcontoso.com. This means that the IssuerUri for a user from
corp.bmcontoso.com will need to be http://bmcontoso.com/adfs/services/trust.
However the standard rule implemented above for Azure AD, will generate a
token with an issuer as http://corp.bmcontoso.com/adfs/services/trust
which will not match the domain's required value and authentication will fail.

為了解決這個問題,應該編輯 ADFS 中的第三條聲明規則,從

c:[Type == "http://schemas.xmlsoap.org/claims/UPN"] => issue(Type = "http://schemas.microsoft.com/ws/2008/06/identity/claims/issuerid", Value = regexreplace(c.Value, ".+@(?<domain>.+)","http://${domain}/adfs/services/trust/"));

c:[Type == "http://schemas.xmlsoap.org/claims/UPN"] => issue(Type = "http://schemas.microsoft.com/ws/2008/06/identity/claims/issuerid", Value = regexreplace(c.Value, "^((.*)([.|@]))?(?<domain>[^.]*[.].*)$", "http://${domain}/adfs/services/trust/"));

但是,請注意,這可能會破壞與其他方案的兼容性,例如父域未聯合的實際第三級聯合域。

引用自:https://serverfault.com/questions/796102