3
votes

I am building a registration page using Wildfly for my application that requires users to register using their smart card. I would like to have an initial landing page that does not require any authentication, then when they access the registration page it will prompt them to select a certificate from their smart card.

I have gotten pretty close to having this work how I expect, but have hit a wall that I feel is surely due to my lack of understanding of Wildfly/JBOSS.

I have the following security domain defined in my standalone.xml

<security-domain name="client_cert_domain" cache-type="default">
                <authentication>
                    <login-module code="Certificate" flag="required">
                        <module-option name="verifier" value="org.jboss.security.auth.certs.AnyCertVerifier"/>
                        <module-option name="securityDomain" value="client_cert_domain"/>
                    </login-module>
                </authentication>
                <jsse keystore-password="secret" keystore-url="file:${jboss.server.config.dir}/Certificates/HQ/KeyStore" truststore-password="secret" truststore-url="file:${jboss.server.config.dir}/Certificates/HQ/cacerts.jks" client-auth="true"/>
            </security-domain>

and my web.xml is

<?xml version="1.0" encoding="UTF-8"?>
<web-app version="3.1" xmlns="http://xmlns.jcp.org/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd">
<security-constraint>
    <web-resource-collection>
        <web-resource-name>Registration page only</web-resource-name>
        <url-pattern>/register/*</url-pattern>
    </web-resource-collection>
    <auth-constraint>
        <role-name>User</role-name>
    </auth-constraint>
</security-constraint>

<login-config>
    <auth-method>CLIENT-CERT</auth-method>
    <realm-name>Some Name For User To See</realm-name>
</login-config>

Lastly, my jboss-web.xml

<jboss-web>
    <security-domain>client_cert_domain</security-domain>
</jboss-web>

This does almost exactly what I want. The main page doesn't require any authentication, and /register/ requires a client certificate. The only gotcha is that because this is not a registered user, they have no Roles assigned to them so the page is blocked since they are not in the "User" Role specified in the auth-constraint tag.

Is there an easy way to automatically assign a default role to any user who authenticates using client certificates without having to have them pre-defined in a roles.properties file?

1

1 Answers

5
votes

As is typical, I seem to have stumbled upon my answer shortly after posting this question.

I have been digging through all of the login modules listed here. After looking at the Identity module, I figured I would try including it after my certificate authentication and just specify the "roles" module option. So I ended up with the following.

<security-domain name="client_cert_domain" cache-type="default">
    <authentication>
        <login-module code="Certificate" flag="required">
            <module-option name="password-stacking" value="useFirstPass"/>
            <module-option name="verifier" value="org.jboss.security.auth.certs.AnyCertVerifier"/>
            <module-option name="securityDomain" value="client_cert_domain"/>
        </login-module>
        <login-module code="Identity" flag="required">
            <module-option name="password-stacking" value="useFirstPass"/>
            <module-option name="roles" value="User"/>
        </login-module>
    </authentication>
    <jsse keystore-password="Password1" keystore-url="file:${jboss.server.config.dir}/Certificates/HQ/KeyStore" truststore-password="Password1" truststore-url="file:${jboss.server.config.dir}/Certificates/HQ/cacerts.jks" client-auth="true"/>
</security-domain>

This seems to functionally do what I want. By specifying the password-stacking option on both login modules, it ensures that authentication only happens using client certificates. The second login module, Identity, simply adds the role "User" to whoever has logged in. Now when I access any resources under my protected directory specified in my web.xml, I am prompted for my certificate and allowed in.

Hopefully this will help someone else out in the future.