Java限制IP访问页面 实现方式

简介: Java限制IP访问页面 实现方式

Java限制IP访问页面 实现方式

最近遇到一个需求,一个只能内网访问的网站,需要限制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>


//最简单的获取外网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;
    }


  • 以上方法均来自网络,亲测有效,记录于此。


总结


如果这篇文章对您有所帮助,或者有所启发的话,求一键三连:点赞、转发、收藏,您的支持是我坚持写作最大的动力。

目录
相关文章
|
1月前
|
前端开发 Java
java实现动态验证码源代码——jsp页面
java实现动态验证码源代码——jsp页面
13 0
|
24天前
|
存储 NoSQL Java
Java数据库编程指南:实现高效数据存储与访问
【4月更文挑战第2天】Java开发者必须掌握数据库编程,尤其是JDBC,它是连接数据库的标准接口。使用Spring JDBC或JPA能简化操作。选择合适的JDBC驱动,如MySQL Connector/J,对性能至关重要。最佳实践包括事务管理、防SQL注入、优化索引和数据库设计。NoSQL数据库如MongoDB也日益重要,Java有对应的驱动支持。理解这些概念和技术是构建高效数据库应用的基础。
Java数据库编程指南:实现高效数据存储与访问
|
1月前
|
前端开发 Java
java通过commons-fileupload实现多张图片的上传(jsp页面)
java通过commons-fileupload实现多张图片的上传(jsp页面)
16 2
|
4月前
|
存储
JavaWeb如何获取当前访问IP
JavaWeb如何获取当前访问IP
83 0
|
1天前
|
存储 Java 定位技术
【Java】根据IP地址获取省市
【Java】根据IP地址获取省市
7 1
|
7天前
|
存储 Java
Java动态转发代理IP的实现方法
Java动态转发代理IP的实现方法
23 11
|
8天前
|
安全 Java API
java借助代理ip,解决访问api频繁导致ip被禁的问题
java借助代理ip,解决访问api频繁导致ip被禁的问题
|
9天前
|
网络协议 Java API
深度剖析:Java网络编程中的TCP/IP与HTTP协议实践
【4月更文挑战第17天】Java网络编程重在TCP/IP和HTTP协议的应用。TCP提供可靠数据传输,通过Socket和ServerSocket实现;HTTP用于Web服务,常借助HttpURLConnection或Apache HttpClient。两者结合,构成网络服务基础。Java有多种高级API和框架(如Netty、Spring Boot)简化开发,助力高效、高并发的网络通信。
|
10天前
|
SQL 缓存 Java
Java数据库连接池:优化数据库访问性能
【4月更文挑战第16天】本文探讨了Java数据库连接池的重要性和优势,它能减少延迟、提高效率并增强系统的可伸缩性和稳定性。通过选择如Apache DBCP、C3P0或HikariCP等连接池技术,并进行正确配置和集成,开发者可以优化数据库访问性能。此外,批处理、缓存、索引优化和SQL调整也是提升性能的有效手段。掌握数据库连接池的使用是优化Java企业级应用的关键。