获取远端真实ip的方式

本帖目的

在web开发等实际应用场景中,许多地方需要获取用户当前真实的使用ip。在先网应用中,例如移动、联通、电信等,不会允许用户直接访问访问服务器的地址,这样做即是我了安全也是为了均衡,而这样操作的结果就是服务器端不能获取用户的真实使用地址,很有可能将一个正常的访问当做是一个攻击,最简单的CSRF攻击即是基于该原理。本帖的目的在于讲述获取用户真实使用ip的方法。

代码讲述

下面代码是具体操作形式,通过下属的代码,我们可以获取到真实的操作ip

private String getRemoteClientAddr(HttpServletRequest request) {
		//常用的5种获取原始ip的方式,其中x-forwarded-for 为获取原始ip的最常用方法。其他方式请搜索相关文档
		String []ipHeaders = {"x-forwarded-for", "http_client_ip", "Proxy-Client-IP", "WL-Proxy-Client-IP", "HTTP_X_FORWARDED_FOR"};
		String []invalidIps = {null, "unknown"};
		String clientIp = null;
		
		for(String ipHeader : ipHeaders) {
			clientIp = request.getHeader(ipHeader);
			String tempClientIp = StringUtils.substringBefore(clientIp, ",");
			clientIp = StringUtils.trimToNull(tempClientIp);
			if(!this.isInvalidIp(clientIp, invalidIps)) {
				//如果当前ip有效,则不再进行循环
				break;
			}
		}
		
		//再次对获取到的IP进行判断
		if(this.isInvalidIp(clientIp, invalidIps)) {
			//这种场景是直接访问服务器而没有转接。
			clientIp = request.getRemoteAddr();
			
		}
		
		return clientIp;
	}
	
	private boolean isInvalidIp(String requestIp, String ...invalidIps) {
		for(String invalidIp : invalidIps) {
			if(null == invalidIp) {
				if(null == requestIp) {
					//第一种场景:输入的ip为null,则一定是invalid
					return true;
				}else {
					continue;
				}
			}else if(invalidIp.equalsIgnoreCase(requestIp)){
				//第二种场景:ip类型属于invalid数组类型中的某一个
				return true;
			}
		}
		
		//for循环遍历完成后仍旧没有返回,则认为是 valid类型
		return false;
	}


ip检索位置

上述方法一般应用于filter中,在request请求到达servlet之前进行判断,确定各项要求是否合法,下面简单介绍filter的使用方法

filter分为两部分:1. java部分,需要实现Filter类;2. web.xml中的配置

java代码部分

Filter类包含三个方法:1. init()方法,在tomcat启动的时候负责filter的初始化;2. dofilter()方法,在tomcat收到http请求时对http请求进行一定处理;3. destroy()方法,在tomcat结束时对指定的资源进行清理。

import java.io.IOException;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;

import org.apache.commons.lang3.StringUtils;

public class CsrfFilter implements Filter {

	@Override
	public void destroy() {

		System.out.println("+++++ destory()+++++");
	}

	@Override
	public void doFilter(ServletRequest request, ServletResponse response, FilterChain filterChain) throws IOException, ServletException {
            filterChain.doFilter(request, response);
	}

	@Override
	public void init(FilterConfig config) throws ServletException {

		System.out.println("csrfTilter");
	}

}

web.xml中的配置

1. 配置某指定的过滤器:需要在web.xml中配置两个节点,即<filter/>和<filter-mapping/>,其中<filter/>节点用于指明过滤器的名称和指定的过滤器文件;而<filter-mapping/>的作用是指定过滤的内容。

        
        <filter>
	   <!-- 过滤器的名称 -->
	    <filter-name>csrf-filter</filter-name>
	    <!-- 过滤器文件的位置 -->
	    <filter-class>com.china.filters.csrf.CsrfFilter</filter-class>
	</filter>
	
	<filter-mapping>
	     <filter-name>csrf-filter</filter-name>
	     <!-- 过滤器所过滤的内容,此处是过滤一切请求 -->
	     <url-pattern>/*</url-pattern>
	</filter-mapping>

2. 常用的spring指定编码格式过滤器:http请求中常常有自己携带的编码方式,当两种编码方式交互时,可能会产生乱码,为了解决该问题,一般强制指定为UTF-8编码格式

     <filter>
        <filter-name>characterEncodingFilter</filter-name>
        <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
        <init-param>
            <!-- 指定编码格式为UTF-8 -->
            <param-name>encoding</param-name>
            <param-value>UTF-8</param-value>
        </init-param>
        <init-param>
            <!-- 强制编码 -->
            <param-name>forceEncoding</param-name>
            <param-value>true</param-value>
        </init-param>
    </filter>
    <filter-mapping>
        <filter-name>characterEncodingFilter</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值