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;
}
![](http://www.2cto.com/uploadfile/2012/1029/20121029093615397.jpg)
![](http://www.2cto.com/uploadfile/2012/1029/20121029093615355.jpg)
![](http://www.2cto.com/uploadfile/2012/1029/20121029093616466.jpg)
![](http://www.2cto.com/uploadfile/2012/1029/20121029093616140.jpg)
![](http://www.2cto.com/uploadfile/2012/1029/20121029093616761.jpg)
![](http://www.2cto.com/uploadfile/2012/1029/20121029093616520.jpg)
![](http://www.2cto.com/uploadfile/2012/1029/20121029093616578.jpg)
![](http://www.2cto.com/uploadfile/2012/1029/20121029093617137.jpg)
![](http://www.2cto.com/uploadfile/2012/1029/20121029093617517.jpg)
![](http://www.2cto.com/uploadfile/2012/1029/20121029093617690.jpg)
![](http://www.2cto.com/uploadfile/2012/1029/20121029093618321.jpg)
![](http://www.2cto.com/uploadfile/2012/1029/20121029093618872.jpg)
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();
* 验证请求的合法性,防止跨域攻击
*
* @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;
}
![](http://www.2cto.com/uploadfile/2012/1029/20121029093615397.jpg)
![](http://www.2cto.com/uploadfile/2012/1029/20121029093615355.jpg)
![](http://www.2cto.com/uploadfile/2012/1029/20121029093616466.jpg)
![](http://www.2cto.com/uploadfile/2012/1029/20121029093616140.jpg)
![](http://www.2cto.com/uploadfile/2012/1029/20121029093616761.jpg)
![](http://www.2cto.com/uploadfile/2012/1029/20121029093616520.jpg)
![](http://www.2cto.com/uploadfile/2012/1029/20121029093616578.jpg)
![](http://www.2cto.com/uploadfile/2012/1029/20121029093617137.jpg)
![](http://www.2cto.com/uploadfile/2012/1029/20121029093617517.jpg)
![](http://www.2cto.com/uploadfile/2012/1029/20121029093617690.jpg)
![](http://www.2cto.com/uploadfile/2012/1029/20121029093618321.jpg)
![](http://www.2cto.com/uploadfile/2012/1029/20121029093618872.jpg)
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();
相关文章推荐
- js跨域脚本攻击java解决方案
- ajax跨域后台java两种解决方案
- ajax的跨域解决方案(java+ajax)
- XSS跨域攻击和SQL注入解决方案
- java跨域解决方案
- XSS 跨域脚本攻击解决方案
- java 模拟http请求(跨域解决方案)
- “前端展示SL后台数据调取java”这种开发模式的跨域访问失败解决方案
- ajax跨域解决方案(服务端仅限java)
- java.lang.NoClassDefFoundError: javax/el/ELResolver解决方案
- 前端跨域问题的几种解决方案
- ajax跨域CORS方式JAVA Spring Boot配置
- Java调用外部程序解决方案
- Spring Session java连接redis 失败解决方案
- WebApi 跨域问题解决方案:CORS
- java.lang.ClassNotFoundException: org.apache.jsp.index_jsp解决方案
- java系统高并发解决方案(转载)
- java系统高并发解决方案(转载)
- Java在J2EE工程中路径寻址问题终极解决方案
- tomcat调用axis服务时出现 java.lang.InvocationException解决方案