Je travaille actuellement sur un prototype pour un service WCF qui utilisera l'authentification par certificat client. Nous aimerions pouvoir publier directement notre application sur IIS, mais également autoriser le déchargement SSL à l'aide d'IIS ARR (Application Request Routing). Après avoir exploré la documentation, j'ai pu tester les deux configurations avec succès. Je suis en mesure de récupérer le certificat client utilisé pour s'authentifier auprès de:Le certificat du client a une thumprint différente via ARR et AuthorizationContext
- X-Arr-ClientCert - l'en-tête qui contient le certificat lors de l'utilisation de ARR.
- X509CertificateClaimSet - lors de la publication directement à IIS, voici comment récupérer le certificat client
Pour vérifier que la demande est autorisée, je correspondent à l'empreinte numérique du certificat au thumbprint attendu configuré quelque part. À ma grande surprise, lors de l'obtention du certificat par différentes méthodes, le même certificat a des empreintes différentes.
Pour vérifier ce qui se passe, je l'ai converti la propriété « RawData » sur les deux certificats à base64 et a constaté que c'est la même, sauf que dans le cas du X509CertificateClaimSet, il y a espaces dans les données de certificat, alors que dans le cas de ARR, il n'y en a pas. Dans le cas contraire, les deux chaînes sont les mêmes:
Ma question: Quelqu'un at-il courir un autre dans ce, et puis-je compter réellement sur les empreintes digitales? Si ce n'est pas le cas, mon plan de sauvegarde consiste à mettre en place une vérification sur le sujet et l'émetteur, mais je suis ouvert à d'autres suggestions.
J'ai inclus quelques exemples de code (simplifié) ci-dessous:
string expectedThumbprint = "...";
if (OperationContext.Current.ServiceSecurityContext == null ||
OperationContext.Current.ServiceSecurityContext.AuthorizationContext.ClaimSets == null ||
OperationContext.Current.ServiceSecurityContext.AuthorizationContext.ClaimSets.Count <= 0)
{
// Claimsets not found, assume that we are reverse proxied by ARR (Application Request Routing). If this is the case, we expect the certificate to be in the X-ARR-CLIENTCERT header
IncomingWebRequestContext request = WebOperationContext.Current.IncomingRequest;
string certBase64 = request.Headers["X-Arr-ClientCert"];
if (certBase64 == null) return false;
byte[] bytes = Convert.FromBase64String(certBase64);
var cert = new System.Security.Cryptography.X509Certificates.X509Certificate2(bytes);
return cert.Thumbprint == expectedThumbprint;
}
// In this case, we are directly published to IIS with Certificate authentication.
else
{
bool correctCertificateFound = false;
foreach (var claimSet in OperationContext.Current.ServiceSecurityContext.AuthorizationContext.ClaimSets)
{
if (!(claimSet is X509CertificateClaimSet)) continue;
var cert = ((X509CertificateClaimSet)claimSet).X509Certificate;
// Match certificate thumbprint to expected value
if (cert.Thumbprint == expectedThumbprint)
{
correctCertificateFound = true;
break;
}
}
return correctCertificateFound;
}
Salut Marco, Merci pour la suggestion, je vais examiner un peu plus dans Octopus quand nous arrivons aux scénarios de déploiement. Le scénario de cette question est que nous voulons authentifier nos consommateurs de services en utilisant des certificats (authentification mutuelle TLS). Bien que le déploiement soit un sujet de préoccupation, il n'est pas lié à cette question spécifique :) – Erik