我认为理解这一点,但我很难过,希望这里有人可以增加一些清晰度。
我写了一个自定义STS。我写了一个单独的,简单的依赖方,输出STS的声明。它适用于我的本地机器。如果我将STS和RP部署到同一台服务器,我可以使它工作。但是,尝试从我的开发箱运行RP,命中开发服务器,我得到ID4036错误(ID4036:解密加密安全令牌所需的密钥无法从以下安全密钥标识符'CN = Cin1Web07-Dev解析。 paycor-test.com116108771XXXXXX3182074711bOkGGQaGymVHZXc9v8AsLyx / Qiy0fhmKKu88BVinXvx4ySzBMqmb1IiY7DSFAXR1PeFevfTxmzmZwu1ztPyJWpNV0LzKnVbxrqChH7iREfYhp5EHUzF0tCdJ49Q / XL3laN / Nh971hxPzj0rBQIIJ8bK / vW70x6gCkIj4Wy50Qow =”。确保SecurityTokenResolver填充了所需的关键)
我已经尝试在声明指南和编程WIF书籍中找到答案,但没有运气。另外,我找到了这个网站:http://consultingblogs.emc.com/simonevans/archive/2010/11/19/common-windows-identity-foundation-ws-federation-exceptions-explained.aspx,但它也没有让我更进一步。
如果有人有任何疑难解答提示或想法,我将不胜感激。以下是我正在做的事情的详细信息:
STS使用简单的cn = LocalHost签署证书,在此处设置:
public static MetadataBase GetFederationMetadata()
{
string endpointId = WebConfigurationManager.AppSettings["ActiveSTSUrl"];
EntityDescriptor metadata = new EntityDescriptor();
metadata.EntityId = new EntityId(endpointId);
// Define the signing key
X509Certificate2 cert = CertificateUtil.GetCertificate(StoreName.My, StoreLocation.LocalMachine, GetCertificateNameForSigningMetadata());
metadata.SigningCredentials = new X509SigningCredentials(cert);
// Create role descriptor for security token service
SecurityTokenServiceDescriptor stsRole = new SecurityTokenServiceDescriptor();
stsRole.ProtocolsSupported.Add(new Uri(WSFederationMetadataConstants.Namespace));
metadata.RoleDescriptors.Add(stsRole);
// Add a contact name
ContactPerson person = new ContactPerson(ContactType.Administrative);
person.GivenName = "contactName";
stsRole.Contacts.Add(person);
// Include key identifier for signing key in metadata
SecurityKeyIdentifierClause clause = new X509RawDataKeyIdentifierClause(cert);
SecurityKeyIdentifier ski = new SecurityKeyIdentifier(clause);
KeyDescriptor signingKey = new KeyDescriptor(ski);
signingKey.Use = KeyType.Signing;
stsRole.Keys.Add(signingKey);
// Add endpoints
string activeSTSUrl = WebConfigurationManager.AppSettings["ActiveSTSUrl"];
EndpointAddress endpointAddress = new EndpointAddress(new Uri(activeSTSUrl),
null,
null, GetMetadataReader(activeSTSUrl), null);
stsRole.SecurityTokenServiceEndpoints.Add(endpointAddress);
ExposeClaimTypesOffered(stsRole);
return metadata;
}
并设置在这里:
public MembershipSTSConfiguration() : base()
{
X509Certificate2 signingCert = CertificateUtil.GetCertificate(
StoreName.My,
StoreLocation.LocalMachine,
Common.GetCertificateNameForSigningMetadata());
this.SigningCredentials = new X509SigningCredentials(signingCert);
this.SecurityTokenService = typeof(MembershipSTS);
this.TokenIssuerName = "MembershipSTS";
}
我调用了方法GetCertificateNameForSigningMetadata,但我的理解是这也签署了令牌。
在我的RP中,我有这一部分 - 指纹与STS服务器中cn = localhost的指纹匹配:
<issuerNameRegistry type="Microsoft.IdentityModel.Tokens.ConfigurationBasedIssuerNameRegistry, Microsoft.IdentityModel, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35">
<trustedIssuers>
<add thumbprint="A6F68xxxxxxxx575EBDC" name="http://cin1web07-dev.paycor-test.com:8080/PaycorAuthServices/PassiveSTS.aspx" />
</trustedIssuers>
</issuerNameRegistry>
我相信这一切都是正确配置的。但是,加密部分是我认为存在问题的地方。这是在RP的web.config中。下面的Thumbprint引用了名为RelyingParty.MyOrg的证书。
<serviceCertificate>
<certificateReference x509FindType="FindByThumbprint" findValue="AA310FF423XXXXXXXX910F9C69" storeLocation="LocalMachine" storeName="My" />
</serviceCertificate>
证书安装在我的开发计算机(RP)上以及私钥。证书颁发机构也存在于我的机器上。我将证书导出到开发服务器和CA证书。它们似乎设置正确。在STS的GetScope中,我有这个:
protected override Scope GetScope(IClaimsPrincipal principal, RequestSecurityToken request)
{
Scope scope = new Scope(request.AppliesTo.Uri.AbsoluteUri, SecurityTokenServiceConfiguration.SigningCredentials);
scope.EncryptingCredentials = new X509EncryptingCredentials(CertificateUtil.GetCertificate(StoreName.My, StoreLocation.LocalMachine,
System.Configuration.ConfigurationManager.AppSettings["CertificateNameForEncryptingToken"]));
scope.ReplyToAddress = scope.AppliesToAddress + "/Default.aspx";
return scope;
}
AppSetting映射到cn = RelyingParty.MyOrg,并且正在查找我相信的证书(因为如果我更改了1个字母,我会得到一个不同的'找不到证书'错误。)
尽管如此,当我使用STS时,我的开发盒上还有ID4036。
以下是REALLY让我感到困惑的部分 - 在更改为RelyingParty.MyOrg证书后,开发服务器上的RP仍然有效 - 即使它设置为旧的cn = localhost并且没有私有密钥CN = RelyingParty.MyOrg。
很清楚,我不明白这个配置。我为冗长的帖子道歉,但我真的很想把它包起来。如果有人有任何建议,我将不胜感激。
答案 0 :(得分:2)
您的开发箱似乎没有RP解密令牌所需的私钥。 STS只需要公钥来加密令牌,这就是为什么它没有失败。如果您在开发服务器上安装了私钥,则可能是私钥上的权限设置不正确,而RP无法读取它。
答案 1 :(得分:1)
这是一个很长的故事 - 但STS实际上是用错误的密钥加密......
至于故障排除,这是一个真正的PITA要解决,但你必须真正看看原始声明令牌。