Select clientssl profile based on uri pattern
Hello everyone, I need some help with this scenario. I've found similar questions and suggestions from devcentral memebers but I'm stuck and haven't been able to come up with a solution.
I have an API Management solution published through a single Virtual Server in my BigIP. There are several API's present on this solution and I would like to enforce client authentication with SSL\TLS certificates, but requiring a specific certificate depending on which API they will be requesting.
In other words, if I have a single VS where I
if the request is to: myapidomain.com/api-companyA, then I want to request the client certificate of Company A
if the request is to: myapidomain.com/api-companyB, , then I want to request the client certificate of Company B
if the request is to: myapidomain.com/general-public-api, then I don't want to use client authentication, just present the server certificate
I think that it all comes down to choosing a different clientssl profile based on the uri pattern, but:
- I can only inspect the http request after the TLS negotation has been completed using the default ssl profile of the VS
- I cannot use the command to change the ssl profile inside the HTTP REQUEST event
I have seen some related questions where they suggest to do something like this. But they are changing the current ssl profile to request client authentication, instead of changing the ssl profile. For testing purposes, I have setup two client ssl profiles, each of them requiring client authentication but using different self signed certificates.
when HTTP_REQUEST {
switch -glob [HTTP::path] {
"/api-companyA" {
HTTP::collect
SSL::session invalidate
SSL::authenticate always
SSL::authenticate depth 9
SSL::cert mode require
SSL::renegotiate
// Another post suggested using SSL::profile here to change the profile, but it is not allowed inside HTTP REQUEST
}
"/api-companyB" {
HTTP::collect
SSL::session invalidate
SSL::authenticate always
SSL::authenticate depth 9
SSL::cert mode require
SSL::renegotiate
}
}
}
Would it be possible to use a flag variable for this? For example, start with a default value, change it within the HTTP_REQUEST event based on the URI, force an SSL\TLS renegotiation and then in a CLIENT_ACCEPTED event use the value of that variable to set the profile? I tried something like this but it seems that the CLIENT_ACCEPTED method does not fire after the SSL::renegotiate command is issued.
when RULE_INIT {
set ::count 0
}
when CLIENT_ACCEPTED {
if {$::count == 1} {
SSL::profile profile_with_client_authentication_companyA
}
}
when HTTP_REQUEST {
switch -glob [HTTP::path] {
"/supervielledev/public-partners/myloopbackapi" {
set ::count 1
SSL::renegotiate
}
"/supervielledev/public-partners/myotherloopbackapi" {
set ::count 2
SSL::renegotiate
}
}
}
Thanks in advance.