|
马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。
您需要 登录 才可以下载或查看,没有帐号?立即注册
x
但是对于JAVA技术类的学习,我觉得大课堂反而会影响自身独立思考的过程,因为上课的时候,老师讲课的速度很快为了不遗漏要点,通常会仔细的听,web在JavaWeb使用程中,出格是网站开辟中,我们偶然候必要为使用程序增添一个进侵检测程序来避免歹意革新的功效,避免不法用户不休的往Web使用中反复发送数据。固然,进侵检测能够用良多办法完成,包含软件、硬件防火墙,进侵检测的战略也良多。在这里我们次要先容的是JavaWeb使用程序中经由过程软件的体例完成复杂的进侵检测及进攻。
该办法的完成道理很复杂,就是用户会见Web体系时纪录每一个用户的信息,然落后行对比,并依据设定的战略(好比:1秒钟革新页面10次)判别用户是不是属于歹意革新。
我们的进侵检测程序应当放到一切JavaWeb程序的实行前,也即若发明用户是歹意革新就不再持续实行JavaWeb中的别的部份内容,不然就会得到了意义。这就必要以插件的体例把进侵检测的程序置进JavaWeb使用中,使得每次用户会见JavaWeb,都先要到这个进侵检测程序中报一次到,切合划定规矩才干放行。
JavaWeb使用大抵分为两种,一种纯JSP(+JavaBean)体例,一种是基于框架(如Struts、EasyJWeb等)的。第一种体例的JavaWeb能够经由过程JavaServlet中的Filter接话柄现,也即完成一个Filter接口,在其doFilter办法中拔出进侵检测程序,然后再web.xml中作复杂的设置便可。在基于框架的Web使用中,因为一切使用都有一个出口,因而能够把进侵检测的程序间接拔出框架出口引擎中,使框架自己撑持进侵检测功效。固然,也能够经由过程完成Filter接口来完成。
在EasyJWeb框架中,已置进了复杂进侵检测的程序,因而,这里我们以EasyJWeb框架为例,先容详细的完成办法及源码,完全的代码能够在EasyJWeb源码中找到。
在基于EasyJWeb的JavaWeb使用中(如http://www.easyjf.com/bbs/),默许情形下你只需一连革新页面次数过量,即会弹出以下的毛病:
EasyJWeb框架友谊提醒!:-):
您对页面的革新太快,请守候60秒后再革新页面!
具体请查询http://www.easyjf.com
2、用户会见信息纪录UserConnect.java类
这个类是一个复杂的JavaBean,次要代表用户的信息,包含用户名、IP、第一次会见工夫、最初登录工夫、登录次数、用户形态等。全体
代码以下:
packagecom.easyjf.web;
importjava.util.Date;
/**
*
*
Title:用户考证信息
*
Description:纪录用户登录信息,判别用户登录情形
*
Copyright:Copyright(c)2006
*
Company:www.easyjf.com
*@author蔡世友
*@version1.0
*/
publicclassUserConnect{
privateStringuserName;
privateStringip;
privateDatefirstFailureTime;
privateDatelastLoginTime;
privateintfailureTimes;//用户登录失利次数
privateintstatus=0;//用户形态0暗示一般,-1暗示锁定
publicintgetFailureTimes(){
returnfailureTimes;
}
publicvoidsetFailureTimes(intfailureTimes){
this.failureTimes=failureTimes;
}
publicDategetFirstFailureTime(){
returnfirstFailureTime;
}
publicvoidsetFirstFailureTime(DatefirstFailureTime){
this.firstFailureTime=firstFailureTime;
}
publicStringgetIp(){
returnip;
}
publicvoidsetIp(Stringip){
this.ip=ip;
}
publicDategetLastLoginTime(){
returnlastLoginTime;
}
publicvoidsetLastLoginTime(DatelastLoginTime){
this.lastLoginTime=lastLoginTime;
}
publicStringgetUserName(){
returnuserName;
}
publicvoidsetUserName(StringuserName){
this.userName=userName;
}
publicintgetStatus(){
returnstatus;
}
publicvoidsetStatus(intstatus){
this.status=status;
}
}
3、监控线程UserConnectManage.java类
这是进侵检测的中心部分,次要完成详细的进侵检测、纪录、判别用户信息、在线用户的革新等功效,并供应别的使用程序利用本组件的挪用接口。
packagecom.easyjf.web;
importjava.util.Date;
importjava.util.HashMap;
importjava.util.HashSet;
importjava.util.Iterator;
importjava.util.Map;
importjava.util.Set;
importorg.apache.log4j.Logger;
/**
*
*
Title:用户进侵检测信息
*
Description:用于判别用户革新情形反省,默许为10秒钟以内一连毗连10次为超时
*
Copyright:Copyright(c)2006
*
Company:www.easyjf.com
*@author蔡世友
*@version1.0
*/
publicclassUserConnectManage{
privatestaticfinalLoggerlogger=(Logger)Logger.getLogger(UserConnectManage.class.getName());
privatestaticintmaxFailureTimes=10;//最年夜登录失利次数
privatestaticlongmaxFailureInterval=10000;//毫秒,到达最年夜登录次数且在这个工夫局限内
privatestaticlongwaitInterval=60000;//失利后承受毗连的守候工夫,默许1分钟
privatestaticintmaxOnlineUser=200;//同时在线的最年夜数
privatefinalstaticMapusers=newHashMap();//利用ip+userName为key寄存用户登录信息UserLoginAuth
privatestaticThreadcheckThread=null;
privatestaticclassCheckTimeOutimplementsRunnable{
privateThreadparentThread;
publicCheckTimeOut(ThreadparentThread)
{
this.parentThread=parentThread;
synchronized(this){
if(checkThread==null){
checkThread=newThread(this);
//System.out.println("创立一个新线程!");
checkThread.start();
}
}
}
publicvoidrun(){
while(true)
{
if(parentThread.isAlive()){
try{
Thread.sleep(2000);
inti=0;
if(users.size()>maxOnlineUser)//当到达最年夜用户数时扫除
{
synchronized(users){//实行删除操纵
Iteratorit=users.keySet().iterator();
Setset=newHashSet();
Datenow=newDate();
while(it.hasNext())
{
Objectkey=it.next();
UserConnectuser=(UserConnect)users.get(key);
if(now.getTime()-user.getFirstFailureTime().getTime()>maxFailureInterval)//删除超时的用户
{
set.add(key);
logger.info("删除一个超时的毗连"+i);
i++;
}
}
if(i<5)//假如删除少于5个,则强行删除1/2在线纪录,就义功能的情形下包管内存
{
intnum=maxOnlineUser/2;
it=users.keySet().iterator();
while(it.hasNext()&&i{
set.add(it.next());
logger.info("删除一个过剩的毗连"+i);
i++;
}
}
users.keySet().removeAll(set);
}
}
}
catch(Exceptione)
{
e.printStackTrace();
}
}
else
{
break;
}
}
logger.info("监督程序运转停止!");
}
}
//经由过程checkLoginValidate判别是不是正当的登录毗连,假如正当则持续,不法则实行
publicstaticbooleancheckLoginValidate(Stringip,StringuserName)//只反省认证失利次数
{
booleanret=true;
Datenow=newDate();
Stringkey=ip+":"+userName;
UserConnectauth=(UserConnect)users.get(key);
if(auth==null)//把用户以后的会见信息到场到users容器中
{
auth=newUserConnect();
auth.setIp(ip);
auth.setUserName(userName);
auth.setFailureTimes(0);
auth.setFirstFailureTime(now);
users.put(key,auth);
if(checkThread==null)newCheckTimeOut(Thread.currentThread());
}
else
{
if(auth.getFailureTimes()>maxFailureTimes)
{
//假如在限制的工夫距离内,则前往回绝用户毗连的信息
if((now.getTime()-auth.getFirstFailureTime().getTime()){
ret=false;
auth.setStatus(-1);
}
elseif(auth.getStatus()==-1&&(now.getTime()-auth.getFirstFailureTime().getTime()<(maxFailureInterval+waitInterval)))//重置计数器
{
ret=false;
}
else
{
auth.setFailureTimes(0);
auth.setFirstFailureTime(now);
auth.setStatus(0);
}
}
//登录次数加1
auth.setFailureTimes(auth.getFailureTimes()+1);
}
//System.out.println(key+":"+auth.getFailureTimes()+":"+ret+":"+(now.getTime()-auth.getFirstFailureTime().getTime()));
returnret;
}
publicstaticvoidreset(Stringip,StringuserName)//重置用户信息
{
Datenow=newDate();
Stringkey=ip+":"+userName;
UserConnectauth=(UserConnect)users.get(key);
if(auth==null)//把用户以后的会见信息到场到users容器中
{
auth=newUserConnect();
auth.setIp(ip);
auth.setUserName(userName);
auth.setFailureTimes(0);
auth.setFirstFailureTime(now);
users.put(key,auth);
}
else
{
auth.setFailureTimes(0);
auth.setFirstFailureTime(now);
}
}
publicstaticvoidremove(Stringip,StringuserName)//删除用户在容器中的纪录
{
Stringkey=ip+":"+userName;
users.remove(key);
}
publicstaticvoidclear()//清空容器中内容
{
if(!users.isEmpty())users.clear();
}
publicstaticlonggetMaxFailureInterval(){
returnmaxFailureInterval;
}
publicstaticvoidsetMaxFailureInterval(longmaxFailureInterval){
UserConnectManage.maxFailureInterval=maxFailureInterval;
}
publicstaticintgetMaxFailureTimes(){
returnmaxFailureTimes;
}
publicstaticvoidsetMaxFailureTimes(intmaxFailureTimes){
UserConnectManage.maxFailureTimes=maxFailureTimes;
}
publicstaticintgetMaxOnlineUser(){
returnmaxOnlineUser;
}
publicstaticvoidsetMaxOnlineUser(intmaxOnlineUser){
UserConnectManage.maxOnlineUser=maxOnlineUser;
}
publicstaticlonggetWaitInterval(){
returnwaitInterval;
}
publicstaticvoidsetWaitInterval(longwaitInterval){
UserConnectManage.waitInterval=waitInterval;
}
4、挪用接口
在必要进进侵检测判别的中央,间接利用UserConnectManage类中的checkLoginValidate办法便可。如EasyJWeb的中心Servlet
com.easyjf.web.ActionServlet中挪用UserConnectManage的代码:
if(!UserConnectManage.checkLoginValidate(request.getRemoteAddr(),"guest"))
{
info(request,response,newException("您对页面的革新太快,请守候"+UserConnectManage.getWaitInterval()/1000+"秒
后再革新页面!"));
return;
}
5、总结
固然,这里供应的办法只是一个复杂的完成示例,因为下面的用户信息是间接保留在内存中,若并发用户很年夜的时分的代码的占用,能够思索引进数据库来纪录用户的会见信息,固然响应的实行效力一定用下降。下面先容的完成中,进侵检测判别的战略也只要用户会见次数实时间距离两个元素,您还能够依据你的完成情形增添别的的检测元素。
你说是sun公司对她研究的透还是微软?针对自己工具开发的.net性能上肯定会站上风的。 |
|