Apache Configuration
Basic Configuration
Beside the SSL server certificate configuration the SSLVerifyClient directive is required to ask for a client certificate. For the WebID use case the parameter optional_no_ca is required. The client may present now a certificate, but it's not validated against a CA.
<VirtualHost *:443> ... SSLVerifyClient optional_no_ca </VirtualHost>)
SSL Variables
Only if the SSLOptions +StdEnvVars +ExportCertData are set the SSL variables are accessible for other modules.
The following example also checks whether the files extension is .phtml or .php. That may be usefull to reduce the overhead for page requests that don't care about the additional data.
<FilesMatch "\.(phtml|php)$"> SSLOptions +StdEnvVars +ExportCertData </FilesMatch>
Renegotation
Single resources or directories can ask for client certificates by putting the SSLVerifyClient directive into the Location or Directory context. It's also possible to use the .htaccess file. Now Apache will use SSL renegotation.
In the following example only the resource https://www.example.org/login-webid will ask the client to present a certificate.
<VirtualHost *:443>
   DocumentRoot /var/www/www.example.org/
   ...
   <Location /login-webid>
      SSLVerifyClient optional_no_ca
   </Location>
</VirtualHost>
Authentication Hinting
With the Accept-Authentication HTTP header property a resource, that would usually not ask for a certificate, can be accessed with WebID in a RESTful way. The trick is to redirect all requests with the Accept-Authentication: WebID property to a specific directory which is WebID protected. Apache offers the possibility to use internal redirects that aren't visible to the user. The Alias directive links the content of the root folder to the /webid directory.
In the following example the user sends a request for https://www.example.org/test. Internal the request get's redirected to https://www.example.org/webid/test.
| physical folder | internal URL | visible URL | |
|---|---|---|---|
| without Accept-Authentication: WebID | /var/www/www.example.org/test | https://www.example.org/test | https://www.example.org/test | 
| with Accept-Authentication: WebID | /var/www/www.example.org/test | https://www.example.org/webid/test | https://www.example.org/test | 
<VirtualHost *:443>
   ...
   Alias /webid /var/www/www.example.org/
   <Location /webid>
      SSLVerifyClient optional_no_ca
   </Location>
   RewriteEngine on
   RewriteBase /
   # don't redirect if we are already in /webid/
   RewriteCond %{REQUEST_URI} !^/webid/.*
   # only redirect if the header property Accept-Authentication contains WebID
   RewriteCond %{HTTP:Accept-Authentication} ^WebID$
   # redirect to /webid/* and don't follow further rewrite rules
   RewriteRule $ /webid%{REQUEST_URI} [L]
</VirtualHost>