Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use Client Certificate Authentication to protect APIs in APIM #33

Open
mbraekman opened this issue Oct 30, 2020 · 0 comments
Open

Use Client Certificate Authentication to protect APIs in APIM #33

mbraekman opened this issue Oct 30, 2020 · 0 comments
Assignees

Comments

@mbraekman
Copy link
Owner

mbraekman commented Oct 30, 2020

Describe the documentation you'd like to see
How to set up client cert. authentication in APIM to allow users to call an API.

Additional context

  • Consumption tier: only allows global use or no use of client cert. authentication
  • Other tiers: enable client certificate negotiation (doesn't force the use, but checks if a client cert. is present)
  • Use "CA certificate"-store to upload public certificates
  • Use "certificate"-store to upload private certificates
  • Use policies to validate/verify the given client certificates (by thumbprint/issuer/... or based on what has been uploaded in the "CA Certificates"-store)
  • In order to validate the certificate which is part of the request, use the following piece of code to validate the certificate against those uploaded in the "CA Certificates"-store:
    <choose>
       <!-- Below condition verifies if the request contains a client certificate + if the certificate can be validated against 1 of the available certificates in the CA Certificates-store. -->
       <when condition="@(context.Request.Certificate == null || !context.Request.Certificate.Verify())">
          <return-response>
             <set-status code="403" reason="Invalid client certificate" />
          </return-response>
       </when>
    </choose>

Important remark!
The above policy will not work if the used certificates are signed by known/global certificate issuers, as uploading the root certificate will cause all client certificates which are using the same root certificate to be allowed as well.

A different approach to this would be to have the following setup:

  • Create a Named Value which contains a list of thumbprints to be accepted.
  • In the APIM-policy perform the following action to validate:
    • whether a client certificate is provided
    • whether the client certificate thumbprint in the request is one of the known/accepted certificates
    • whether the certificate which has been sent along hasn't expired yet.
    <!-- Validate the client certificate in the inbound request -->
    <choose>
      <!-- Below condition verifies if the request contains a client certificate + if the certificate-thumbprint is known + if the certificate has not expired yet. -->
      <when condition="@(context.Request.Certificate == null || ("{{logicalName-clientcertificate-thumbprints}}").Split(';').Any(c => c.Equals(context.Request.Certificate.Thumbprint, StringComparison.OrdinalIgnoreCase)) == false || (context.Request.Certificate.NotBefore > DateTime.Now && context.Request.Certificate.NotAfter < DateTime.Now))">
        <return-response>
          <set-status code="403" reason="Invalid client certificate" />
        </return-response>
      </when>
    </choose>
@mbraekman mbraekman self-assigned this Oct 30, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

1 participant