String getToken( final CtxtHandle continueCtx, final SecBufferDesc continueToken, final String targetName) { final IntByReference attr = new IntByReference(); final SecBufferDesc token = new SecBufferDesc( Sspi.SECBUFFER_TOKEN, Sspi.MAX_TOKEN_SIZE); sspiContext = new CtxtHandle(); final int rc = Secur32.INSTANCE.InitializeSecurityContext(clientCred, continueCtx, targetName, Sspi.ISC_REQ_DELEGATE | Sspi.ISC_REQ_MUTUAL_AUTH, 0, Sspi.SECURITY_NATIVE_DREP, continueToken, 0, sspiContext, token, attr, null); switch (rc) { case WinError.SEC_I_CONTINUE_NEEDED: continueNeeded = true; break; case WinError.SEC_E_OK: dispose(); // Don't keep the context continueNeeded = false; break; default: dispose(); throw new Win32Exception(rc); } return Base64.encodeBase64String(token.getBytes()); }
public static boolean isWinAuthAvailable() { String os = System.getProperty("os.name"); os = os != null ? os.toLowerCase(Locale.ROOT) : null; if (os != null && os.contains("windows")) { try { return Sspi.MAX_TOKEN_SIZE > 0; } catch (final Exception ignore) { // Likely ClassNotFound return false; } } return false; }
@Override public void authenticate(PacketOutputStream writer, String serverPrincipalName, String mechanisms) throws SQLException, IOException { // initialize a security context on the client IWindowsSecurityContext clientContext = WindowsSecurityContextImpl.getCurrent(mechanisms, serverPrincipalName); do { // Step 1: send token to server byte[] tokenForTheServerOnTheClient = clientContext.getToken(); writer.startPacket(packSeq); writer.write(tokenForTheServerOnTheClient); writer.flush(); // Step 2: read server response token if (clientContext.isContinue()) { Buffer buffer = reader.getPacket(true); packSeq = reader.getLastPacketSeq() + 1; byte[] tokenForTheClientOnTheServer = buffer.readRawBytes(buffer.remaining()); Sspi.SecBufferDesc continueToken = new Sspi.SecBufferDesc(Sspi.SECBUFFER_TOKEN, tokenForTheClientOnTheServer); clientContext.initialize(clientContext.getHandle(), continueToken, serverPrincipalName); } } while (clientContext.isContinue()); clientContext.dispose(); }