java - NTLM 身份验证 Android Studio

标签 java android authentication android-studio ntlm

我花了很多时间试图弄清楚如何在 Android Studio 上执行 NTLM 身份验证,但没有成功。我意识到 NTLM 不是 Android 原生的。最近一直在用JCIFS库

jcifs.Config.registerSmbURLHandler();
URL url = new URL("https://domain%5cuser:pass@host");
HttpsURLConnection conn = (HttpsURLConnection) url.openConnection();

但是我得到了错误

"Unable to find default handler for protocol: https"

相同的代码适用于标准 Java。在这一点上,我已经用尽了我找到的所有建议,但我不知道该怎么做。

最佳答案

我试图解决同样的问题,并遇到了以下链接(类粘贴在下面以防链接失效): https://lists.samba.org/archive/jcifs/2013-July/010105.html

然后我使用以下命令强制使用处理程序:

    jcifs.Config.registerSmbURLHandler();

    System.setProperty("http.auth.ntlm.domain", domain);
    System.setProperty("jcifs.smb.client.domain", domain);
    System.setProperty("jcifs.smb.client.username", username);
    System.setProperty("jcifs.smb.client.password", password);
    System.setProperty("java.protocol.handler.pkgs", "domain.com.package");

但是,我遇到了问题,因为返回的响应是空的,因此需要在那里进行更多调查。

(版权声明等已被删除,因为它一直混淆 SO 的代码块解析器)

public class Handler extends URLStreamHandler {
/**
 * The default HTTP port (<code>80</code>).
 */
public static final int DEFAULT_HTTP_PORT = 80;

private static final Map PROTOCOL_HANDLERS = new HashMap();

private static final String HANDLER_PKGS_PROPERTY =
        "java.protocol.handler.pkgs";

/**
 * Vendor-specific default packages.  If no packages are specified in
 * "java.protocol.handler.pkgs", the VM uses one or more default
 * packages, which are vendor specific.  Sun's is included below
 * for convenience; others could be as well.  If a particular vendor's
 * package isn't listed, it can be specified in
 * "java.protocol.handler.pkgs".
 */
private static final String[] JVM_VENDOR_DEFAULT_PKGS = new String[] {
    "sun.net.www.protocol"
};

private static URLStreamHandlerFactory factory;

/**
 * Sets the URL stream handler factory for the environment.  This
 * allows specification of the factory used in creating underlying
 * stream handlers.  This can be called once per JVM instance.
*
 * @param factory The URL stream handler factory.
 */
public static void setURLStreamHandlerFactory(
        URLStreamHandlerFactory factory) {
    synchronized (PROTOCOL_HANDLERS) {
        if (Handler.factory != null) {
            throw new IllegalStateException(
                    "URLStreamHandlerFactory already set.");
        }
        PROTOCOL_HANDLERS.clear();
        Handler.factory = factory;
    }
}

/**
 * Returns the default HTTP port.
 *
 * @return An <code>int</code> containing the default HTTP port.
 */
protected int getDefaultPort() {
    return DEFAULT_HTTP_PORT;
}

@Override
protected URLConnection openConnection(URL url) throws IOException
{
    return this.openConnection(url, null);
}

@Override
protected URLConnection openConnection(URL url, Proxy proxy) throws IOException
{
    url = new URL(url, url.toExternalForm(), getDefaultStreamHandler(url.getProtocol()));

    final HttpURLConnection urlConnection;
    if (proxy == null) {
        urlConnection = (HttpURLConnection) url.openConnection();
    } else {
        urlConnection = (HttpURLConnection) url.openConnection(proxy);
    }

    return new NtlmHttpURLConnection(urlConnection);
}

private static URLStreamHandler getDefaultStreamHandler(String protocol)
        throws IOException {
    synchronized (PROTOCOL_HANDLERS) {
        URLStreamHandler handler = (URLStreamHandler)
                PROTOCOL_HANDLERS.get(protocol);
        if (handler != null) return handler;
        if (factory != null) {
            handler = factory.createURLStreamHandler(protocol);
        }
        if (handler == null) {
            String path = System.getProperty(HANDLER_PKGS_PROPERTY);
            StringTokenizer tokenizer = new StringTokenizer(path, "|");
            while (tokenizer.hasMoreTokens()) {
                String provider = tokenizer.nextToken().trim();
                if (provider.equals("jcifs")) continue;
                String className = provider + "." + protocol + ".Handler";
                try {
                    Class handlerClass = null;
                    try {
                        handlerClass = Class.forName(className);
                    } catch (Exception ex) { }
                    if (handlerClass == null) {
                        handlerClass = ClassLoader.getSystemClassLoader(
                                ).loadClass(className);
                    }
                    handler = (URLStreamHandler) handlerClass.newInstance();
                    break;
                } catch (Exception ex) { }
            }
        }
        if (handler == null) {
            for (int i = 0; i < JVM_VENDOR_DEFAULT_PKGS.length; i++) {
                String className = JVM_VENDOR_DEFAULT_PKGS[i] + "." +
                        protocol + ".Handler";
                try {
                    Class handlerClass = null;
                    try {
                        handlerClass = Class.forName(className);
                    } catch (Exception ex) { }
                    if (handlerClass == null) {
                        handlerClass = ClassLoader.getSystemClassLoader(
                                ).loadClass(className);
                    }
                    handler = (URLStreamHandler) handlerClass.newInstance();
                } catch (Exception ex) { }
                if (handler != null) break;
            }
        }
        if (handler == null) {
            throw new IOException(
                    "Unable to find default handler for protocol: " +
                            protocol);
        }
        PROTOCOL_HANDLERS.put(protocol, handler);
        return handler;
    }
}

关于java - NTLM 身份验证 Android Studio,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38680924/

相关文章:

android - 获取 ListView TextView 的值

.net - 将选项 "show password "添加到 asp.net 登录控件

android - Landroid/content/pm/PackageInfo 类中没有虚方法 getLongVersionCode()J

java - 将形状移动到手指触摸的位置

powershell - 如何使用具有集成安全性的 Powershell 连接 Azure Paas 数据库

authentication - 在 Neo4j 节点中存储身份验证数据是一个好习惯吗?

Java正则表达式,获取定界字符串中的字符,忽略中间的文本

java - 有没有办法在启动 mvn appengine :devserver? 时不运行单元测试

java - 计算器的问题

java - 在数组列表中查找最大序列