如何检查无限制的Internet访问?(强制门户检测)

ccp*_*zza 35 authentication redirect android http connectivity

我需要可靠地检测设备是否具有完全的互联网访问权限,即用户不仅限于强制网络门户(也称为围墙花园),即有限的子网强制用户在表单上提交凭据以便获得满访问.

我的应用程序正在自动执行身份验证过程,因此在开始登录活动之前知道完全互联网访问不可用非常重要.

问题在于如何检查网络接口是否已启动且处于连接状态.它是关于确保设备具有不受限制的互联网访问,而不是沙盒内部网段.

到目前为止我尝试过的所有方法都失败了,因为连接到任何知名主机都不会抛出异常但返回有效的HTTP 200响应代码,因为所有请求都被路由到登录页面.

以下是我尝试的所有方法,但它们都返回true而不是false出于上述原因:

1:

InetAddress.getByName(host).isReachable(TIMEOUT_IN_MILLISECONDS);
isConnected = true; <exception not thrown>
Run Code Online (Sandbox Code Playgroud)

2:

Socket socket = new Socket();
SocketAddress sockaddr = new InetSocketAddress(InetAddress.getByName(host), 80);
socket.connect(sockaddr, pingTimeout);
isConnected = socket.isConnected();
Run Code Online (Sandbox Code Playgroud)

3:

URL url = new URL(hostUrl));
URLConnection urlConn = url.openConnection();
HttpURLConnection httpConn = (HttpURLConnection) urlConn;
httpConn.setAllowUserInteraction(false);
httpConn.setRequestMethod("GET");
httpConn.connect();
responseCode = httpConn.getResponseCode();
isConnected = responseCode == HttpURLConnection.HTTP_OK;
Run Code Online (Sandbox Code Playgroud)

那么,我如何确保连接到实际主机而不是登录重定向页面?显然,我可以从我使用的'ping'主机检查实际的响应体,但它看起来不是一个合适的解决方案.

ccp*_*zza 43

作为参考,这里是来自Android 4.0.1 AOSP代码库的"官方"方法: WifiWatchdogStateMachine.isWalledGardenConnection().我将包括下面的代码,以防万一链接在将来中断.

private static final String mWalledGardenUrl = "http://clients3.google.com/generate_204";
private static final int WALLED_GARDEN_SOCKET_TIMEOUT_MS = 10000;

private boolean isWalledGardenConnection() {
    HttpURLConnection urlConnection = null;
    try {
        URL url = new URL(mWalledGardenUrl); // "http://clients3.google.com/generate_204"
        urlConnection = (HttpURLConnection) url.openConnection();
        urlConnection.setInstanceFollowRedirects(false);
        urlConnection.setConnectTimeout(WALLED_GARDEN_SOCKET_TIMEOUT_MS);
        urlConnection.setReadTimeout(WALLED_GARDEN_SOCKET_TIMEOUT_MS);
        urlConnection.setUseCaches(false);
        urlConnection.getInputStream();
        // We got a valid response, but not from the real google
        return urlConnection.getResponseCode() != 204;
    } catch (IOException e) {
        if (DBG) {
            log("Walled garden check - probably not a portal: exception "
                    + e);
        }
        return false;
    } finally {
        if (urlConnection != null) {
            urlConnection.disconnect();
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

此方法依赖于特定的URL,mWalledGardenUrl = "http://clients3.google.com/generate_204"始终返回204响应代码.即使DNS受到干扰,这也会起作用,因为在这种情况下200将返回代码而不是预期的代码204.我看到一些强制门户网站欺骗了对此特定URL的请求,以防止Android设备上的Internet无法访问的消息.

谷歌有这个主题的变体:提取http://www.google.com/blank.html将返回200一个零长度响应体的代码.因此,如果你得到一个非空的身体,这将是另一种方法来弄清楚你是在有围墙的花园后面.

苹果拥有自己的网址,用于检测圈养门户网站:当网络已经启动IOS和MacOS设备将连接到像一个URL http://www.apple.com/library/test/success.html,http://attwifi.apple. com/library/test/success.html,或http://captive.apple.com/hotspot-detect.html,它必须返回HTTP状态代码200和包含的正文Success.

注意:此方法不适用于互联网访问受限的区域,例如中国,其中整个国家是围墙花园,大多数Google/Apple服务被阻止或过滤.其中的一些可能无法阻止:http://www.google.cn/generate_204,http://g.cn/generate_204,http://gstatic.com/generate_204http://connectivitycheck.gstatic.com/generate_204-但这些都属于谷歌这样不能保证工作.


Del*_*yan 5

另一种可能的解决方案可能是通过HTTPS连接并检查目标证书.不确定有围墙的花园是否真的通过HTTPS服务登录页面或只是删除连接.在任何一种情况下,您都应该能够看到您的目的地不是您期望的目的地.

当然,您还需要TLS和证书检查的开销.遗憾的是,这是经过身份验证的连接的价格.