Version 46


    JBoss Negotiation

     

    Use ^^^^



    Note from Anil Saldhana, JBoss Security and Identity Management.

     

    Users stop disfiguring this page if something does not work. We know that Kerberos/spnego stuff is critical for you. But this page shows some prototypical work that is not endorsed by us. So you are on your own. We are however formalizing our kerberos offering.

     

    UPDATE_APRIL_2008: We should be releasing a beta version of our JBoss Negotiate library this month (hopefully toward the end of April 2008)

     

    This page is still a work in progress.  The information here should be considered alpha quality right now!

     

    UPDATE_JUNE_2008: Please see JBossNegotiation for further information on the new authenticator to handle SPNEGO negotiation.

     

    Silent Authentication

     

    Unified authentication has been the holy grail of security implementations for some time now.  Users have a plethora of user names/passwords to try and remember for the various systems the need to use on a day to day basis.  The goal of this page is to document a few recipes that can be used to get web clients authenticating with web servers, and application servers using Negotiate.  Futhermore, it is intended that this authentication be done silently so that the user simply has to log into their operating system once, and then that information can be used to authenticate the user on the web.

     

    This page will be Wintel centric for now, since I don't have a lot of knowledge of Linux + Kerberos right now, and I have a specific question about getting this to work with Windows first.  Sorry.

     

    The scenario I wanted to try out first is that of Internet Explorer 6.0 and Tomcat inside JBoss AS against a Windows 2000 domain.  IE 6.0 supports Negotiate authentication right out of the box, so that should allow me to focus on getting Tomcat working properly.  Also, Internet Explorer will silently try to use the current user id and password for authentication if the security settings in IE are set up properly.  Firefox/Mozilla has a plugin to allow Negotiate authentication, but there aren't any win32 binaries for it, and I don't want to compile it myself right now.  I'll tackle throwing IIS or Apache into the mix later as well.

     

    update11-2006

     

    When using Apache httpd with SSL in front of Tomcat you should note that you will get a problem with this standard setting  (a keepalive connection is needed for the authentication..):

    SetEnvIf User-Agent ".*MSIE.*" \
            nokeepalive ssl-unclean-shutdown \
            downgrade-1.0 force-response-1.0
    

    If you remove it, you can authenticate but will face problems with your application (like not beeing able to upload documents, get kicked out of the session ocasionally..)

    Perhaps this will get better with IE7?

     

    --end of update

     

     

    Currently, this library is using RAP to get group information for NTLM type authentications.  This method only works sometimes for Windows 2000 domains, but is supposed to work pretty well for earlier domains.  Once I've gotten SPNEGO and PAC implemented properly, then this shouldn't be an issue on Windows 2000 and later domains.

     

    For the following example, I originally used JBoss 4.0.2 and I created a copy of the default server configuration to work with so I wouldn't break that instance.

     

    (I've attached the necessary jars to this wiki page so that you don't need to go download and compile stuff.)

     

    Negotiate Authentication on Tomcat in JBoss AS

     

    1. (You can use jcifs-1.2.3_spnego.jar on this page instead of downloading)  Get jCIFS and apply the SPNEGO patch.  It looks like the patch doesn't actually change any of the jCIFS classes, so it should work with most versions of jCIFS.

     

     

    update11-2006

     

    If you have some more complex network configuration (many interfaces/IP addresses) you might want to try jcifs version 1.2.9 in which those kind of problems are solved

     

    -end of update-

     

     

    Copy this patched library to the lib directory of the server you want to use Negotiate with.

     

    (You can use jcifs-ext-1.2.3.jar on this page instead of downloading) You will also need jcifs-ext for getting group information for users in embedded NTLM authentications.  You can get that library from here.  You also need to copy that library to the lib directory of the server above.

     

    2. Copy the negotitate-src.jar file that I've attached to this wiki, and copy it to the lib directory of the server you copied the jCIFS jar to.

     

    3. Modify the ${jboss.server.dir}/conf/jboss-service.xml (if you installed via the JBoss Installer Jar, then the file you need to edit is ${jboss.server.dir}/deploy/security-service.xml) in the server you copied the jars to.  You need to change the "jboss.security:service=JaasSecurityManager MBean" to use the new callback handler included with the negotiate jar.  You need to find the mbean definition in the file, and add or change the CallbackHandlerClassName attribute to be the following:

          <attribute name="CallbackHandlerClassName">org.jboss.web.tomcat.security.AdvancedWebCallbackHandler</attribute>
    
      • for 4.04 you may need to use ${jboss.server.dir}/deploy/security-service.xml) event it is not installed using the JBoss Installer Jar.

      • for 4.05 you may need to  use ${jboss.server.dir}\deploy\security.sar\META-INF\jboss-service.xml

     

    4. Create a new security domain in the ${jboss.server.dir}/conf/login-config.xml for the Negotiate domain.  I used the following in my example application:

         <!-- SPNEGO test -->
         <application-policy name = "SPNEGO">
           <authentication>
                <login-module code="org.jboss.security.auth.NegotiateLoginModule"
               flag = "required">
                  <module-option name="loadBalance">false</module-option>
                  <module-option name="domainController">CHRISSPENGGO</module-option>
                  <module-option name="defaultDomain">TEST</module-option>
                </login-module>
            </authentication>
         </application-policy>
    
    

     

    You will need to replace the domainController option with an actual Windows domain controller to authenticate against, and the defaultDomain to the domain that will be appended to the user id if none is given.

     

    5. Create a web application, or use the example WAR that I've attached to the wiki page, and deploy it to the server you put the above jars into.

     

    If you don't already have an application that you want to secure, you will need to create one.  I just created a small application with one static index.html at the root of the application for testing.  Also, I made sure to have a web.xml file that specified security constraints for the page.  I used this in the example application:

    <?xml version="1.0"?>
    <!DOCTYPE web-app PUBLIC
       "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
       "http://java.sun.com/dtd/web-app_2_3.dtd">
    <web-app>
          <security-constraint>
               <web-resource-collection>
                    <web-resource-name>All</web-resource-name>
                    <url-pattern>/*</url-pattern>
                    <http-method>GET</http-method>
                    <http-method>POST</http-method>
               </web-resource-collection>
               <auth-constraint>
                    <role-name>JBossAdmin</role-name>
               </auth-constraint>
          </security-constraint>
       
          <login-config>
            <auth-method>Negotiate</auth-method>
         <realm-name>Test Realm</realm-name>
          </login-config>
       
          <security-role>
             <role-name>JBossAdmin</role-name>
          </security-role>
    
    </web-app>
    

     

    You need to include a context.xml file in the WEB-INF directory of the web application that contains the valve definition for the NegotitateAuthenticator.  That file looks like this:

    <Context>
         <Valve className="org.jboss.web.tomcat.security.HttpServletRequestResponseValve" ></Valve>
    </Context>
    

     

    Finally, you need to include a jboss-web.xml file in the WEB-INF directory of the web application that attaches the security domain we defined above to the web context.  I used this in the example:

    <?xml version='1.0' encoding='UTF-8' ?>
     
    <!DOCTYPE jboss-web
        PUBLIC "-//JBoss//DTD Web Application 2.3V2//EN"
        "http://www.jboss.org/j2ee/dtd/jboss-web_3_2.dtd">
    
    <jboss-web>
      <security-domain>java:/jaas/SPNEGO</security-domain>
    </jboss-web>
    

     

    6. Create a group in the Domain/Active Directory called JBossAdmin, and a user that is part of that group.

     

    7. Log in to a workstation that is part of your Domain using the above user.  Try to access your application with IE.

     

    Figure out what zone your server is in by looking at the lower left area of the status bar when you try to go to an unprotected resource on that server.  You need to make sure that automatic authentication is set for the zone that the site is in.

     

    I made sure that there wouldn't be any problems by adding my server to the Trusted sites zone in IE, and then ensuring that the Trusted sites zone's security level allowed automatic logins.  You can verify this by either setting the Trusted sites security level to "Low" security, or customizing the security level, and setting the User Authenticate/Login property to "Automatic Login with current username and password".

     

    Also, I made sure to set the Security/Enable Integrated Windows Authentication setting in the Advanced tab of Internet Explorer's options.

     

    Try to go to your site, and it should authenticate you silently, and automatically!

     

     

    update-11-2006-

     

    you might want to have your LoginModule and CallBackHandler also do the following for you:

     

    1.) CallbackHandler: within the last else, when no appropriate CallBack has been found:

     

      headerSent=true;
      super.handle(callbacks);
    

    Then the normal CallbackHandler will do the handling, thus you can then still use your "normal" loginmodules within the same server instance.

     

    2.) LoginModule: at the end of login(), when authentication seems succesful

     

    if (_principal.getName().toLowerCase().startsWith(defaultDomain.toLowerCase()+"\\")) {
         super.loginOk = true;
         return true;
    } else {
            log.debug("Wrong domain!!! (User " + _principal.getName() + ") - DefaultDomain " + defaultDomain );
            return false;
    }
    

    If you don�&130;´t do something like this, requests even from the domain "null" are valid..

     

     

    ---end-of-update

     

     

    Silent Authentication using Kerberos

     

    The previous instructions support doing silent NTLM authentication, which is the fall back method this authentication module will resort to.  To enable true Kerberos authentication, you need to create a Kerberos service principal in the active directory for the server.  I followed a modified form of the "Setting up the Web Server" instructions on this page: http://www.onlamp.com/pub/a/onlamp/2003/09/11/kerberos.html?page=2.  Basically you need to associate an Active Directory user with the server using the ktpass utility provided on the Windows 2000 Server Resource CD.  I don't know if Windows 2003 Server has this installed by default or not.  Also, you shouldn't have to do anything with the keytab file.

     

    Once this is done, IE will suddenly recognize that the server it is trying to authenticate to is a Kerberos service principal, and send the proper Kerberos info to the server for authentication.  Should look the same from the UI persepective, but a slightly different path on the back end.

     

    !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

    If Silent Authentication is not working properly and if you see 'No Role Found' error message in 'server.log',   please refer to a work-around at http://www.jboss.com/index.html?module=bb&op=viewtopic&p=39895673989567

    !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

     

     

    -


     

    TODO: Protect an EJB resource.

     

    TODO: Attempt EJB resource from application client.