你写了很多,很少实质性的。让我为你分解事情。
Java 似乎还支持开箱即用的 NTLM——这个和这个看起来很有趣。
那是错误的。这是使用 SSPI 专门用于HttpUrlConnection
. 忘记两者。
忘记 NTLM,它是基于连接的,并且是专有的。使用 Kerberos!
我不知道您使用的是什么 HTTP 库,但该方法非常简单,您不需要 Waffle,而只需要 JNA:
import java.io.IOException;
import java.util.Base64;
import org.apache.commons.io.HexDump;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.util.EntityUtils;
import com.sun.jna.platform.win32.Secur32;
import com.sun.jna.platform.win32.Sspi;
import com.sun.jna.ptr.IntByReference;
public class SspiAuth {
public static void main(String[] args)
throws ArrayIndexOutOfBoundsException, IllegalArgumentException, IOException {
Sspi.CredHandle cred = new Sspi.CredHandle();
int status = Secur32.INSTANCE.AcquireCredentialsHandle(null, "Negotiate",
Sspi.SECPKG_CRED_OUTBOUND, null, null, null, null, cred, null);
System.out.println(status);
Sspi.CtxtHandle ctxt = new Sspi.CtxtHandle();
Sspi.SecBufferDesc bufferDesc = new Sspi.SecBufferDesc(Sspi.SECBUFFER_TOKEN,
Sspi.MAX_TOKEN_SIZE);
IntByReference ctxtAttrs = new IntByReference();
status = Secur32.INSTANCE.InitializeSecurityContext(cred, null,
"HTTP/<fqdn of the proxy>",
Sspi.ISC_REQ_MUTUAL_AUTH, 0, Sspi.SECURITY_NATIVE_DREP, null, 0, ctxt, bufferDesc,
ctxtAttrs, null);
System.out.println(status);
HexDump.dump(bufferDesc.getBytes(), 0, System.out, 0);
HttpClientBuilder builder = HttpClientBuilder.create();
try (CloseableHttpClient httpClient = builder.build()) {
HttpGet method = new HttpGet("https://deblndw024v.ad001.siemens.net:8444/manager/html");
method.addHeader("Authorization",
"Negotiate " + Base64.getEncoder().encodeToString(bufferDesc.getBytes()));
CloseableHttpResponse response = httpClient.execute(method);
EntityUtils.consumeQuietly(response.getEntity());
response.close();
System.out.println(response.getStatusLine());
String responseToken = response.getFirstHeader("WWW-Authenticate").getValue()
.substring(10);
System.out.println(responseToken);
byte[] rawResponseToken = Base64.getDecoder().decode(responseToken);
Sspi.SecBufferDesc bufferDesc2 = new Sspi.SecBufferDesc(Sspi.SECBUFFER_TOKEN,
rawResponseToken);
Sspi.CtxtHandle ctxt2 = new Sspi.CtxtHandle();
Sspi.SecBufferDesc bufferDesc3 = new Sspi.SecBufferDesc(Sspi.SECBUFFER_TOKEN,
Sspi.MAX_TOKEN_SIZE);
status = Secur32.INSTANCE.InitializeSecurityContext(cred, ctxt,
"HTTP/<fqdn of the proxy>",
Sspi.ISC_REQ_MUTUAL_AUTH, 0, Sspi.SECURITY_NATIVE_DREP, bufferDesc2, 0, ctxt2,
bufferDesc3, ctxtAttrs, null);
System.out.printf("0x%x%n", status);
}
}
}
考虑释放句柄以避免内存泄漏!