Client certificate per endpoint - azure-api-management

I would like to configure a self signed client certificate for a certain endpoint.
I uploaded the PFX, copied the thumbprint and added the following line under <base/> in the "Inbound processing" section:
<policies>
<inbound>
<base />
<authentication-certificate thumbprint="THUMBPRINT" />
</inbound>
<backend>
<base />
</backend>
<outbound>
<base />
</outbound>
<on-error>
<base />
</on-error>
</policies>
If I go to the browser and access the endpoint I see that the site wide SSL cert is being used and not the self signed cert for that specific endpoint.
I tried adding it under "proxy" in custom domains section but it's being by overridden by the SSL certificate in the App Service of the domain in the "Web service URL" for the API.
Any ideas?

authentication-certificate is a policy that allows APIM to use certificate to authenticate to backend service, not to client's calling APIM. Since you're testing in browser I assume that you want to setup custom domain with custom certificate, see here: https://learn.microsoft.com/en-us/azure/api-management/configure-custom-domain

Related

APIM Policy to store the public key and verify against it

I need to store the issuer signing key in keyvault and then verify the JWT against it through apim policy . How to do that ?
<policies>
<inbound>
<base />
<validate-jwt header-name="Authorization" failed-validation-httpcode="401" failed-validation-error-message="Unauthorized">
<issuer-signing-keys>
<key>123412341234123412341234</key>
</issuer-signing-keys>
</validate-jwt>
</inbound>
</policies>
Use named values and configured it to get your secret from Key Vault and then use it in the policy
<key>{{IssuerSigningKey}}</key>

Why is APIM only verifying my client certificate when it is added as both a CA Certificate and a Certificate

I'm setting up Azure API Management to secure a Logic App with a certificate. I've added the following policy to the API:
<choose>
<when condition="#(context.Request.Certificate == null || !context.Request.Certificate.Verify() || context.Request.Certificate.NotAfter<DateTime.Now || !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>
When I add the self-signed certificate, I can only make a successful call to the API when the certificate is added to both the CA certificates and Certificates. Otherwise I get an invalid certificate warning (the one from my policy) in Postman
Question I don't believe this is normal behaviour and am sure I have done something incorrect. How do I correctly add the certificate to APIM and ensure it is used correctly?
I suppose you need to remove context.Request.Certificate.Verify() policy.
This policy tries to build an X509 chain and perform some validations. Without knowing the CA it is not possible.

CORS Error in DELETE REST hosted in Azure API gateway

I am getting the following errors in the browser when trying to call a DELETE REST API hosted in Azure API Gateway and Azure function.
All other API requests (GET, POST) are working fine.
Cross-Origin Request Blocked: The Same Origin Policy disallows reading the remote resource at https://xxxx.azure-api.net/Lookup/a03aebd1c. (Reason: CORS header ‘Access-Control-Allow-Origin’ missing).
Cross-Origin Request Blocked: The Same Origin Policy disallows reading the remote resource at https://xxxxx.azure-api.net/Lookup/a03aebd1c. (Reason: CORS request did not succeed).
The Azure API gateway CORS configuration is
<policies>
<inbound>
<base />
<cors>
<allowed-origins>
<origin>https://xxxx.z13.web.core.windows.net</origin>
</allowed-origins>
<allowed-methods>
<method>GET</method>
<method>POST</method>
<method>DELETE</method>
<method>OPTIONS</method>
</allowed-methods>
</cors>
</inbound>
<backend>
<base />
</backend>
<outbound>
<base />
</outbound>
<on-error>
<base />
</on-error>
Any Advice on how to fix this issue?
The issue turned out that the CORS in global scope was set to only accept GET and POST. when I added DELETE to the global scope it worked. more details about scopes at:https://learn.microsoft.com/en-us/azure/api-management/set-edit-policies

Questions about add firewall exception in wix installer by firewall extension

I am new to Wix installer. I am trying to add firewall exception for my program.
My code is as follow:
<Component Id="_VIEW.EXE" Guid="*" Transitive="yes">
<File Id="view.exe"
Name="view.exe"
KeyPath="yes"
Source="$(var.INSTALLSOURCE)\view.exe">
<fire:FirewallException Id="view_firewall_domain_tcp"
Name="View"
Protocol="tcp"
Scope="any"
IgnoreFailure="yes"
Profile="domain" />
<fire:FirewallException Id="view_firewall_domain_udp"
Name="View"
Protocol="udp"
Scope="any"
IgnoreFailure="yes"
Profile="domain" />
<fire:FirewallException Id="view_firewall_private_tcp"
Name="View"
Protocol="tcp"
Scope="any"
IgnoreFailure="yes"
Profile="private" />
<fire:FirewallException Id="view_firewall_private_udp"
Name="View"
Protocol="udp"
Scope="any"
IgnoreFailure="yes"
Profile="private" />
</File>
</Component>
In my code, I add 4 firewall exception and each exception has different value for "Profile" and "Protocol" attributes. My expected result is 4 exceptions created:
NAME GROUP Profile Enabled Action Override Program Local Address Remote Address Protocol Local Port Remote Port Allowed Users Allowed Computers
view Domain Yes Allow No c:\test\view.exe Any Any TCP Any Any Any Any
view Domain Yes Allow No c:\test\view.exe Any Any UDP Any Any Any Any
view Private Yes Allow No c:\test\view.exe Any Any TCP Any Any Any Any
view Private Yes Allow No c:\test\view.exe Any Any UDP Any Any Any Any
But the actual result is only one exception is created and the value of "Protocol" attribute is "any" instead of "TCP" or "UDP":
NAME GROUP Profile Enabled Action Override Program Local Address Remote Address Protocol Local Port Remote Port Allowed Users Allowed Computers
view Domain Yes Allow No c:\test\view.exe Any Any Any Any Any Any Any
So, I have two questions:
Why is only one exception created? Must the name of the exception be unique?
Why does the value of the "Protocol" attribute not take effect?
I refer an official document about firewall extension:
http://wixtoolset.org/documentation/manual/v3/xsd/firewall/firewallexception.html
In the document, I saw some description about "File" attribute:
Identifier of a file to be granted access to all incoming ports and protocols. If you use File, you cannot also use Program.
If you use File and also Port or Protocol in the same FirewallException element, the exception will fail to install on Windows XP and Windows Server 2003. IgnoreFailure="yes" can be used to ignore the resulting failure, but the exception will not be added.
Does it mean that if I set firewall rule for a program, the "Protocol" and "Port" attributes will be "Any" automatically even I set "Protocol"?
The existing wix FirewallException custom actions make use of the XP/Server2003 windows firewall API. In this API, setting a firewall exception for a particular executable implies that all ports and all protocols will be opened to the exception.
For reference, the XP/Server2003 firewall API interfaces. Notice that INetFwOpenPort has the ability to get/set the port, while INetFwAuthorizedApplication does not.
If you want to create a firewall exception on a program and explicitly limit the port, protocol, and domain you'll need to make use of the windows 'advanced' firewall API that came with Vista. Check out these references:
Highlevel overview
Reference guide
Command-line reference guide
Sadly, nobody has yet implemented an AdvancedFirewallException extension for wix that makes use of these updated APIs. Maybe I'll run a kickstarter campaign to see if there interest in funding the development ;P
Try to use different Names for each FirewallExeption ID. This worked for me:
<File Id="sample.exe"
Name="sample.exe"
Source="..\TestFrame\bin\debug\sample.exe"
Vital="yes"
KeyPath='yes'>
<fire:FirewallException Id="FirewallDomainSampleTcp"
Name="Domain Sample TCP"
Protocol="tcp"
Port="8080"
Scope="any"
IgnoreFailure="yes"
Profile="domain" />
<fire:FirewallException Id="FirewallDomainSampleUdp"
Name="Domain Sample UDP"
Protocol="udp"
Port="8080"
Scope="any"
IgnoreFailure="yes"
Profile="domain" />
<fire:FirewallException Id="FirewallPrivatSampleTcp"
Name="Private Sample TCP"
Protocol="tcp"
Port="8080"
Scope="any"
IgnoreFailure="yes"
Profile="private" />
<fire:FirewallException Id="FirewallPrivateSampleUdp"
Name="Private Sample UDP"
Protocol="udp"
Port="8080"
Scope="any"
IgnoreFailure="yes"
Profile="private" />
</File>

The HTTP request is unauthorized with client authentication scheme 'Anonymous'. The authentication header received from the server was 'NTLM’

I have an ASP.NET web application written in VB.NET. One part of the application makes an AJAX call to an internal ASMX file which in turn makes a call to a remote web service which is just a single ASMX file. Normally this works fine and has been deployed a couple of times and works fine. One client however, is getting the message from the AJAX call:
The HTTP request is unauthorized with client authentication scheme
'Anonymous'. The authentication header received from the server was
'NTLM’.
I have scoured a large amount of websites trying to fix this but I can’t seem to find any answer that works for me.
I have been unable to replicate the error on my test server, which is the same as the client, Win2003 IIS6.
The remote web service is deployed on Windows 2008 r2 – IIS7.5. The remote service is deployed using ‘Anonymous’ authentication only. The client deployment is set up with Anonymous and ‘Integrated Windows Authentication’. I have tried changing the authentication levels on both implementations but cannot replicate the issue. The closest I have come is when I set the remote service IIS authentication to
The HTTP request is unauthorized with client authentication scheme
'Ntlm'. The authentication header received from the server was ''.
In the web.config file the reference to the remote service is:
<system.serviceModel>
<bindings>
<basicHttpBinding>
<binding name="SVCMappingSoap" closeTimeout="00:01:00" openTimeout="00:01:00" receiveTimeout="00:10:00" sendTimeout="00:01:00" allowCookies="false" bypassProxyOnLocal="false" hostNameComparisonMode="StrongWildcard" maxBufferSize="65536" maxBufferPoolSize="524288" maxReceivedMessageSize="65536" messageEncoding="Text" textEncoding="utf-8" transferMode="Buffered" useDefaultWebProxy="true">
<readerQuotas maxDepth="32" maxStringContentLength="8192" maxArrayLength="16384" maxBytesPerRead="4096" maxNameTableCharCount="16384"/>
<security mode="None">
<transport clientCredentialType="None" proxyCredentialType="None" realm=""/>
<message clientCredentialType="UserName" algorithmSuite="Default"/>
</security>
</binding>
</basicHttpBinding>
</bindings>
<client>
<endpoint address="http://svc.website.com/services/myService.asmx" binding="basicHttpBinding" bindingConfiguration="SVCMappingSoap" contract="SVCMappingService.SVCMappingSoap" name="SVCMappingSoap"/>
</client>
</system.serviceModel>
I have tried changing a number of the setting in the <security> section but still unable to replicate.
I am not sure of your total server setup.
<security mode="None">
<transport clientCredentialType="None" proxyCredentialType="None" realm=""/>
</security>
instead of above one please try with below configuration
<security mode="TransportCredentialOnly">
<transport clientCredentialType="Ntlm"/>
<message clientCredentialType="UserName" algorithmSuite="Default"/>
</security>
please go through below links, you can more idea on those and you can change the config based on your requirements:
http://blogs.msdn.com/b/publicsector/archive/2005/10/19/482833.aspx
http://fczaja.blogspot.com/2009/10/http-request-is-unauthorized-with.html
http://ddkonline.blogspot.com/2009/11/fix-http-request-is-unauthorized-with.html
I had to change the default generated
<security mode="Transport"/>
into
<security mode="Transport" >
<transport clientCredentialType="Ntlm"/>
</security>
One more comment for this problem:
If you are not using HTTPS,
<security mode="Transport"/>
is not supported. You can use
<security mode="TransportCredentialOnly">
instead.