Introduction
I'm using PHP 5.6 and Apache 2.4 in the back-end of my web site where I use SSL to authenticate clients as an optional form of entering the site. I want to get some SSL_CLIENT_* variables which are contained in the certificate but aren't being shown by Apache 2.4, therefore, I cannot access them using $_SERVER
.
Description
I want to get the following environment variables from the client certificate:
- SSL_CLIENT_S_DN_CN
- SSL_CLIENT_SAN_OTHER_msUPN_0
- SSL_CLIENT_SAN_Email_0
When I dump $_SERVER
in PHP 5.6 I can see what is returned by the variable SSL_CLIENT_VERIFY
. If it returns GENEROUS
, all three variables are shown; if it is SUCCESS
only the first on the list above, SSL_CLIENT_S_DN_CN
, is shown; and, if SSL_CLIENT_VERIFY
is NONE
, there is no certificate supplied by the client.
I used XAMPP v3.2.2 on Windows 10 (Apache 2.4 and PHP 7.0) locally and I can access all the variables, but, somehow, I cannot do the same using a remote Debian 9 server running Apache 2.4 and PHP 5.6.
I tried unsuccessfully to set up the SSLRequire
(which is deprecated according to the docs - mod_ssl) option and Require as well.
I resorted to StackOverflow and ServerFault search for similar questions, involving SSL client certificates, but all the questions I came across involve SSL basic configuration (HTTP to HTTPS, Proxy, etc.) and creating headers with existing environment variables, like SSLRequire that works this way, for what I understood by reading the docs.
In the default-ssl.conf
I tried to set the headers using the variables, but when I do the following:print_r(getallheaders());
PHP 5.6 returns NULL
:Array ( [...] [SSL_CLIENT_SAN_OTHER_msUPN_0] => (null) [SSL_CLIENT_SAN_Email_0] => (null) )
The question again is how to get the variables SSL_CLIENT_SAN_OTHER_msUPN_0
and SSL_CLIENT_SAN_Email_0
from the client certificate.
Attachments
- My Apache 2.4 SSL configuration file:*
default-ssl.conf
<VirtualHost *:443>
ServerName myserver.name #Omitted
RequestHeader set SSL_CLIENT_SAN_OTHER_msUPN_0 "%{SSL_CLIENT_SAN_OTHER_msUPN_0}s"
RequestHeader set SSL_CLIENT_SAN_Email_0 "%{SSL_CLIENT_SAN_Email_0}s"
ServerAdmin webmaster@localhost
DocumentRoot /var/www/html
# Configuracoes de cache
Header set Cache-Control "max-age=0, no-cache, no-store, must-revalidate"
Header set Note "Cache desabilitado no servidor/host"
ErrorLog ${APACHE_LOG_DIR}/error.log
CustomLog ${APACHE_LOG_DIR}/access.log combined
# Configuracao do SSL
SSLEngine on
# [...] Certificados AC e certificados da aplicacao: OMITTED
SSLOptions +StdEnvVars +OptRenegotiate -StrictRequire +FakeBasicAuth -ExportCertData
# Solicita certificado SSL/TLS do cliente
SSLVerifyClient optional_no_ca
SSLVerifyDepth 3
<FilesMatch "\.(cgi|shtml|phtml|php)$">
SSLOptions +OptRenegotiate -ExportCertData -StrictRequire +FakeBasicAuth +StdEnvVars
</FilesMatch>
<Directory /usr/lib/cgi-bin>
SSLOptions +StdEnvVars
</Directory>
BrowserMatch "MSIE [2-6]" \
nokeepalive ssl-unclean-shutdown \
downgrade-1.0 force-response-1.0
BrowserMatch "MSIE [17-9]" ssl-unclean-shutdown
</VirtualHost>
- PHP 5.6 file*
index.php
<?php //index.php
// Get client certificate data
$cn = $_SERVER['SSL_CLIENT_S_DN_CN'];
$email = $_SERVER['SSL_CLIENT_SAN_Email_0'];
$id = $_SERVER['SSL_CLIENT_SAN_OTHER_msUPN_0'];
$client_certificate_data = [
'cn' => $cn,
'email' => $email,
'id' => $id
];
echo json_encode(
$client_certificate_data,
JSON_NUMERIC_CHECK
);
// Output: {"cn":"EXAMPLE CN CONTENT HERE","email":null,"id":null}
2条答案
按热度按时间ljo96ir51#
Apache指令SSLOptions +StdEnvVars将SSL信息作为环境变量传递给Php。更多信息请参见以下链接:
Using SSL Client Certificates with PHP和SSL选项指令
bvn4nwqk2#
如果
SSL_CLIENT_VERIFY
被设置为NONE
,则意味着客户端没有发送证书。在这种情况下,当然不能提供关于客户端证书的信息。在所有其他情况下,您应该获得
SSL_CLIENT_S_DN_CN
。只有当客户端证书包含SAN条目时,您才会获得SSL_CLIENT_SAN_*
,即您看到的差异可能是由于使用了不同的客户端证书。