WIF ID 4036 Error - Troubleshoot, Ideas?
I thought understood this, but I am stumped and hope someone here can add some clarity.
I have written a custom STS. I have written a separate, simple Relying Party that outputs the claims 开发者_开发百科of the STS. It works on my local machine. I can make it work if I deploy the STS and RP to the same server. However, trying to run an RP from my dev box, hitting the dev server, I get ID4036 errors (ID4036: The key needed to decrypt the encrypted security token could not be resolved from the following security key identifier 'CN=Cin1Web07-Dev.paycor-test.com116108771XXXXXX3182074711bOkGGQaGymVHZXc9v8AsLyx/Qiy0fhmKKu88BVinXvx4ySzBMqmb1IiY7DSFAXR1PeFevfTxmzmZwu1ztPyJWpNV0LzKnVbxrqChH7iREfYhp5EHUzF0tCdJ49Q/XL3laN/Nh971hxPzj0rBQIIJ8bK/vW70x6gCkIj4Wy50Qow='. Ensure that the SecurityTokenResolver is populated with the required key)
I've tried finding answers in the Claims Guide and Programming WIF books, but no luck. Also, I found this site: http://consultingblogs.emc.com/simonevans/archive/2010/11/19/common-windows-identity-foundation-ws-federation-exceptions-explained.aspx but it doesn't get me further either.
If anyone has any troubleshooting tips, or ideas, I would appreciate. Here are my details of what I'm doing:
The STS signs the certificate with a simple cn=LocalHost, this is set here:
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;
}
and set here:
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";
}
I called the method GetCertificateNameForSigningMetadata, but my understanding is that this also signs the token.
In my RP, I have this section - and the thumbprint matches the thumbprint of the cn=localhost from the STS server:
<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>
I believe that is all configured correctly. However, the encryption part is where I think there is a problem. This is in the RP's web.config. The Thumbprint below references a certificate called RelyingParty.MyOrg.
<serviceCertificate>
<certificateReference x509FindType="FindByThumbprint" findValue="AA310FF423XXXXXXXX910F9C69" storeLocation="LocalMachine" storeName="My" />
</serviceCertificate>
The certificate is installed on my development machine (the RP) along with the private key. The Certificate Authority also exists on my machine. I exported the certificate to the dev server and the CA cert. They seem to be setup correctly. In the GetScope of the STS, I have this:
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;
}
The AppSetting maps to cn=RelyingParty.MyOrg, and is finding the certificate I believe (because if I change 1 letter, I get a different 'can't find cert' error).
Despite all this, I get the ID4036 on my dev box when I use the STS.
Here is the part that REALLY stumps me - after changing to the RelyingParty.MyOrg cert, the RP on the dev server still works - even though it is set to the old cn=localhost and does not have the private key for the cn=RelyingParty.MyOrg.
So clearly, I do not understand some of this config. I apologize for the lengthy post, but I am really getting desperate to wrap this up. If anyone has any suggestions, I would greatly appreciate it.
It appears that your dev box doesn't have the private key needed by the RP to decrypt the token. The STS only needs the public key to encrypt the token, so thats why it's not failing. If you installed the private key on the dev server, it could be that the permissions are set incorrectly on the private key and the RP can't read it.
It's a long story - but the STS was actually encrypting with the wrong key...
As for troubleshooting, this is a real PITA to solve, but you have to really look at the raw claims token.
精彩评论