Authentication

The client authenticates with either NTLM or Kerberos (SPNEGO). The scheme is chosen with authentication(...) on the WinRMClient[1] builder, which takes one or more AuthScheme[2] values:

import org.metricshub.winrm.AuthScheme;

WinRMClient.builder("server.example.com")
    .credentials("DOMAIN\\Administrator", password)
    .authentication(AuthScheme.NTLM)                       // NTLM only (also the default)
    // .authentication(AuthScheme.KERBEROS)                // Kerberos only
    // .authentication(AuthScheme.KERBEROS, AuthScheme.NTLM) // ordered fallback
    .build();

When authentication(...) is not called, NTLM is used.

Ordered fallback

Several schemes form an ordered fallback list: each is tried in the given order until one succeeds. authentication(KERBEROS, NTLM) attempts Kerberos first and falls back to NTLM — for example when the KDC is unreachable or the clock skew is too large.

User name and domain

The user name may be given as DOMAIN\user or as a bare user. When a backslash is present, the part before it is treated as the Windows domain and the part after it as the account name. In Java, remember to escape the backslash in a string literal:

"DOMAIN\\Administrator"   // domain = DOMAIN, user = Administrator
"Administrator"           // no domain

The password is a char[], and the builder deliberately does not copy it: after closing the client you can wipe the single authoritative copy of the secret (Arrays.fill(password, '\0')).

NTLM

NTLM is the default. It works over both transports:

  • HTTP — the WinRM payload is protected with NTLM message encryption, so credentials and data are not sent in the clear even without TLS.
  • HTTPS — NTLM runs inside the TLS tunnel. See TLS / HTTPS[3].

NTLM needs no extra configuration beyond the user name and password.

Kerberos (SPNEGO)

Kerberos authentication uses SPNEGO through the JDK's GSS-API and requires HTTPS. Connect by the FQDN the KDC knows (the service principal is HTTP/<hostname>), not by IP address:

try (WinRMClient client = WinRMClient.builder("server.internal.example.com")
        .https()
        .credentials("DOMAIN\\Administrator", password)
        .authentication(AuthScheme.KERBEROS)
        // .ticketCache(Path.of("/tmp/krb5cc_1000"))   // optional
        .build()) {
    ...
}

Requesting Kerberos on a plain-HTTP client fails at build() with a clear message: there is no Kerberos message encryption over HTTP.

Kerberos configuration

By default, Kerberos relies on the ambient JDK Kerberos configuration — the platform krb5.conf (or the file named by -Djava.security.krb5.conf), or the realm and KDC given directly with -Djava.security.krb5.realm and -Djava.security.krb5.kdc:

java -Djava.security.krb5.realm=EXAMPLE.COM \
     -Djava.security.krb5.kdc=dc01.example.com \
     -cp ... MyApp

The optional ticketCache(Path) builder option points at a Kerberos ticket cache to use for the connection; without it, Kerberos logs in with the user name and password.

Authentication failures

A rejected credential (after every scheme of the fallback list was tried) surfaces as a WinRMAuthenticationException[4] whose message has the stable form Authentication error on <endpoint> with user name "<user>".

Choosing the scheme on the command line

The standalone jar selects the scheme with --ntlm (the default) or --kerberos. The two are mutually exclusive, and --kerberos requires --https:

java -jar winrm-java-2.0.00-standalone.jar \
  -h server.example.com -u 'DOMAIN\user' -pf password.txt \
  --https --kerberos \
  command whoami

Instead of relying on the ambient configuration, the CLI can set the JDK Kerberos configuration for the current invocation:

Option Meaning
--kerberos-kdc <host> Sets the KDC and, unless --kerberos-realm is given, infers the realm from the KDC's DNS suffix.
--kerberos-realm <realm> Overrides the inferred realm. Requires --kerberos-kdc.
java -jar winrm-java-2.0.00-standalone.jar \
  -h server.internal.example.com -u 'DOMAIN\user' -pf password.txt \
  --https --kerberos --kerberos-kdc dc01.internal.example.com \
  command whoami

Here the realm is inferred as INTERNAL.EXAMPLE.COM by dropping the KDC's first DNS label and upper-casing the rest. This follows a common Active Directory naming convention but is not guaranteed by Kerberos — pass --kerberos-realm when the realm does not match the KDC's DNS suffix, or when the KDC is not a fully qualified DNS name.

See also

authentication ntlm kerberos spnego domain realm kdc krb5 ticket cache winrm wql wmi windows ntlm kerberos java remote management
Links:
  • [1] apidocs/org/metricshub/winrm/WinRMClient.html
  • [2] apidocs/org/metricshub/winrm/AuthScheme.html
  • [3] tls.html
  • [4] apidocs/org/metricshub/winrm/exceptions/WinRMAuthenticationException.html
  • [5] preparing-the-host.html
  • [6] timeouts-and-errors.html
Searching...
No results.