5
votes

I am working on a very simple Java application that needs to be secured with a username and password. I have to use Active Directory for the authentication. I can only allow authenticated users to access it. I do not need any kind of group/role checking to determine what the users may see or not. I'm using JETTY to run the application.

I've been trying for quite some time now to implement the LDAP Login Module with Jetty. But every time I submit the login form, I get a 403 error with the "!role" message.

HTTP ERROR 403

Problem accessing /JAAS/. Reason:

    !role

Jetty standard output when I submit the login form:

2013-07-18 19:28:47.035:INFO:oejpjs.LdapLoginModule:Searching for users with filter: '(&(objectClass={0})({1}={2}))' from base dn: DC=mydomain,DC=test,DC=local
2013-07-18 19:28:47.041:INFO:oejpjs.LdapLoginModule:Found user?: true
2013-07-18 19:28:47.042:INFO:oejpjs.LdapLoginModule:Attempting authentication: CN=User Name,OU=ADMIN_HOME,DC=mydomain,DC=test,DC=local

Jetty log file when I submit the login form (the username I entered appears in the log, so a part of the authentication seems to work):

0:0:0:0:0:0:0:1 -  -  [18/Jul/2013:17:28:38 +0000] "GET /JAAS/ HTTP/1.1" 302 0 
0:0:0:0:0:0:0:1 -  -  [18/Jul/2013:17:28:38 +0000] "GET /JAAS/login.html HTTP/1.1" 304 0 
0:0:0:0:0:0:0:1 -  -  [18/Jul/2013:17:28:47 +0000] "POST /JAAS/j_security_check HTTP/1.1" 302 0 
0:0:0:0:0:0:0:1 - username [18/Jul/2013:17:28:47 +0000] "GET /JAAS/ HTTP/1.1" 403 1362 

Extract of the web.xml where security-constraint and security-roke are declared:

<security-constraint>
    <web-resource-collection>
         <web-resource-name>Entire Application</web-resource-name>
         <url-pattern>/*</url-pattern>
    </web-resource-collection>

    <auth-constraint>
       <role-name>*</role-name>
    </auth-constraint>
  </security-constraint>

    <security-role>
        <role-name>*</role-name>
    </security-role>

    <security-role>
        <role-name>Domain Users</role-name>
    </security-role>

    <security-role>
        <role-name>MyLocalGroup</role-name>
    </security-role>

LDAP Login module configuration file (ldaploginmodule.conf):

myloginmodule {
   org.eclipse.jetty.plus.jaas.spi.LdapLoginModule required
   debug="true"
   debugNative="true"
   contextFactory="com.sun.jndi.ldap.LdapCtxFactory"
   hostname="ldapserver"
   port="389"
   bindDn="CN=Administrator,CN=Users,DC=mydomain,DC=test,DC=local"
   bindPassword="secret"
   directGroupExtraction="true"
   userGroupAttribute="cn"
   allRolesMode="authOnly"
   userFilter="(objectClass=organizationalPerson)"
   authenticationMethod="simple"
   forceBindingLogin="true"
   userBaseDn="DC=mydomain,DC=test,DC=local"
   userRdnAttribute="cn"
   userIdAttribute="sAMAccountName"
   userPasswordAttribute="unicodePwd"
   userObjectClass="user"
   roleSearch="(member={0})" 
   roleName="cn" 
   roleSubtree="true"
   roleBaseDn="CN=Users,DC=mydomain,DC=test,DC=local";
   };

Jetty realm configuration (my-jaas.xml):

<Configure id="Server" class="org.eclipse.jetty.server.Server">

    <!-- JAAS TEST -->
    <Call name="addBean">
       <Arg>
          <New class="org.eclipse.jetty.plus.jaas.JAASLoginService">
             <Set name="Name">Test JAAS Realm</Set>
             <Set name="LoginModuleName">myloginmodule</Set>

             <Set name="roleClassNames">
                <Array type="java.lang.String">
                   <Item>org.eclipse.jetty.plus.jaas.JAASRole</Item>
                </Array>
             </Set>

          </New>
      </Arg>
    </Call>

</Configure>

Finally, the jetty startup command:

java -Xdebug -Djava.naming.referral=follow -Djava.security.auth.login.config=etc/ldaploginmodule.conf -jar start.jar etc/my-jaas.xml

I checked the Windows Security event log and I do see a successful audit entry for a logon for the user I provided in the login form.

The thing is, I don't need any role. I just want to perform authentication and allow all authenticated users to access the application.

Any idea how I could have authentication only and avoid roles? I was thinking about overriding the LdapLoginModule class and force a 'dummy' role that I would declare in web.xml. But I'm not sure if this is the right way to do it.

2

2 Answers

0
votes

Your authentication is successful.

Since you want to allow all authenticated users to access everything, you still need to protect the URL pattern /* as you are doing. You can use the RegExpAuthorizationFilter (see https://wiki.apache.org/solr/SolrSecurity). Now, they don't include this class in the regular distribution. I found the code here (https://issues.apache.org/jira/secure/attachment/12572819/SOLR-4470_branch_4x_r1454444.patch) and it compiled easily.

When you configure the filter, specify one arbitrary (non-existent, like /abcde) URL pattern with any role. The way it works is that it will see if the URL being requested matches this pattern. Since it doesn't, it moves forward. But there are no more rules, and access is allowed.

So it requires authentication for all URLs but all valid URLs will be accessible after successful authentication.

My setup was in the context of solr running on Jetty. However, I think all my configuration was tied to the standard stuff such as web.xml.

0
votes

You need to modify web.xml to use the special role ** as indicated here: Authorization section for Jetty Authentication:

access granted to any user who is authenticated, regardless of roles. This is indicated by the special value of "**" for the <role-name> of a <auth-constraint> in the <security-constraint>

So, this is what my security-constraint looks like:

<security-constraint>
  <web-resource-collection>
    <web-resource-name>Secured Solr Admin User Interface</web-resource-name>
    <url-pattern>/*</url-pattern>
  </web-resource-collection>
  <auth-constraint>
    <role-name>**</role-name>
  </auth-constraint>
</security-constraint>