The Windows Identity Foundation (WIF) provides an IssuerNameRegistry for validating the issuer of a security token. There are multiple implementations of the abstract class IssuerNameRegistry. ConfigurationBasedIssuerNameRegistry is probably the most commonly used one. You can add trusted issuers to this implementation by adding them in the respective section of your web.config file.
The method GetIssuerName of the IssuerNameRegistry (which is responsible for validating issuers) expects a SecurityToken as parameter and returns the name of the issuer (if valid) or null. Internally the paramter is casted to a X509SecurityToken and the thumbprint of the corresponding certificate is looked up in the list of registered trusted issuers.
This sounds pretty simple and straight forward, but the actual question that came to my mind is: how to obtain the thumbprint of the issuer, as it does not seem to be included in the security token?
It took me some time of research and reading through decompiled framework code, but finally I “discovered” a solution in the SAML2 implementation inside WIF:
Validating signatures of incoming security tokens inside WIF is usually done with an EnvelopedSignatureReader. After reading and validating the xml signature this reader provides the SigningCredentials of the signature:
var root = XElement.Load(wrappedSignatureReader); var signingCredentials = wrappedSignatureReader.SigningCredentials;
When the security token was signed with a X509 certificate (that’s the most common way), the SigningCredentials are of type X509SigningCredentials and contain somehow a reference to the used certificate.
You can obtain a reference to this certificate by using a X509CertificateStoreTokenResolver. This SecurityTokenResolver is usually present in the property SecurityTokenServiceConfiguration.IssuerTokenResolver (i.e. through your service configuration).
To resolve the SigningCredentials to a X509SecurityToken simply pass the SigningKeyIdentifier to the method TryResolveToken of the IssuerTokenResolver:
protected virtual bool TryResolveIssuerToken(SigningCredentials signingCredentials, SecurityTokenResolver issuerResolver, out SecurityToken token) { if (signingCredentials != null && signingCredentials.SigningKeyIdentifier != null && issuerResolver != null) { return issuerResolver.TryResolveToken(signingCredentials.SigningKeyIdentifier, out token); } token = null; return false; }
All this fragments come together in the ReadToken method of your custom SecurityTokenHandler:
protected override SecurityToken ReadToken(XmlReader reader) { using (var wrappedSignatureReader = new EnvelopedSignatureReader(reader, this, this.Configuration.IssuerTokenResolver, true, true, false)) { var root = XElement.Load(wrappedSignatureReader); var signingCredentials = wrappedSignatureReader.SigningCredentials; SecurityToken issuerToken; this.TryResolveIssuerToken(signingCredentials, this.Configuration.IssuerTokenResolver, out issuerToken); SecurityToken token; // create and fill your custom security token with data here... return token; } }
The obtained SecurityToken is of type X509SecurityToken, which can be used to verify the issuer with an IssuerNameRegistry. This is/should be done in the ValidateToken method of your SecurityTokenHandler.
WIF in depth: What’s a SecurityKeyIdentifierClause | peschuster
[…] peschuster Technology, .NET and Web Skip to content HomeInfo ← Upgrading user settings WIF in depth: Validating a security token against an IssuerNameRegistry → […]
jeevitha
Hi This blog is very informative.. however, i stuck with another issue. I need to configure around 100 issuer in my issuerRegistry and validate the user token against the specific issuer it tied with.. is there any simple way of doing this instead of having all the issuers configured in my config file. Also i am worried about the performance if we have more number of issuers in config. will that affect my performance since on returning the security token the request url need to find its corresponding issuer token and validate against it