关于wifi portal认证--为浏览器添加wifi认证功能

###关于wifi portal认证–为浏览器添加wifi认证功能

  • 1.什么是portal认证
  • 2.android的原生portal认证概要讲述
  • 3.独立出portal认证到浏览器
    ####1.什么是portal认证

就是连接wifi成功后,有些需要去一个登录页面,登录后才能正常使用wifi。在现在商店比如肯德基,万科,万达等很多外场,都有这样的认证方式。还不清楚的百度下portal认证

####2.android的原生portal认证概要讲述

Google开发者文档 有以下讲述:

Handling Network Sign-On
Some Wi-Fi networks block Internet access until the user clicks through a sign-on page. Such sign-on pages are typically presented by using HTTP redirects. You can use getURL() to test if your connection has been unexpectedly redirected. This check is not valid until after the response headers have been received, which you can trigger by calling getHeaderFields() or getInputStream(). For example, to check that a response was not redirected to an unexpected host:
   HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection();
   try {
     InputStream in = new BufferedInputStream(urlConnection.getInputStream());
     if (!url.getHost().equals(urlConnection.getURL().getHost())) {
       // we were redirected! Kick the user out to the browser to sign on?
     
     ...
   } finally {
     urlConnection.disconnect();
   }
 }

google翻译:

处理网络点登录
一些Wi-Fi网络禁止访问Internet ,直到用户点击通过一个登录页面。这样的登录页面通常通过使用HTTP重定向呈现。您可以使用的getURL ()来测试,如果你的连接意外重定向。此检查是无效的,直到已收到响应报头之后,您可以通过调用getHeaderFields ()或的getInputStream ()触发。例如,要检查一个响应没有重定向到一个意想不到的主机:

然后在android系统中会有如下判断:

  private boolean More ...isWalledGardenConnection() {
HttpURLConnection urlConnection = null;
try {
	URL url = new URL(mWalledGardenUrl);
	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();
		}
	}
}

大概意思是说,那一个连接去测试,如果返回的是204 就是连接成功的,如果不是就是需要认证的,然后弹出需要认证的通知栏。点击通知,会打开,CaptivePortalLogin.apk 里面就一个activity

public class CaptivePortalLoginActivity extends Activity {
    private static final String TAG = "CaptivePortalLogin";
    private static final String DEFAULT_SERVER = "clients3.google.com";
    private static final int SOCKET_TIMEOUT_MS = 10000;

    // Keep this in sync with NetworkMonitor.
    // Intent broadcast to ConnectivityService indicating sign-in is complete.
    // Extras:
    //     EXTRA_TEXT       = netId
    //     LOGGED_IN_RESULT = "1" if we should use network, "0" if not.
    private static final String ACTION_CAPTIVE_PORTAL_LOGGED_IN =
            "android.net.netmon.captive_portal_logged_in";
    private static final String LOGGED_IN_RESULT = "result";

    private URL mURL;
    private int mNetId;
    private NetworkCallback mNetworkCallback;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        String server = Settings.Global.getString(getContentResolver(), "captive_portal_server");
        if (server == null) server = DEFAULT_SERVER;
        try {
            mURL = new URL("http://" + server + "/generate_204");
        } catch (MalformedURLException e) {
            done(true);
        }
        ....
 private void testForCaptivePortal() {
        new Thread(new Runnable() {
            public void run() {
                // Give time for captive portal to open.
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                }
                HttpURLConnection urlConnection = null;
                int httpResponseCode = 500;
                try {
                    urlConnection = (HttpURLConnection) mURL.openConnection();
                    urlConnection.setInstanceFollowRedirects(false);
                    urlConnection.setConnectTimeout(SOCKET_TIMEOUT_MS);
                    urlConnection.setReadTimeout(SOCKET_TIMEOUT_MS);
                    urlConnection.setUseCaches(false);
                    urlConnection.getInputStream();
                    httpResponseCode = urlConnection.getResponseCode();
                } catch (IOException e) {
                } finally {
                    if (urlConnection != null) urlConnection.disconnect();
                }
                if (httpResponseCode == 204) {
                    done(true);
                }
            }
        }).start();
    }

    private class MyWebViewClient extends WebViewClient {
        private boolean firstPageLoad = true;

        @Override
        public void onPageStarted(WebView view, String url, Bitmap favicon) {
            if (firstPageLoad) return;
            testForCaptivePortal();
        }

        @Override
        public void onPageFinished(WebView view, String url) {
            if (firstPageLoad) {
                firstPageLoad = false;
                // Now that WebView has loaded at least one page we know it has read in the proxy
                // settings.  Now prompt the WebView read the Network-specific proxy settings.
                setWebViewProxy();
                // Load the real page.
                view.loadUrl(mURL.toString());
                return;
            }
            testForCaptivePortal();
        }
    }

就是用个webView去打开认证登录的网页。如果连接成功了就,发送广播,应该是去删除通知栏消息之类的操作。

####3.独立出portal认证到浏览器

将这部分功能独立出来,放到自己的浏览器中或者apk中,改怎么做呢?有两种方式

1、接收系统的intent 就是已经有系统的通知了,当用户点击通知的时候弹出自己apk中的acivity这里面需要在activity中加入如下属性,才会弹出用户选择框。

  <action android:name="android.net.conn.CAPTIVE_PORTAL" />

2、不依赖系统自己做检测,自己弹出通知流程如下

public class ConnectChangeReceiver extends BroadcastReceiver {
	@Override
	public void onReceive(Context context, Intent arg1) {
		
		Intent i = new Intent(context,WifiPortalCheckService.class);
		context.startService(i);
	}
}

用一个接收器接收网络变化广播,然后启动个服务,在服务中做如下判断,如果连接不上就弹出通知,后面就和方案1一样了

 private boolean isNeed() { 
        final String mWalledGardenUrl = "http://XXXX/generate_204"; 
        final int WALLED_GARDEN_SOCKET_TIMEOUT_MS = 10000; 

        HttpURLConnection urlConnection = null; 
        try { 
            URL url = new URL(mWalledGardenUrl); 
            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(); 
            return urlConnection.getResponseCode() != 204; 
        } catch (IOException e) { 
            return false; 
        } finally { 
            if (urlConnection != null) { 
                urlConnection.disconnect(); 
            } 
        } 
    }
  • 3
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 4
    评论
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

沈万三djh

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值