I am setting up client authentication on my API management component. I want clients to authenticate to my API management before they can access any APIs (so API management is server and API users are clients, NOT client authentication for backend services)
According to Microsoft, I can do this (https://learn.microsoft.com/en-us/azure/api-management/api-management-howto-mutual-certificates-for-clients). However, when I try to verify the thumbprint of my certificate against all trusted certificates I uploaded, it fails because of an invalid client certificate. I used the same policy code as Microsoft provides:
<choose>
<when condition="@(context.Request.Certificate == null || !context.Deployment.Certificates.Any(c => c.Value.Thumbprint == context.Request.Certificate.Thumbprint))" >
<return-response>
<set-status code="403" reason="Invalid client certificate" />
</return-response>
</when>
</choose>
Now when I use a hard coded thumbprint to check, it succeeds:
<choose>
<when condition="@(context.Request.Certificate == null || context.Request.Certificate.Thumbprint != "desired-thumbprint")" >
<return-response>
<set-status code="403" reason="Invalid client certificate" />
</return-response>
</when>
</choose>
I upload my client certificate to CA certificates. I cannot upload it in client certificates on API management because I do not have the private key. Only clients will have them and they will only send their public certificate so I can upload it into my API management instance when I trust them.
I think the policy to check all certificates might be wrong and it might be checking only the certificates from my client certificates. Is this correct? And if so, is it possible to check against all ca certificates I uploaded to API management?
This only works if you upload it to client certificates. context.Deployment.Certificates
is client certificates collection. I know that may seem counter-intuitive, and it is because context.Deployment.Certificates
was not meant to be used exactly like that. It holds certificates APIM uses to authenticate itself to backend, thus need to provide private key.
If you do not have access to private keys of your client certificates and all of them are issued by a few CA/Root certificates, consider uploading CA/root certificates and use context.Request.Certificate.Verify to validate the chain.