We apologize for untranslated text, you can use the Google Translation button to get an automatic translation of the web page in the language of your choice.

Windows Authentication - Waffle Plugin 3.0

Description

This plugin provide Single Sign On (SSO) for Windows clients using SPNEGO (NTLM & Kerberos) protocols.


Installation

1. Introduction

The "Windows Authentication - Waffle" plugin adds support for SPNEGO (NTLM & Kerberos) based authentication in order to provide Single Sign On (SSO) for Windows clients.

 

Requirements

  • This plugin relies on native Windows implementation and the application server must be installed on a Windows operating system connected to the domain.
  • LDAP must be enabled in JCMS and properly configured using your Active Directory server.
  • Application server must be run using Windows' Local System account or preferably Network Service account
  • If you use Tomcat with Apache/mod_jk or IIS/isapi_redirect, make sure to use the latest version of the JK connector mod_jk/isapi_redirect. You must use version 1.2.32 or higher.
  • Keep-Alive must be enabled on servers.

 

Principle

  1. The user opens a Windows session on his PC.
    His authentication occurs using a Windows Domain and an Active Directory server.
  2. User connects to JCMS using his browser which automatically communicate the users' credential (see client side configuration for more detailed on this matter)
  3. The internal Authentication Handler bundled in the Waffle plugin receives the credential through the Waffle filter and sets the authenticated member (synchronizing it from LDAP/Active Directory if required).

 

2. Installation

2.1 Server Side configuration : LDAP / Active Directory

Make sure LDAP is enabled and configured to connect to your Active Directory server.
Try to connect to JCMS with one of your ActiveDirectory user accounts to make sure the connection and the synchronisation work properly.

2.2 Server Side configuration : WaffleHttpFilter

Configure WaffleHttpFilter in your web.xml as follows :

Important: Make sure the <filter> and <filter-mapping> sections of the WaffleHttpFilter are added BEFORE all other <filter> and <filter-mapping> sections already existing in the web.xml.
This is especially required for the InitFilter. Indeed, the authentication is retrieved by JCMS in the InitFilter, thus the WaffleHttpFilter must have been invoked prior to the InitFilter.

A typical configuration will be the following :

       
       <filter>
         <filter-name>WaffleHttpFilter</filter-name>
         <filter-class>com.jalios.jcmsplugin.waffle.WaffleHttpFilter</filter-class>
         <init-param>
             <param-name>principalFormat</param-name>
             <param-value>fqn</param-value>
         </init-param>
         <init-param>
             <param-name>roleFormat</param-name>
             <param-value>both</param-value>
         </init-param>
         <init-param>
             <param-name>allowGuestLogin</param-name>
             <param-value>false</param-value>
         </init-param>
         <init-param>
             <param-name>impersonate</param-name>
             <param-value>false</param-value>
         </init-param>
         <init-param>
             <param-name>securityFilterProviders</param-name>
             <param-value>
              waffle.servlet.spi.NegotiateSecurityFilterProvider
             </param-value>
         </init-param>
         <init-param>
             <param-name>waffle.servlet.spi.NegotiateSecurityFilterProvider/protocols</param-name>
             <param-value>
              Negotiate
              NTLM
             </param-value>
         </init-param>
       </filter>
       
       [...]
       
       <filter-mapping>
         <filter-name>WaffleHttpFilter</filter-name>
         <url-pattern>/*</url-pattern>
       </filter-mapping>
       
     

Be aware that once this filter is configured, a Windows authentication will be asked and required, no other authentication will be possible, unless you configure the plugin as explained in section 3.1 Using both Windows authentication and other JCMS authentications.

 

2.3 Server Side configuration : Java Application Server and HTTP Server

SPNego and Kerberos protocols require very large HTTP headers values.
In order for those HTTP headers to be received properly from the browser, it is necessary to increase the default limit of most Application Server.
If this configuration is not properly done, some clients will see HTTP errors "400 bad request" and "413 Request entity too large" as explained in great details in the Microsoft blog post : Microsoft Technology - Kerberos Authentication Problem with Active Directory

The following configuration applies to Apache HTTPD, with mod_jk, and the AJP or HTTP connector on Apache Tomcat. If you are using any other Application Server and HTTP server connector, check its documentation to ensure HTTP headers limits are configured properly.

The value of 15360 bytes is arbitrarily used in all examples bellow as it exceeds the maximum HTTP header size used during SP Nego protocol (as indicated in the the Apache HTTPD documentation).
You may want to fine tune this value depending on your architecture.

2.3.1. Apache Tomcat : maxHttpHeaderSize

Add attribute maxHttpHeaderSize on the HTTP connector in server.xml file of Apache Tomcat

  maxHttpHeaderSize="15360"

Cf http://tomcat.apache.org/tomcat-6.0-doc/config/http.html

2.3.2. mod_jk / AJP : max_packet_size/packetSize

When using mod_jk and AJP protocol between Apache HTTPD and Apache Tomcat, the packet size used by the AJP protocol between both sides must be modified using a bigger value, identical on both sides !

a) Apache HTTPD : add attribute max_packet_size in the workers.properties file

  worker.myworker.max_packet_size=15360

Cf http://tomcat.apache.org/connectors-doc/reference/workers.html

b) Apache Tomcat : add attribute packetSize on the AJP connector in server.xml file

  packetSize="15360"

Cf http://tomcat.apache.org/tomcat-6.0-doc/config/ajp.html

2.3.3. Apache HTTPD : LimitRequestFieldSize and Keep-Alive

Add the LimitRequestFieldSize on all virtual host (HTTP and HTTPS)

  LimitRequestFieldSize 15360

Cf http://httpd.apache.org/docs/2.2/mod/core.html#limitrequestfieldsize

Also, make sure Keep-Alive is enabled (which is the default configuration) 

  KeepAlive On

http://httpd.apache.org/docs/2.2/mod/core.html#keepalive 

2.4 Client Side configuration

Most internet browsers requires custom configuration in order for Windows authentication to be sent to remote HTTP server.

2.4.1 Microsoft Internet Explorer

The domain of the HTTP server must be added to the local intranet security zone, and the option "Automatic logon only in Intranet zone" must be enabled.

You can configure Internet Explorer by completing the following procedure on each client computer.
You can also configure these settings by using Group Policy. By using Group Policy, you can configure client computers without having to log on to each computer.

To configure Internet Explorer for automatic logon

  1. Open the Internet Options dialog box by choosing Internet Options either from Control Panel or from the Tools menu in Internet Explorer.
  2. In the Internet Options dialog box, on the Security tab, select Local intranet, and then click Custom Level.
  3. In the Security Settings dialog box, under Logon, select Automatic logon only in Intranet zone, and then click OK.
  4. In the Internet Options dialog box on the Security Settings tab with Local intranet still selected, click Sites.
  5. In the Local intranet dialog box, click Advanced.
  6. In the next dialog box (also titled Local intranet), type the URL of your JCMS web site (for example, https://intranet.mycompany.com) in the Add this Web site to the zone box, and then click Add.
  7. In the Local intranet dialog, box click OK.
  8. In the original Local intranet dialog box, click OK.
  9. In the Internet Options dialog box, click OK.

To configure Internet Explorer for automatic logon by using Group Policy

  1. Open the Group Policy Management Console, and then either create a new Group Policy Object (GPO) or edit an existing GPO.
  2. Expand Computer Configuration, expand Policies, expand Administrative Templates, expand Windows Components, expand Internet Explorer, expand Internet Control Panel, and then clickSecurity Page.
  3. In the details pane, double-click Site to Zone Assignment List.
  4. In the Site to Zone Assignment List Properties dialog box, click Enabled.
  5. In the Site to Zone Assignment List Properties dialog box, click Show.
  6. In the Show Contents dialog box, click Add.
  7. In the Add Item dialog box, type the URL of your JCMS web site (for example, https://intranet.mycompany.com) in the Enter the name of the item to be added box.
  8. Type 1 (indicating the local intranet zone) in the Enter the value of the item to be added box, and then click OK.
  9. In the Show Contents dialog box, click OK.
  10. In the Site to Zone Assignment List dialog box, click OK.
  11. In the Group Policy Management Editor, click Intranet Zone.
  12. In the details pane, double-click Logon options.
  13. In the Logon options Properties dialog box, click Enabled.
  14. In the Logon options list, click Automatic logon only in Intranet zone, and then click OK.
  15. Close the Group Policy Management Editor.

For more information, read :

2.4.2 Google Chrome

Google chrome uses Internet Explorer configuration, and is automatically configured to send the proper credential if Internet Explorer is correctly configured.
Read Chromium.org - HTTP authentication for more information.

2.4.3 Mozilla Firefox

The domain of the HTTP server must be added to the trusted domain for Negotiate authentication, using preference network.negotiate-auth.trusted-uris, either through about:config (in address bar) or in prefs.js (in user profil directory).
Read Mozilla.org - Integrated Authentication for more information.

2.5 Migrating from "Windows SSO NTLM plugin"

If you were using the "Windows SSO NTLM plugin", follow this simple steps to migrate your installation to this new plugin :

  1. Check your architecture meets the Requirements
  2. Configure web.xml
    • Configure the Waffle servlet filter as explained in section 2.2 Server Side configuration : Waffle,
    • Migrate servlet configuration for JSync : 
      Contrary to the NTLM plugin, the Waffle plugin is fully compatible with JSync by using only the simple wildcard mapping /*, no other configuration is required. Therefore, if you had performed advanced configuration of NTLM servlet filter for JSync compatibiliy, you are advised to use the simpler and safer wildcard mapping.
    • Migrate custom access rules if any : 
      If you had any custom access rules configured for the NtlmHttpFilter in web.xml, recopy the configuration as is in the new WaffleHttpFilter. Then replace old package namecom.jalios.jcmsplugin.ntlm.rules with com.jalios.jcms.authentication.rules.
  3. Cleanup
    • Remove all reference to the NTLM servlet filter and JCIFS from your web.xml,
    • Uninstall the NTLM Plugin from JCMS,
  4. Run 
    Make sure the Application server hosting JCMS is running using Local System Account or preferably the Network Service account.

3. Advanced configuration

3.1 Using both Windows authentication and other JCMS authentications

If you want to provide both Windows authentication and default JCMS authentication methods, the waffle plugin provides two possibilties to help you in that task :

  1. Completely automatic Authentication : Using advanced custom rule to determine when to trigger windows authentication or not.
  2. Semi-automatic Authentication : Using property jcmsplugin.waffle.windows-auth-required to allow site access without Windows authentication being required.

3.1.1 Completely automatic Authentication : Using advanced custom rule (IP, User-Agent, URI, HostName, ...)

You can specify custom rule to define when the Waffle authentication filter will be triggered or not.
This approach provides the best user experience as it performs authentication automatically when you know it is possible.
For example you may want to automatically use the Windows authentication for intranet user (having an internal IP) but fallback other authentication methods for user coming from the internet.

In order to help you in this task the WaffleHttpFilter allows custom access rules to be defined.
An access rule allows the Waffle authentication to be triggered only when some conditions are met as defined by the WaffleAccessRule class specified in the initialization parameter of the servlet filter.

Some basic access rules are provided in the package com.jalios.jcms.authentication.rules. You can implement your own access rule by extending the AccessRule interface.
For more informations on existing rules and development of your own rules, see the Access Rule Javadoc, which is bundled in the plugin in directory PluginWaffle/plugins/WafflePlugin/docs/javadoc/access-rules/index.html.

Example #1 : IP Access Rule

The following example declares an access rule based on the client IP address. In this example Waffle will be used only for clients in the network 192.168.0.0/24 : *

     <filter>
      <filter-name>WaffleHttpFilter</filter-name>
      <filter-class>com.jalios.jcmsplugin.waffle.WaffleHttpFilter</filter-class>
      [...]
      <init-param>
          <param-name>access-rule.class</param-name>
          <param-value>com.jalios.jcms.authentication.rules.IpAccessRule</param-value>
      </init-param>
      <init-param>
          <param-name>ip-access-rule.regex</param-name>
          <param-value>^192\.168\.0\..*$</param-value>
      </init-param>
     </filter>
    

 

Example #2 : User Agent Access Rule

The following example declares an access rule based on the User Agent of the web client. 
Authentication will be requested for Web clients which match the specified User-Agent. Other Web clients will not use Waffle Authentication. 
This rule can be used with Group Poliy Object of Internet Explorer which allows custom User-Agent to be specified.
See Internet Explorer Maintenance : Customize the User Agent String 
For this example we suppose the custom string "MyCompagny Custom UserAgent" has been configured in the Internet Explorer GPO (this string is appended to the original Internet Explorer User-Agent) : *

     <filter>
      <filter-name>WaffleHttpFilter</filter-name>
      <filter-class>com.jalios.jcmsplugin.waffle.WaffleHttpFilter</filter-class>
      [...]
      <init-param>
          <param-name>access-rule.class</param-name>
          <param-value>com.jalios.jcms.authentication.rules.UserAgentAccessRule</param-value>
      </init-param>
      <init-param>
          <param-name>user-agent-access-rule.regex</param-name>
          <param-value>.*MyCompagny Custom UserAgent.*</param-value>
      </init-param>
     </filter>
    

 

If no access rule parameter is specified in the servlet filter configuration, the default behavior of the Waffle NegotiateSecurityFilter is applied.

3.1.2 Semi-automatic authentication : Using property "jcmsplugin.waffle.windows-auth-required"

Setting this option to false allows site access without Windows authentication being required :

  • users without Windows account will be able to enter their login / password as usual (or use any other login method available on the site),
  • users with an Active Directory account will have to click button "Authenticate with my Windows account", as opposed to when this option is set to true in which case authentication is automatic.
    logon screen with 'Authenticate with my Windows account' button

This option does not change the private configuration of the site as defined in administration area, if site is configured as private, an authentication will be required, Windows or not.

3.2 Logging

If you need to obtain log message for the authentication process (for example to trace any authentication problem), edit the log4j.xml file and add the following lines at the end.

<logger name="com.jalios.jcmsplugin.waffle"> <level value="DEBUG" /> </logger>
<logger name="waffle.servlet"> <level value="INFO" /> </logger>

Waffle library is very verbose by default in INFO mode, thus the default configuration for waffle logger is configured to only output WARNING logs.

3.3 Open API (REST)

The JCMS Open API servlet (corresponding to the servlet mapping /rest/*) does not require a Windows Authentication to be properly accessed.
If you want to benefit from your windows authentication when accessing the OpenAPI servlet, simply add parameter authenticateWithWindows set to true (constantsWaffleHttpFilter.REQUEST_WINDOWS_AUTHENTIFICATION) to the request's parameter and the current windows authentication will be verified if possible.

3.4 JSync

You can safely use the widlcard /* servlet filter mapping for the WaffleHttpFilter.
This configuration is compatible with JCMS JSync protocol and the WaffleHttpFilter guarantees a fully functional configuration.

The "JSyncServlet" path used by JSync is always omitted from the Windows authentication, whatever mapping is specified.
JSync's servlet uses its own security mecanism and must not be filtered by Waffle authentication in order to be reachable by other JCMS nodes in the JSync cluster.

3.5 Multi-LDAP

When this plugin is being used on a JCMS in which several LDAP have been configured (as explained in the Multi-LDAP section of Configuration et fonctionnement du ldap dans jcms), the following property must be modified in your properties file :

# The LDAP and JCMS login to use based on WindowsPrincipal information
# {0} : fqn aka Fully Qualified Name, eg : "JALIOS\jaquemet" see WindowsPrincipal.getName()
# {1} : domain, eg "JALIOS" (first part of fqn)
# {2} : name, eg "jaquemet" (second part of fqn)
jcmsplugin.waffle.login-format: {2}

This property defines which login is being used for LDAP synchronization once user has been authenticated by the Windows Waffle plugin. The default value only allows to use the name of the user, which is not enough in multi-LDAP configuration.
Set this property (either in custom.prop or in your main plugin plugin.prop) to use the fully qualified name of the user :

jcmsplugin.waffle.login-format: {0}

4. Common problems and solutions - Frequently Asked Questions

4.1 ClassNotFoundException and JSP compilation error

Ensure init parameter impersonate of the Waffle servlet filter is set to false

4.2 Firefox : authentication granted in two steps after cancel

Problem: When using firefox, authentication is granted only after hitting cancel button on a login / pass request window.

Explanation: The Basic authentication has been enable in Waffle servlet filter configuration and is requested before the Negotiate authentication.

Fix 1: Remove the "Basic" authentication from the Waffle servlet filter configuration init parameter securityFilterProviders.

Fix 2: Ensure "Basic" appears in second, after the Negotiate authentication in the Waffle servlet filter configuration init parameter isecurityFilterProviders :

  waffle.servlet.spi.NegotiateSecurityFilterProvider
  waffle.servlet.spi.BasicSecurityFilterProvider 
  

4.3 How to determine if NTLM or Kerberos is being used ?

Perform a Wireshark capture on the client Windows PC.
Observe value of Authorization: Negotiate... HTTP header field.

4.3.1 Kerberos

  • Using filter kerberos in wireshark displays all HTTP requests.
  • HTTP header field Authorization: Negotiate... displays information "krb5" in detailed SPNEGO "Simple Protected Negotiation" informations.

4.3.2 NTLM

  • Using filter ntlmssp in wireshark displays first HTTP requests.
  • 3 HTTP requests in a row appear in the begining of the authentication, each one with a different information in the HTTP header
    1. NTLMSSP_NEGOTIATE
    2. NTLMSSP_CHALLENGE
    3. NTLMSSP_AUTH

4.4 Authentication fails, and "KRB Error : KRB5KRB_AP_ERR_MODIFIED" in HTTP headers

Problem: Authentication fails and a login/password window is prompted by the browser and error KRB5KRB_AP_ERR_MODIFIED is visible in HTTP headers when using Wireshark.

Explanation: Application server running JCMS & Waffle has not been launched using Windows SystemAccount and kerberos ticket received cannot be validated.

Fix: Execute application server using appropriate system account.

4.5 Authentication succeed, but "KRB Error : KRB5KRB_ERR_BADOPTION" in HTTP headers

Problem: Everything work as expected, but the error KRB5KRB_ERR_BADOPTION is visible in HTTP headers when using Wireshark.

Explanation: Account used to run application server does not have proper delegation privilege on the Active Directory.

Fix: Execute application server using appropriate system account or grant delegation privilege to account being used.

4.6 NTLM Authentication is used instead of Kerberos, and error "KRB Error : KRB5KRB_ERR_S_PRINCIPAL_UNKNOWN" in HTTP headers

Problem: Authentication is sucessful, but NTLM Authentication is being used instead of the expected Kerberos authentication, and error "KRB Error : KRB5KRB_ERR_S_PRINCIPAL_UNKNOWN" is visible in HTTP headers when using Wireshark.

Explanation: The domain name of the HTTP server has not been registered in the Windows hosts.

Fix: Run the following command on the Windows machine hosting JCMS :

Setspn -A HTTP/mydomainname.com NetbiosNameOfWindowsServer

For example, if JCMS is hosted on a windows machine with netbios name COMPANY-WINSERVER123, and accessed through domain name intranet.mycompany.com, run this command :

Setspn -A HTTP/intranet.mycompany.com COMPANY-WINSERVER123

You might also find useful informations in the following articles :

4.7 HTTP error "400 bad request" or "413 request entity too large"

Make sure you have properly configured the maximum headers size and packet size of your application server and HTTP server connectors, as explained in the installation section Server Side configuration : Java Application Server and HTTP Server.

4.8 How to troubleshoot Kerberos-related issues

Read the following guides and Microsoft knowledge base article to get more information on kerberos related problems which also apply to the architecture used by the Waffle plugin with a Java application server : 

5. Developper Documentation

  • Waffle library home on GitHub
  • Waffle Plugin Javadoc is bundled the plugin, in directory
    PluginWaffle/plugins/WafflePlugin/docs/javadoc/index.html
  • Access Rule Javadoc is bundled the plugin, in directory
    PluginWaffle/plugins/WafflePlugin/docs/javadoc/access-rules/index.html

6. Author & Copyright

This plugin has been developed by Jalios using Daniel Doubrovkine's Waffle library (Eclipse Public License).


FAQ

1. Is it possible to skip Windows authentication for HTTP client ?

If windows authentication has been configured as mandator, there are still two possibilities if you need to access a protected resource of JCMS using an HTTP client without support for Windows Authentication :

  • Client side : Send the HTTP header X-Jalios-AuthenticateWithWindows: false during your request
    Windows Authentication will not be requested by the plugin
    For example, using command line client curl :
    curl -H "X-Jalios-AuthenticateWithWindows: false" http://jcms.example.com/
  • Server side : Configure an access rule for the Waffle plugin, to exclude requests performed by your HTTP client from mandatory Windows authentication. Use any technical criteria relevant for you and specific to your HTTP client.
    See Règles d'accès des modules de SSO (aka AccessRules)

Information

Version
  • 3.0
Stability
  • Stable
Compatibility
  • JPlatform 10
Certified by Jalios
  • Yes
Price
  • Module gratuit
Support
  • Jalios Support
Author
  • Jalios SA
License
  • Jalios
Size
  • 4.09 MB
Updated
  • 10/25/17
Download
  • 58