生活不易、且行且珍惜。网站首页 程序人生
Java限制IP访问页面
发布时间:2020-03-30 11:45编辑:zj 阅读:文章分类: Java互动QQ群:170915747
最近遇到一个需求,一个只能内网访问的网站,需要限制ip访问。就是网站内的部分文章只有白名单内的ip才能打开。因为是静态化的网站,所有文章都是静态html页面。所以首先想到的就是直接js获取访问者ip然后再判断是否在白名单内,不在白名单内就到没有权限页面。
但是JS获取内网Ip还是比较麻烦的,查到几个方法最后试了都不行。
记录下查到的几个方法和最后实现的方法。
JS获取外网ip的方法:
//最简单的获取外网ip的方法。可以直接用,但是没啥用.. <script src="http://pv.sohu.com/cityjson?ie=utf-8"></script> <script> document.write(returnCitySN["cip"]); </script>
JS获取内网Ip的方法://有些浏览器获取到的加密ip段有问题,所以当其时期
function getIP(callback) { let recode = {}; let RTCPeerConnection = window.RTCPeerConnection || window.mozRTCPeerConnection || window.webkitRTCPeerConnection; // 如果不存在则使用一个iframe绕过 if (!RTCPeerConnection) { // 因为这里用到了iframe,所以在调用这个方法的script上必须有一个iframe标签 // <iframe id="iframe" sandbox="allow-same-origin" style="display:none;"></iframe> let win = iframe.contentWindow; RTCPeerConnection = win.RTCPeerConnection || win.mozRTCPeerConnection || win.webkitRTCPeerConnection; } //创建实例,生成连接 let pc = new RTCPeerConnection(); // 匹配字符串中符合ip地址的字段 function handleCandidate(candidate) { debugger; let ip_regexp = /([0-9]{1,3}(\.[0-9]{1,3}){3}|([a-f0-9]{1,4}((:[a-f0-9]{1,4}){7}|:+[a-f0-9]{1,4}){6}))/; let ip_isMatch = candidate.match(ip_regexp)[1]; if (!recode[ip_isMatch]) { callback(ip_isMatch); recode[ip_isMatch] = true; } } //监听icecandidate事件 pc.onicecandidate = (ice) => { if (ice.candidate) { handleCandidate(ice.candidate.candidate); } }; //建立一个伪数据的通道 pc.createDataChannel(''); pc.createOffer((res) => { pc.setLocalDescription(res); }, () => {}); //延迟,让一切都能完成 setTimeout(() => { let lines = pc.localDescription.sdp.split('\n'); lines.forEach(item => { if (item.indexOf('a=candidate:') === 0) { handleCandidate(item); } }) }, 1000); } getIP(function (ip) { alert(ip); });
利用WebRTC获取真实内网Ip,WebRTC是一个支持网页浏览器进行实时语音对话或视频对话的API
由于WebRTC在建立连接过程中,会向对方发送本地地址SDP,因此可以通过访问SDP获得访问者的IP
但是有些浏览器用不了,所以还是放弃这种方式了。
最后还是觉得用Java来实现比较好吧,前端文章页写个ajax,每次进入文章先判断文章是否需要限制IP访问,如果需要就请求下后端,后端获取Ip判断是否在白名单内。注意ajax要用同步。
Java获取访问者Ip方法:
String ip = request.getHeader("x-forwarded-for"); if (ip == null || ip.length() == 0 || "nuknown".equalsIgnoreCase(ip)) { ip = request.getHeader("Proxy-Client-IP"); } if (ip == null || ip.length() == 0 || "nuknown".equalsIgnoreCase(ip)) { ip = request.getHeader("WL-Proxy-Client-IP"); } if (ip == null || ip.length() == 0 || "nuknown".equalsIgnoreCase(ip)) { ip = request.getRemoteAddr(); } System.out.println(ip);
完整代码
/** * 判断文章是否有权可看 * * @param map * @return */ @RequestMapping("/isIntranet.do") @ResponseBody public String isIntranet(ServletRequest request, ServletResponse response) { Map<String, Object> map = new HashMap<String, Object>(); HttpServletRequest req = (HttpServletRequest)request; HttpServletResponse resp = (HttpServletResponse)response; // 判断访问者Ip是否白名单内 boolean flag = isIPOK(req, resp); System.out.println(flag); if (flag) { return "true"; } else { return "false"; } } private boolean isIPOK(HttpServletRequest request, HttpServletResponse response) { // String accessIP = IPUtil.getUserIp(request); String ip = request.getHeader("x-forwarded-for"); if (ip == null || ip.length() == 0 || "nuknown".equalsIgnoreCase(ip)) { ip = request.getHeader("Proxy-Client-IP"); } if (ip == null || ip.length() == 0 || "nuknown".equalsIgnoreCase(ip)) { ip = request.getHeader("WL-Proxy-Client-IP"); } if (ip == null || ip.length() == 0 || "nuknown".equalsIgnoreCase(ip)) { ip = request.getRemoteAddr(); } System.out.println(ip); return isLAN(ip); } // 是否为内网网段 public boolean isLAN(String ip) { if ("127.0.0.1".equals(ip)) { return true; } boolean result = true; try { Properties prop = new Properties(); //获取设置Ip段的配置文件 InputStream in = this.getClass().getClassLoader().getResourceAsStream("ipConfig.properties"); prop.load(in); // 遍历取值 Set<Object> objects = prop.keySet(); for (Object object : objects) { String ipNot = new String(prop.getProperty((String)object).getBytes("iso-8859-1"), "gbk"); System.out.println(ipNot); /*result = ipIsValid("192.168.8.78-192.168.255.255", ip) || ipIsValid("172.16.0.0-172.31.255.255", ip) || ipIsValid("10.0.0.0-10.255.255.255", ip);*/ result = ipIsValid(ipNot, ip); } in.close(); } catch (IOException e) { e.printStackTrace(); } return result; } //校验Ip是否包含在Ip段内 public static boolean ipIsValid(String ipSection, String ip) { if (ipSection == null) { throw new NullPointerException("IP段不能为空!"); } if (ip == null) { throw new NullPointerException("IP不能为空!"); } ipSection = ipSection.trim(); ip = ip.trim(); final String REGX_IP = "((25[0-5]|2[0-4]\\d|1\\d{2}|[1-9]\\d|\\d)\\.){3}(25[0-5]|2[0-4]\\d|1\\d{2}|[1-9]\\d|\\d)"; final String REGX_IPB = REGX_IP + "\\-" + REGX_IP; if (!ipSection.matches(REGX_IPB) || !ip.matches(REGX_IP)) { return false; } int idx = ipSection.indexOf('-'); idx = idx < 0 ? ipSection.length() : idx; String[] sips = ipSection.substring(0, idx).split("\\."); String[] sipe = ipSection.substring(idx + 1).split("\\."); String[] sipt = ip.split("\\."); long ips = 0L, ipe = 0L, ipt = 0L; for (int i = 0; i < 4; ++i) { ips = ips << 8 | Integer.parseInt(sips[i]); ipe = ipe << 8 | Integer.parseInt(sipe[i]); ipt = ipt << 8 | Integer.parseInt(sipt[i]); } if (ips > ipe) { long t = ips; ips = ipe; ipe = t; } return ips <= ipt && ipt <= ipe; }
以上方法均来自网络,亲测有效,记录于此。
I am just a porter
#去评论一下
标签:#Ip
版权声明:本博客的所有原创内容皆为作品作者所有
转载请注明:来自ZJBLOG 链接:www.zjhuiwan.cn
「万物皆有时,比如你我相遇」
感谢大佬打赏【请选择支付宝或微信,再选择金额】
使用微信扫描二维码完成支付