爆破,也就是通過海量的嘗試,最終確定密碼,人們設置密碼具有習慣性,好記、簡單、有象征等,也就有密碼字典一說,但是該字典也是巨量的,但是相對于各種字母符號等組合就顯得輕量非常多
在Java Spring Boot中,使用Redis實現賬號密碼防爆破是一種常見的安全措施。通過Redis的高性能和原子性操作,可以有效地限制用戶在一定時間內的登錄嘗試次數,從而防止暴力破解攻擊。以下是一個巧妙的實現方案:
1. 引入依賴
首先,在pom.xml
中引入Spring Boot的Redis依賴:
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
2. 配置Redis
在application.properties
或application.yml
中配置Redis連接信息:
spring.redis.host=localhost
spring.redis.port=6379
3. 創建Redis工具類
創建一個Redis工具類,用于操作Redis中的登錄嘗試次數:
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Component;import java.util.concurrent.TimeUnit;@Component
public class RedisLoginAttemptService {private static final String LOGIN_ATTEMPT_KEY_PREFIX = "login_attempt:";private static final int MAX_ATTEMPTS = 5; // 最大允許的登錄嘗試次數private static final long LOCK_TIME = 30 * 60; // 鎖定時間,單位:秒@Autowiredprivate StringRedisTemplate redisTemplate;/?**?* 記錄登錄嘗試** @param username 用戶名* @return 當前嘗試次數*/public int recordLoginAttempt(String username) {String key = LOGIN_ATTEMPT_KEY_PREFIX + username;Integer attempts = redisTemplate.opsForValue().increment(key, 1).intValue();if (attempts == 1) {redisTemplate.expire(key, LOCK_TIME, TimeUnit.SECONDS);}return attempts;}/?**?* 檢查是否超過最大嘗試次數** @param username 用戶名* @return 是否超過最大嘗試次數*/public boolean isBlocked(String username) {String key = LOGIN_ATTEMPT_KEY_PREFIX + username;Integer attempts = redisTemplate.opsForValue().get(key) == null ? 0 : Integer.parseInt(redisTemplate.opsForValue().get(key));return attempts != null && attempts >= MAX_ATTEMPTS;}/?**?* 重置登錄嘗試次數** @param username 用戶名*/public void resetLoginAttempts(String username) {String key = LOGIN_ATTEMPT_KEY_PREFIX + username;redisTemplate.delete(key);}
}
4. 在登錄邏輯中使用
在登錄邏輯中使用上述工具類來限制登錄嘗試次數:
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;@Service
public class LoginService {@Autowiredprivate RedisLoginAttemptService loginAttemptService;@Autowiredprivate UserRepository userRepository; // 假設有一個UserRepository用于驗證用戶public boolean login(String username, String password) {// 檢查是否被鎖定if (loginAttemptService.isBlocked(username)) {throw new RuntimeException("賬號已被鎖定,請稍后再試");}// 驗證用戶名和密碼User user = userRepository.findByUsername(username);if (user == null || !user.getPassword().equals(password)) {// 記錄登錄嘗試loginAttemptService.recordLoginAttempt(username);throw new RuntimeException("用戶名或密碼錯誤");}// 登錄成功,重置登錄嘗試次數loginAttemptService.resetLoginAttempts(username);return true;}
}
5. 控制器層
在控制器層調用登錄服務:
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;@RestController
public class LoginController {@Autowiredprivate LoginService loginService;@PostMapping("/login")public String login(@RequestParam String username, @RequestParam String password) {try {if (loginService.login(username, password)) {return "登錄成功";}} catch (RuntimeException e) {return e.getMessage();}return "登錄失敗";}
}
6. 也可以加入ip封禁
啟動應用后,存在ip胡亂請求,也可以加入ip封禁,當ip存在大量登錄失敗請求,可以將ip進行限制,比如1個小時最多進行5~7次登錄,超過拉進黑名單,接下來半個小時或一天都不再校驗他的登錄請求,但是每次也返回一個請求成功的返回碼或者錯誤的登錄令牌,欺騙爆破工具,真真假假,虛虛實實,使它爆破難度激增