【问题标题】:NTLM Authentication Android StudioNTLM 身份验证 Android Studio
【发布时间】:2016-07-31 05:02:25
【问题描述】:

我花了很多时间试图弄清楚如何在 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 中使用。在这一点上,我已经用尽了我找到的每一个建议,我不知道该怎么做。

【问题讨论】:

    标签: java android authentication android-studio ntlm


    【解决方案1】:

    我正在尝试解决相同的问题,但遇到了以下链接(在链接失效的情况下将类粘贴在下面): 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;
        }
    }
    

    }

    【讨论】:

    • 仍在努力;我将 Handler 和测试类移到了 Java 库模块中。我现在返回的是 401,而不是空响应流。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-09-02
    相关资源
    最近更新 更多