您的位置:首页 > 编程语言 > Java开发

Java防跨域攻击解决方案

2013-07-04 09:46 218 查看
/**

* 验证请求的合法性,防止跨域攻击

*

* @param request

* @return

*/

@SuppressWarnings("rawtypes")

publicstatic boolean validateRequest(HttpServletRequest request) {

String referer = "";

booleanreferer_sign = true;// true 站内提交,验证通过 //false 站外提交,验证失败

Enumeration headerValues = request.getHeaders("referer");

while(headerValues.hasMoreElements()) {

referer = (String) headerValues.nextElement();

}

// 判断是否存在请求页面

if(StringUtils.isBlank(referer)) referer_sign = false;

else{

// 判断请求页面和getRequestURI是否相同

String servername_str = request.getServerName();

if(StringUtils.isNotBlank(servername_str)) {

intindex = 0;

if(StringUtils.indexOf(referer, "https://") == 0) {

index = 8;

}

elseif (StringUtils.indexOf(referer, "http://") == 0) {

index = 7;

}

if(referer.length() - index < servername_str.length()) {// 长度不够

referer_sign = false;

}

else{ // 比较字符串(主机名称)是否相同

String referer_str = referer.substring(index, index + servername_str.length());

if(!servername_str.equalsIgnoreCase(referer_str)) referer_sign = false;

}

}

elsereferer_sign = false;

}

returnreferer_sign;

}




































Tip:请求重定向和请求转发的区别

一个web资源收到客户端请求后,通知服务器去调用另外一个web资源进行处理,称之为请求转发。

一个web资源收到客户端请求后,通知浏览器去访问另外一个web资源,称之为请求重定向。



lRequestDispatcher.forward方法只能将请求转发给同一个WEB应用中的组件;而HttpServletResponse.sendRedirect 方法还可以重定向到同一个站点上的其他应用程序中的资源,甚至是使用绝对URL重定向到其他站点的资源。

l如果传递给HttpServletResponse.sendRedirect 方法的相对URL以“/”开头,它是相对于整个WEB站点的根目录;如果创建RequestDispatcher对象时指定的相对URL以“/”开头,它是相对于当前WEB应用程序的根目录。

l调用HttpServletResponse.sendRedirect方法重定向的访问过程结束后,浏览器地址栏中显示的URL会发生改变,由初始的URL地址变成重定向的目标URL;调用RequestDispatcher.forward 方法的请求转发过程结束后,浏览器地址栏保持初始的URL地址不变。

lHttpServletResponse.sendRedirect方法对浏览器的请求直接作出响应,响应的结果就是告诉浏览器去重新发出对另外一个URL的访问请求;RequestDispatcher.forward方法在服务器端内部将请求转发给另外一个资源,浏览器只知道发出了请求并得到了响应结果,并不知道在服务器程序内部发生了转发行为。

lRequestDispatcher.forward方法的调用者与被调用者之间共享相同的request对象和response对象,它们属于同一个访问请求和响应过程;而HttpServletResponse.sendRedirect方法调用者与被调用者使用各自的request对象和response对象,它们属于两个独立的访问请求和响应过程。



例:

采用MVC设计模式实现一个简单程序:

lUserRegister.html是一个包含有让用户填写注册信息的FORM表单的HTML页面;

lUser.java是一个代表用户注册信息的普通Java类;

lActionServlet.java是一个用于处理FORM表单信息的Servlet程序,它根据表单提交的信息创建一个User类的实例对象,并把这个User实例对象存储到请求域中,然后将请求转发给另外一个用于显示用户注册信息的Servlet程序;

lJspResultServlet.java是一个用于显示用户注册信息的Servlet程序,JspResultServlet从请求域中取出User实例对象,并显示出这个User实例对象的信息。





package com.hbsi.domain;

public class User {

private String name;

private String email;

public String getName() {

return name;

}

public void setName(String name) {

this.name = name;

}

public String getEmail() {

return email;

}

public void setEmail(String email) {

this.email = email;

}

}





package com.hbsi.servlet;

import java.io.IOException;

import java.io.PrintWriter;

import javax.servlet.ServletException;

import javax.servlet.http.HttpServlet;

import javax.servlet.http.HttpServletRequest;

import javax.servlet.http.HttpServletResponse;

import com.hbsi.domain.User;

public class JsResultServlet extends HttpServlet {



public void doGet(HttpServletRequest request, HttpServletResponse response)

throws ServletException, IOException {

response.setContentType("text/html;charset=UTF-8");

PrintWriter out=response.getWriter();

User user=(User) request.getAttribute("user");

if(user!=null){

out.println("<h1>您的注册信息如下:</h1>");

out.println("用户名:"+user.getName()+"<br/>");

out.println("邮箱:"+user.getEmail()+"<br/>");

}

}

public void doPost(HttpServletRequest request, HttpServletResponse response)

throws ServletException, IOException {

doGet(request, response);

}



}





package com.hbsi.servlet;

import java.io.IOException;

import javax.servlet.RequestDispatcher;

import javax.servlet.ServletException;

import javax.servlet.http.HttpServlet;

import javax.servlet.http.HttpServletRequest;

import javax.servlet.http.HttpServletResponse;

import com.hbsi.domain.User;

public class RegisterServlet extends HttpServlet {



public void doGet(HttpServletRequest request, HttpServletResponse response)

throws ServletException, IOException {

request.setCharacterEncoding("UTF-8");

String name=request.getParameter("username");

String email=request.getParameter("email");

User user=new User();

user.setName(name);

user.setEmail(email);

request.setAttribute("user",user);

RequestDispatcher rd=request.getRequestDispatcher("JsResultServlet");

rd.forward(request, response);

}

public void doPost(HttpServletRequest request, HttpServletResponse response)

throws ServletException, IOException {

doGet(request, response);

}

}



Referer:

public void referer(HttpServletRequest request, HttpServletResponse response)

throws Exception {

String referer = request.getHeader("referer");

if (referer == null || !referer.startsWith("http://localhost")) {

response.sendRedirect("/webTwo/index.jsp");

return;

}

String data = "welcome";

response.getOutputStream().write(data.getBytes());

}

编写URL技巧:

先写'/',给服务器用的就不用写web应用程序名称;给浏览器用的就加上web应用程序名称;

RequestDispatcher:

//请求转发,使用Request域对象把数据带给转发资源;

与重定向的区别:客户端只发出一次请求,服务器端调用多个资源,客户端浏览器地址栏没改变;

获取方式:

ServletContext.getRequestDispatcher(String);

ServletContext.getNamedDispatcher(String);

ServletRequest.getRequestDispatcher(String);

ex:request.getRequestDispatcher("/index.jsp").forward(request, response);

Encoder:乱码处理

request.setCharacterEncoding("UTF-8");//只对Post方式有效

// get方式处理乱码

String value = request.getParameter("username");

String out = new String(value.getBytes("iso8859-1"), "UTF-8");

System.out.println(out);

// 获取请求数据时一般都先检查再使用

获取Header:

// String value = request.getHeader("headername");

// Enumeration headers = request.getHeaders("");

// Enumeration headernames = request.getHeaderNames();
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: