Forum Discussion
Client Certificate Authentication/Certificate in header PROBLEM
Hi everyone,
I have big problem with f5. In my application I authentication users by their cert. Authentication is required in specified URL. Bellow my iRule. I have configured Client SSL Profile and connected to VIP: every options default excluding:
Client Certificate: ignore
Frequency: once
Certificate Chain Traversal Depth 9
Trusted Certificate Authorities: My_CA
Advertised Certificate Authorities: None
Certificate Revocation List (CRL): My_CRL
When I open url: "/url/no_"1 I get prompt about client certificate. This is OK. But when I choose certificate and click "OK" f5 should add and send my client cert to the application in header. F5 don't send this certificate. Header is blank. F5 add and send certificate in header after 2 redirection or when user two time refresh website. Cert should by always send in header. If header is blank application returns 401 (unauthorized).
Please help me, thank you
My irule in the order:
iRule1:
when HTTP_REQUEST {
set host [string tolower [HTTP::host]]
if { $host eq "" }
{
set host [IP::local_addr]
}
STREAM::disable
}
when HTTP_RESPONSE {
if { [HTTP::header value Content-Type] contains "text" and $host ne "" }
{
STREAM::expression "@http://$host @https://$host@"
STREAM::enable
}
if { [string tolower [HTTP::header Location]] starts_with "http://$host" }
{
HTTP::header replace Location [string map -nocase "http://$host https://$host"
[HTTP::header Location]]
}
}
iRule2:
when CLIENTSSL_HANDSHAKE {
set cur [SSL::sessionid]
set ask [session lookup ssl $cur]
if { $ask eq "" } {
session add ssl [SSL::sessionid] [SSL::cert 0]
}
}
when HTTP_REQUEST {
set id [SSL::sessionid]
set the_cert [session lookup ssl $id]
if { $the_cert != ""} {
HTTP::header insert SSL_CLIENT_CERT [X509::whole $the_cert]
}
}
iRule3:
when CLIENTSSL_HANDSHAKE {
if { [SSL::cert count] ==0 } {
}
else {
HTTP::release
}
}
when HTTP_REQUEST {
if { [HTTP::uri] starts_with "/url/no_1" or [HTTP::uri] starts_with "/url/no_2" } {
if {[SSL::cert count] == 0} {
HTTP::collect
SSL::authenticate always
SSL::authenticate depth 9
SSL::cert mode require
SSL::renegotiate
}
}
else {
}
}
2 Replies
- Kevin_Stewart
Employee
Give this a shot. It's also a combination of all of your rules, so you can replace all of them for this one:
when CLIENTSSL_CLIENTCERT { if { [SSL::cert count] < 1 } { if the client did not present a certificate - fail reject } else { set a temporary cert variable here set clientcertdata [X509::whole [SSL::cert 0]] } HTTP::release } when HTTP_REQUEST { get host header and disable STREAM set host [string tolower [HTTP::host]] if { $host eq "" } { set host [IP::local_addr] } STREAM::disable private URI space requested and F5AUTH cookie does not exist - prompt for client certificate if { not ( [HTTP::uri] equals "/favicon.ico" ) and ( [HTTP::uri] starts_with "/private" ) and not ( [HTTP::cookie exists F5AUTH] ) } { invalidate SSL and renegotiate HTTP::collect SSL::session invalidate SSL::authenticate always SSL::authenticate depth 9 SSL::cert mode require SSL::renegotiate } elseif { [HTTP::cookie exists F5AUTH] } { F5AUTH cookie exists - send HTTP header data if { [table lookup -subtable CERTDATA [HTTP::cookie value F5AUTH]] ne "" } { insert cert subject HTTP::header replace SSL-CLIENT-CERT [table lookup -subtable CERTDATA [HTTP::cookie value F5AUTH]] } } } when HTTP_REQUEST_SEND { clientside { if { ( [info exists clientcertdata] ) and not ( [HTTP::cookie exists F5AUTH] ) } { send first header HTTP::header replace SSL-CLIENT-CERT $clientcertdata } } } when HTTP_RESPONSE { process response payload with STREAM if { [HTTP::header value Content-Type] contains "text" and $host ne "" } { STREAM::expression "@http://$host @https://$host@" STREAM::enable } rewrite the redirect Location header if it exists if { [string tolower [HTTP::header Location]] starts_with "http://$host" } { HTTP::header replace Location [string map -nocase "http://$host https://$host" [HTTP::header Location]] } if the uniqueid variable is set - send the F5AUTH cookie to client if { [info exists clientcertdata] } { generate a GUID set uniqueid "_[string range [AES::key 256] 34 end]" insert the table entry table add -subtable CERTDATA $uniqueid $clientcertdata 3600 send the cookie HTTP::header insert "Set-Cookie" "F5AUTH=$uniqueid; path=/; secure; HTTPOnly" unset the clientcertdata variable unset clientcertdata } }The iRule sets a cookie and stores the cookie data in a session table entry to guarantee that a) it always exists, and b) the user doesn't have to renegotiate SSL every time they attempt to access a private URI. You'll need to modify the URI condition above for your private URI patterns.
- Marcin_01_16191
Nimbostratus
Thank you very much for your help. It works.
Help guide the future of your DevCentral Community!
What tools do you use to collaborate? (1min - anonymous)Recent Discussions
Related Content
* Getting Started on DevCentral
* Community Guidelines
* Community Terms of Use / EULA
* Community Ranking Explained
* Community Resources
* Contact the DevCentral Team
* Update MFA on account.f5.com
