In Geneva you use a IssuerNameRegistry to establish trust with token issuers. The job of the registry is to parse the issuer details and return a well-known string identifying that issuer. If the registry cannot determine that well known string, the issuer is considered non-trusted and request processing is stopped.
Typically it is enough to inspect the X509 certificate that was used to issue the SAML token, but with the Access Control Service the situation is a little different. The ACS uses a multi-tenant model and signs all outgoing tokens with the same certificate. This means it is not sufficient to check the signature only to determine that the token was issued by a specific instance of the ACS.
In addition you also have to check the value of the SAML issuer URI which contains the logical issuer name which in turn contains the ACS solution name. Prior to Geneva Beta 2 you had to use two different extensibility points to do both checks. I wrote about that here.
Starting with Beta 2, the issuer name registry now has the capability to parse both the physical and logical issuer. Great!
Find a sample implementation below:
class AccessControlServiceIssuerNameRegistry : IssuerNameRegistry
{
string _solutionName = “leastprivilege”;
string _acsThumbprint = “6de1689a739d548a5690dbc3894b953ef6123d93”;
string _samlIssuer;
public AccessControlServiceIssuerNameRegistry()
{
_samlIssuer = String.Format(“http://{0}.accesscontrol.windows.net/”,
_solutionName);
}
public override string GetIssuerName(SecurityToken securityToken)
{
// should never get called
throw new NotImplementedException();
}
public override string GetIssuerName(SecurityToken securityToken, string requestedIssuerName)
{
var issuerToken = securityToken as X509SecurityToken;
if (issuerToken == null)
{
throw new ArgumentException(“securityToken”);
}
if (string.IsNullOrEmpty(requestedIssuerName))
{
throw new ArgumentNullException(“requestedIssuerName”);
}
if (!string.Equals(_acsThumbprint, issuerToken.Certificate.Thumbprint, StringComparison.OrdinalIgnoreCase))
{
throw new SecurityTokenException(
“Token not issued by the Access Control Service”);
}
if (!string.Equals(_samlIssuer, requestedIssuerName, StringComparison.OrdinalIgnoreCase))
{
throw new SecurityTokenException(
“Token not issued by the requested instance of the Access Control Service”);
}
return _samlIssuer;
}
}