JAVA管理系统:遇到的请求安全问题

 

1.后台使用jfinal作为框架的管理系统。

使用Interceptor + Handler 拦截用户每次的请求做一些安全校验。

登陆拦截器:

public void intercept(Invocation ai) {
		// TODO Auto-generated method stub
		HttpSession session = ai.getController().getSession(); 
		
		//判断session是否为空
        if(session == null){  
            ai.getController().redirect("/login?systype="+ai.getControllerKey());  
        }  
        else{
            //判断session中的用户是否还存在
	        String userAccount = (String) session.getAttribute("userAccount");
	        String userName = (String) session.getAttribute("userName");
	        if(userName != null&&userAccount !=null) {  
	        	ai.getController().redirect("/"+ai.getMethod().getName());  
	            ai.invoke();
	        }  
            else { 
            	ai.getController().redirect("/login?systype="+ai.getControllerKey());  
            }  
        }  
    }  

请求拦截器:

    public void handle(String target, HttpServletRequest request,HttpServletResponse response, boolean[] isHandled) {
		
		
		Cookie[] cookies = request.getCookies();
		//对cookie进行了处理
        if(cookies!=null){
		    for(Cookie cookie : cookies){
		      String value = cookie.getValue(); 
              StringBuilder builder = new StringBuilder(); 
              builder.append("JSESSIONID=" + value + "; "); 
              builder.append("Secure; "); 
              builder.append("HttpOnly; "); 
              Calendar cal = Calendar.getInstance(); 
              cal.add(Calendar.HOUR, 1); 
              Date date = cal.getTime(); 
              Locale locale = Locale.CHINA; 
              SimpleDateFormat sdf = new SimpleDateFormat("dd-MM-yyyy HH:mm:ss",locale); 
              builder.append("Expires=" + sdf.format(date)); 
              response.setHeader("Set-Cookie", builder.toString());
            
		    }
		}
        
		String ctx = WebContextUtil.getContextPath(request);
		String referer=request.getHeader("Referer");  
		
		if(StrKit.notBlank(referer) && !referer.contains(ctx)){ 
			response.setContentType("text/html;charset=GBK");
        	response.setCharacterEncoding("GBK");
        	response.setStatus(403);
        	try {
				response.getWriter().print("对不起,您的请求非法,系统拒绝响应!");
			} catch (IOException e) {
				
				e.printStackTrace();
			}
        	return;
		}else{
			String method = request.getMethod();
	        if(!"GET".equals(method)&&!"POST".equals(method)&&!"HEAD".equals(method)){
	        	response.setContentType("text/html;charset=GBK");
	        	response.setCharacterEncoding("GBK");
	        	response.setStatus(403);
	        	try {
					response.getWriter().print("对不起,您的请求非法,系统拒绝响应!");
				} catch (IOException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
	        	return;
	        }else{
	        	 if (target.indexOf(".") == -1&&!target.contains("manager")){
	                 request = new HttpServletRequestWrapper(request);
	             }
	            
	             next.handle(target, request, response, isHandled);
	        }
		}
    }

描述:XssHandler 这个类的主要作用是对返还给用户的Cookie进行一些设置,还有就是对请求中的一些特殊字符进行转义和判断。

一个域名下面可能存在着很多个cookie对象。

name字段为一个cookie的名称。

value字段为一个cookie的值。

domain字段为可以访问此cookie的域名。

非顶级域名,如二级域名或者三级域名,设置的cookie的domain只能为顶级域名或者二级域名或者三级域名本身,不能设置其他二级域名的cookie,否则cookie无法生成。

顶级域名只能设置domain为顶级域名,不能设置为二级域名或者三级域名,否则cookie无法生成。

二级域名能读取设置了domain为顶级域名或者自身的cookie,不能读取其他二级域名domain的cookie。所以要想cookie在多个二级域名中共享,需要设置domain为顶级域名,这样就可以在所有二级域名里面或者到这个cookie的值了。
顶级域名只能获取到domain设置为顶级域名的cookie,其他domain设置为二级域名的无法获取。

path字段为可以访问此cookie的页面路径。 比如domain是abc.com,path是/test,那么只有/test路径下的页面可以读取此cookie。

expires/Max-Age 字段为此cookie超时时间。若设置其值为一个时间,那么当到达此时间后,此cookie失效。不设置的话默认值是Session,意思是cookie会和session一起失效。当浏览器关闭(不是浏览器标签页,而是整个浏览器) 后,此cookie失效。

Size字段 此cookie大小。

http字段  cookie的httponly属性。若此属性为true,则只有在http请求头中会带有此cookie的信息,而不能通过document.cookie来访问此cookie。

secure 字段 设置是否只能通过https来传递此条cookie

 

 

Cookie的Secure属性

基于安全的考虑,需要给cookie加上Secure和HttpOnly属性,HttpOnly比较好理解,设置HttpOnly=true的cookie不能被js获取到,无法用document.cookie打出cookie的内容。

Secure属性是说如果一个cookie被设置了Secure=true,那么这个cookie只能用https协议发送给服务器,用http协议是不发送的。换句话说,cookie是在https的情况下创建的,而且他的Secure=true,那么之后你一直用https访问其他的页面(比如登录之后点击其他子页面),cookie会被发送到服务器,你无需重新登录就可以跳转到其他页面。但是如果这是你把url改成http协议访问其他页面,你就需要重新登录了,因为这个cookie不能在http协议中发送。

例子是:

前提条件:https://localhost:9102应用对cookie设置了Secure=true

1. 访问 https://localhost:9102/manager

2. 输入用户名、密码,用IE或者Chrome的developer tool会看到response的header里,set-cookie的值里有Secure属性

3. 登录后,继续访问https://localhost:9102/manager#user,可以正常看到内容

4. 修改url,访问http://localhost:9100/manager#domain,会跳转到登录页面,因为cookie在http协议下不发送给服务器,服务器要求用户重新登录

在工作当中遇到了360浏览器兼容性问题。当使用XssHandler将Cookie设置成只支持HTTPS协议时,会导致后台接收请求时接收不到Cookie从而找不到session,导致tiao'跳出登陆系统。其他浏览器(chrome,原生IE)并未出现此情况。

后调查发现,因为JFINAL框架,前台调用后台Controller时,直接写路径不制定具体方法,虽然会默认制定到该Controller下的index方法。而当改变cookie支持协议后,继续使用这种默认方式,会使360l浏览器发送请求时不携带cookie,所以要将1路径改为/controllerName/index使用。

你可能感兴趣的:(JAVA管理系统编程)