Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/379.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 如何阻止或限制对action Struts(grabber)的多个调用_Java_Spring_Struts2 - Fatal编程技术网

Java 如何阻止或限制对action Struts(grabber)的多个调用

Java 如何阻止或限制对action Struts(grabber)的多个调用,java,spring,struts2,Java,Spring,Struts2,我有一个Struts2/Spring应用程序,我想知道如何阻止“抓取器” 在我的服务器上,我检测到一些grabber多次调用相同的action struts,结果是我的服务器在抓取过程中速度太慢,数据库有多个点击 如何停止对同一action struts的多个调用并最小化数据库命中 例如,grabber在同一动作中每分钟调用超过40次 从安全的角度来看,我认为我应该使用缓存来存储ip地址和呼叫号码,并在ip地址和呼叫号码超过限制时阻止它们 但我不知道怎么做 如果您已经这样做了,请告诉我如何实施

我有一个Struts2/Spring应用程序,我想知道如何阻止“抓取器”

在我的服务器上,我检测到一些grabber多次调用相同的action struts,结果是我的服务器在抓取过程中速度太慢,数据库有多个点击

如何停止对同一action struts的多个调用并最小化数据库命中

例如,grabber在同一动作中每分钟调用超过40次


从安全的角度来看,我认为我应该使用缓存来存储ip地址和呼叫号码,并在ip地址和呼叫号码超过限制时阻止它们

但我不知道怎么做


如果您已经这样做了,请告诉我如何实施解决方案?

如果您同时使用struts2和spring,您应该检查spring Security限制用户尝试的功能。如果用户尝试失败3次,则应阻止用户访问页面,如果尝试次数少于3次,则应重置计数器。此外,每次登录尝试都应使用不同的csrf令牌

春季安全 请看一下实施情况

主文件为LimitLoginAuthenticationProvider.java

package com.mkyong.web.handler;

import java.util.Date;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.security.authentication.BadCredentialsException;
import org.springframework.security.authentication.LockedException;
import org.springframework.security.authentication.dao.DaoAuthenticationProvider;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.stereotype.Component;

import com.mkyong.users.dao.UserDetailsDao;
import com.mkyong.users.model.UserAttempts;

@Component("authenticationProvider")
public class LimitLoginAuthenticationProvider extends DaoAuthenticationProvider {

@Autowired
UserDetailsDao userDetailsDao;

@Autowired
@Qualifier("userDetailsService")
@Override
public void setUserDetailsService(UserDetailsService userDetailsService) {
    super.setUserDetailsService(userDetailsService);
}

@Override
public Authentication authenticate(Authentication authentication) 
      throws AuthenticationException {

  try {

    Authentication auth = super.authenticate(authentication);

    //if reach here, means login success, else an exception will be thrown
    //reset the user_attempts
    userDetailsDao.resetFailAttempts(authentication.getName());

    return auth;

  } catch (BadCredentialsException e) { 

    //invalid login, update to user_attempts
    userDetailsDao.updateFailAttempts(authentication.getName());
    throw e;

  } catch (LockedException e){

    //this user is locked!
    String error = "";
    UserAttempts userAttempts = 
                userDetailsDao.getUserAttempts(authentication.getName());

           if(userAttempts!=null){
        Date lastAttempts = userAttempts.getLastModified();
        error = "User account is locked! <br><br>Username : " 
                       + authentication.getName() + "<br>Last Attempts : " + lastAttempts;
    }else{
        error = e.getMessage();
    }

  throw new LockedException(error);
}

}

}
您也可以在尝试3次失败后使用Recaptcha或重置密码

从安全的角度来看,你必须多做一点。例如,使用缓存存储ip地址和登录尝试,如果ip地址和登录尝试用完,则阻止ip。使用Spring和自动过期缓存,使用
expireAfterWrite(10,TimeUnit.MINUTES)
可以轻松实现


如果您只想存储/缓存ipaddress和count as key-value对,在spring框架中也是一个不错的选择。

如果您同时使用struts2和spring,您应该检查spring Security限制用户尝试的功能。如果用户尝试失败3次,则应阻止用户访问页面,如果尝试次数少于3次,则应重置计数器。此外,每次登录尝试都应使用不同的csrf令牌

春季安全 请看一下实施情况

主文件为LimitLoginAuthenticationProvider.java

package com.mkyong.web.handler;

import java.util.Date;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.security.authentication.BadCredentialsException;
import org.springframework.security.authentication.LockedException;
import org.springframework.security.authentication.dao.DaoAuthenticationProvider;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.stereotype.Component;

import com.mkyong.users.dao.UserDetailsDao;
import com.mkyong.users.model.UserAttempts;

@Component("authenticationProvider")
public class LimitLoginAuthenticationProvider extends DaoAuthenticationProvider {

@Autowired
UserDetailsDao userDetailsDao;

@Autowired
@Qualifier("userDetailsService")
@Override
public void setUserDetailsService(UserDetailsService userDetailsService) {
    super.setUserDetailsService(userDetailsService);
}

@Override
public Authentication authenticate(Authentication authentication) 
      throws AuthenticationException {

  try {

    Authentication auth = super.authenticate(authentication);

    //if reach here, means login success, else an exception will be thrown
    //reset the user_attempts
    userDetailsDao.resetFailAttempts(authentication.getName());

    return auth;

  } catch (BadCredentialsException e) { 

    //invalid login, update to user_attempts
    userDetailsDao.updateFailAttempts(authentication.getName());
    throw e;

  } catch (LockedException e){

    //this user is locked!
    String error = "";
    UserAttempts userAttempts = 
                userDetailsDao.getUserAttempts(authentication.getName());

           if(userAttempts!=null){
        Date lastAttempts = userAttempts.getLastModified();
        error = "User account is locked! <br><br>Username : " 
                       + authentication.getName() + "<br>Last Attempts : " + lastAttempts;
    }else{
        error = e.getMessage();
    }

  throw new LockedException(error);
}

}

}
您也可以在尝试3次失败后使用Recaptcha或重置密码

从安全的角度来看,你必须多做一点。例如,使用缓存存储ip地址和登录尝试,如果ip地址和登录尝试用完,则阻止ip。使用Spring和自动过期缓存,使用
expireAfterWrite(10,TimeUnit.MINUTES)
可以轻松实现


如果您只想存储/缓存ipaddress和count as key-value pair,在spring framework中也是一个不错的选择。

您可以这样做。每次响应来自同一ip时,在struts2中使用拦截器,然后重定向到警告页面。请阅读以下内容:。然后实现您的拦截器,检查ip或其他内容,并过滤不需要的连接。请注意,您可能也可以在web服务器级别执行某些操作,尝试向管理员询问,如果您有,是否可以使用Guava或Ehcache之类的缓存实现解决方案,并为缓存中的每个条目定义过期时间?例如,我如何在10分钟内检查电话号码?谢谢,验证码是最简单的解决方案。当验证码显示在屏幕上时,请禁用其他面板。@ParthTrivedi例如,当一个操作struts在10分钟内被调用过多次时,您是否有一种简单的方法来使用Struts2实现验证码?谢谢。您可以这样做。每次响应来自同一ip时,请在struts2中使用拦截器,然后重定向到警告页面。请阅读以下内容:。然后实现您的拦截器,检查ip或其他内容,并过滤不需要的连接。请注意,您可能也可以在web服务器级别执行某些操作,尝试向管理员询问,如果您有,是否可以使用Guava或Ehcache之类的缓存实现解决方案,并为缓存中的每个条目定义过期时间?例如,我如何在10分钟内检查电话号码?谢谢,验证码是最简单的解决方案。当验证码显示在屏幕上时,请禁用其他面板。@ParthTrivedi例如,当一个操作struts在10分钟内被调用过多次时,您是否有一种简单的方法来使用Struts2实现验证码?谢谢谢谢你的代码示例,它非常有用。但你能给我一个样本,让我用Guavas自动过期缓存来做吗?我对这一点非常感兴趣。ImmutableSortedSet set=ContiguousSet.create(Range.open(1,5),discreatedDomain.integers());//集合包含[2,3,4]个连续集合。创建(Range.greaterThan(0),DiscreteDomain.integers());//集合包含[1,2,…,Integer.MAX_VALUE],这里是缓存的全局过期时间否?是否可以为每个条目设置ttl?我正试图用ehcache实现这一点,但缓存中的元素永远不会过期。对于你的struts2样品,我在哪里可以使用它?什么是“我的监听器”?对于ttl
expireAfterWrite(10,TimeUnit.MINUTES)
。但是您正在使用ehcache吗?您可以通过
CacheBuilder.removalListener(removalListener)
为缓存指定一个删除侦听器,以便在删除条目时执行某些操作。
RemovalListener
获得一个
RemovalNotification
,它指定了
RemovalCause
、键和值。为了记录异常,该页面上有一个示例。感谢您提供此代码示例,它非常有用。但你能给我一个样本,让我用Guavas自动过期缓存来做吗?我对这一点非常感兴趣。ImmutableSortedSet set=ContiguousSet.create(Range.open(1,5),discreatedDomain.integers());//集合包含[2,3,4]个连续集合。创建(Range.greaterThan(0),DiscreteDomain.integers());//集合包含[1,2,…,Integer.MAX_VALUE],这里是缓存的全局过期时间否?可以为ea设置ttl
public String intercept (ActionInvocation invocation) throws Exception {
// Get the action context from the invocation so we can access the
// HttpServletRequest and HttpSession objects.
final ActionContext context = invocation.getInvocationContext ();
HttpServletRequest request = (HttpServletRequest) context.get(HTTP_REQUEST);
HttpSession session =  request.getSession (true);

// Is there a "user" object stored in the user's HttpSession?
Object user = session.getAttribute (USER_HANDLE);
if (user == null) {
    // The user has not logged in yet.

    // Is the user attempting to log in right now?
    String loginAttempt = request.getParameter (LOGIN_ATTEMPT);
    if (! StringUtils.isBlank (loginAttempt) ) { // The user is attempting to log in.

        // Process the user's login attempt.
        if (processLoginAttempt (request, session) ) {
            // The login succeeded send them the login-success page.
            return "login-success";
        } else {
            // The login failed. Set an error if we can on the action.
            Object action = invocation.getAction ();
            if (action instanceof ValidationAware) {
                ((ValidationAware) action).addActionError ("Username or password incorrect.");
            }
        }
    }

    // Either the login attempt failed or the user hasn't tried to login yet, 
    // and we need to send the login form.
    return "login";
} else {
    return invocation.invoke ();
}
}