一家公司正在使用带有ADFS身份validation的Office 365; AD Connect用于目录同步,ADFS是Windows服务器2012 R2版本。
该公司有多个Active Directory域:
parent1.com child1.parent1.com child2.parent1.com child3.parent1.com parent2.com ... ...
根域在Office 365中configuration为联合域(公用域名和AD域名相同); 这个工作正常,用户可以使用他们的UPNlogin到Office 365,比如[email protected]和他们的AD密码。
我需要添加对子域的支持; 因此我通过运行以下命令(在使用Connect-MsolService以pipe理员帐户连接到Office 365之后)将child1.parent1.com添加到Office 365:
New-MsolFederatedDomain -DomainName child1.parent1.com -SupportMultipleDomain
(注意:如果我没有使用SupportMultipleDomain参数,PowerShell会给出一个错误,说明它是必需的)。
然后,我开始在私人和公共DNS中添加所有必需的DNSlogging; DNSlogging的Office 365validation报告一切正常。
然后将子域添加到AD Connect,并执行同步; 因此,来自子域的用户出现在Office 365中,其用户名如[email protected] 。 我为其分配了相应的许可证,并尝试login到Office 365门户。
但是,子域的用户无法login; 他们会收到一个“无效的请求”错误,并提供以下额外的详细信息:
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方面显然有些问题,但我不是专家,我也不是那个设置它的人。 我该如何解决这个问题,以便子域中的用户可以成功login到Office 365?
这个问题几乎没有文档记载( 一个Technet的博客文章和Azure AD的一些文档 ),但它确实存在,这是由于ADFS在某些特定情况下不能正确运行(多个顶级联合域并在联合子域中引入联合子域混合); 该解决scheme涉及编辑ADFS索赔规则中的正则expression式,该规则用于构build与用户的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/"));
但是,请注意,这可能会破坏与其他scheme的兼容性,例如其父域未联合的实际第三级联合域。