Implementing Windows Integrated Authentication (SSO) for Intranet Web Apps via Active Directory and Kerberos/NTLM


2 views

html

When building intranet web applications in Windows environments, we often need to implement true single sign-on (SSO) where users authenticated via Active Directory can access web apps without additional login prompts. This requires Windows Integrated Authentication rather than traditional form-based authentication.

There are two primary protocols enabling this seamless authentication:

  • Kerberos: The preferred modern protocol using ticket-based authentication
  • NTLM: The older challenge-response protocol as fallback

For this to work properly, several components must be configured:

1. Active Directory domain-joined client machines
2. Service Principal Names (SPNs) registered in AD
3. Correct browser security zone settings
4. Properly configured web server (IIS/Tomcat/etc.)

Here's how to configure Tomcat to accept Windows authentication:

<!-- In server.xml -->
<Connector port="8443" protocol="org.apache.coyote.http11.Http11NioProtocol"
           maxThreads="150" SSLEnabled="true" scheme="https" secure="true"
           clientAuth="want" sslProtocol="TLS"
           keystoreFile="conf/keystore.jks" keystorePass="changeit"/>

<!-- In web.xml -->
<login-config>
    <auth-method>CLIENT-CERT</auth-method>
    <realm-name>Client Cert Users-only Area</realm-name>
</login-config>

For processing the authenticated user in your Java webapp:

public class SSOFilter implements Filter {
    public void doFilter(ServletRequest request, ServletResponse response,
            FilterChain chain) throws IOException, ServletException {
        
        HttpServletRequest httpRequest = (HttpServletRequest) request;
        String remoteUser = httpRequest.getRemoteUser();
        
        if (remoteUser != null) {
            // User was authenticated via Windows Integrated Auth
            Principal principal = httpRequest.getUserPrincipal();
            // Process user...
        } else {
            // Fallback to form-based auth
            httpRequest.getRequestDispatcher("/login.jsp").forward(request, response);
        }
        chain.doFilter(request, response);
    }
}
  • Double-hop issue: Kerberos has restrictions on credential delegation. Solution: Configure constrained delegation in AD
  • Browser configuration: The intranet site must be in Trusted Sites zone. Solution: Push via Group Policy
  • SPN issues: Missing or duplicate SPNs cause failures. Solution: Use setspn tool to verify

For Spring-based applications, you can leverage Spring Security Kerberos:

@Configuration
@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
    
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
            .authorizeRequests()
                .anyRequest().authenticated()
                .and()
            .formLogin().disable()
            .logout().disable()
            .csrf().disable()
            .addFilterBefore(
                new SpnegoAuthenticationProcessingFilter(),
                BasicAuthenticationFilter.class);
    }
}

When troubleshooting Windows Integrated Authentication:

  1. Enable Kerberos logging via set KRB5_TRACE=C:\kerberos.log
  2. Check Windows Event Viewer for security audit events
  3. Use Wireshark to examine protocol negotiation
  4. Verify SPNs with setspn -L [serviceaccount]

When implementing transparent SSO for Active Directory-authenticated intranet applications, the authentication sequence typically follows this pattern:

1. User logs into Windows domain workstation
2. Browser requests protected resource from web server
3. Server responds with 401 Unauthorized + WWW-Authenticate headers
4. Browser automatically negotiates authentication via SPNEGO (Kerberos/NTLM)
5. Server validates credentials against AD without user interaction

There are two primary protocols that enable this transparent authentication:

  • Kerberos: The preferred method for modern AD environments
  • NTLM: Fallback protocol when Kerberos isn't available

Here's a sample configuration for enabling SPNEGO authentication in Tomcat:

<!-- In server.xml -->
<Connector port="8443" protocol="org.apache.coyote.http11.Http11NioProtocol"
           maxThreads="150" SSLEnabled="true" scheme="https" secure="true"
           clientAuth="want" sslProtocol="TLS"
           keystoreFile="conf/keystore.jks" keystorePass="changeit"
           truststoreFile="conf/truststore.jks" truststorePass="changeit"/>

<!-- In context.xml -->
<Realm className="org.apache.catalina.realm.JNDIRealm"
       connectionURL="ldap://ad.example.com:389"
       userPattern="CN={0},CN=Users,DC=example,DC=com"
       roleBase="CN=Roles,DC=example,DC=com"
       roleName="cn"
       roleSearch="(member={0})"/>

For applications that need custom handling, here's a basic SPNEGO filter:

public class SpnegoFilter implements Filter {
    private static final String NEGOTIATE = "Negotiate";
    private static final String WWW_AUTHENTICATE = "WWW-Authenticate";
    
    @Override
    public void doFilter(ServletRequest request, ServletResponse response, 
            FilterChain chain) throws IOException, ServletException {
        
        HttpServletRequest req = (HttpServletRequest) request;
        HttpServletResponse res = (HttpServletResponse) response;
        
        String authHeader = req.getHeader("Authorization");
        
        if (authHeader == null || !authHeader.startsWith(NEGOTIATE)) {
            res.setHeader(WWW_AUTHENTICATE, NEGOTIATE);
            res.sendError(HttpServletResponse.SC_UNAUTHORIZED);
            return;
        }
        
        // Extract token and validate with JGSS API
        byte[] token = Base64.getDecoder().decode(
            authHeader.substring(NEGOTIATE.length()).trim());
        
        try {
            GSSManager manager = GSSManager.getInstance();
            GSSName clientName = manager.createContext(
                new GSSByteArrayToken(token)).getSrcName();
            
            req.setAttribute("REMOTE_USER", clientName.toString());
            chain.doFilter(request, response);
        } catch (GSSException e) {
            res.sendError(HttpServletResponse.SC_FORBIDDEN);
        }
    }
}

SPN Registration Issues:

setspn -A HTTP/webserver.example.com domain\serviceaccount

Browser Configuration: Ensure the intranet zone is properly configured in IE/Edge or Firefox/Chrome equivalent settings.

Cross-Domain Challenges: Kerberos requires strict name resolution - ensure DNS is properly configured with forward/reverse lookups.

For environments where SPNEGO isn't feasible:

  • ADFS with WS-Federation: For web applications across security boundaries
  • Header-based Authentication: Using IIS as a reverse proxy with authentication
  • OAuth2/OIDC with AD as Identity Provider: For modern web applications