REST API Authentication - dogtagpki/pki GitHub Wiki
PKI uses on Tomcat and RESTEasy for REST API authentication.
The SSL Connector in Tomcat is configured to optionally request client certificate but it will not fail if the client doesn’t provide any certificate:
<Connector name="Secure" port="8443" ... clientAuth="want" ... />
There’s a bug in Tomcat JSS so this option doesn’t work now.
See also The HTTP Connector.
In the web.xml
most REST services are configured to require certain roles. This will trigger authentication and authorization process.
<security-constraint> <web-resource-collection> <web-resource-name>Agent Services</web-resource-name> <url-pattern>/rest/agent/*</url-pattern> </web-resource-collection> <auth-constraint> <role-name>*</role-name> </auth-constraint> ... </security-constraint>
In the context.xml
each PKI Web application is configured with an authenticator and a realm:
<Context crossContext="true" allowLinking="true"> <Valve className="com.netscape.cms.tomcat.SSLAuthenticatorWithFallback" /> <Realm className="com.netscape.cms.tomcat.ProxyRealm" /> </Context>
The fallback authenticator will authenticate the user certificate if it’s provided. Otherwise it will request username and password. The actual authentication will be performed by the realm.
Tomcat requires that the classes for the authenticator and the realm must be stored in common/lib. The problem is the PKI classes that do the authentication are stored in the WEB-INF/lib
, which is not accessible directly by the realm. To address this problem, a ProxyRealm
is created in common/lib
to satisfy Tomcat’s requirement and a PKIRealm
is created in WEB-INF/lib
to execute the actual authentication. When the Web application is started, the ProxyRealm
will be linked to the PKIRealm
(see CMSStartServlet.java
below). The ProxyRealm
will then forward any incoming authentication request to the PKIRealm
.
// Register realm for this subsystem String context = getServletContext().getContextPath(); if (context.startsWith("/")) context = context.substring(1); ProxyRealm.registerRealm(context, new PKIRealm());
See also The Realm Component.