国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

基于Springboot 限制IP訪問(wèn)指定的網(wǎng)址

這篇具有很好參考價(jià)值的文章主要介紹了基于Springboot 限制IP訪問(wèn)指定的網(wǎng)址。希望對(duì)大家有所幫助。如果存在錯(cuò)誤或未考慮完全的地方,請(qǐng)大家不吝賜教,您也可以點(diǎn)擊"舉報(bào)違法"按鈕提交疑問(wèn)。

基于Springboot 限制 IP 訪問(wèn)指定的網(wǎng)址

方式一:

添加一個(gè)簡(jiǎn)單的白名單,然后只有白名單上面的 IP 才能訪問(wèn)網(wǎng)站,否則不能訪問(wèn)
這是只是一個(gè)很簡(jiǎn)單的實(shí)現(xiàn)方法
首先:在 application.yml 配置 IP 白名單

my:
  ipList:
    - 192.168.3.3
    - 192.168.2.12
    - 192.168.5.24
    - 152.63.54.26

想要引用到配置文件里面的 String 數(shù)組,如果使用普通的 @Value 是不行的,必須使用其他方法

步驟一:創(chuàng)建一個(gè)實(shí)體類

@Component
@ConfigurationProperties(prefix = "my") // 這里是對(duì)應(yīng)的配置文件里面自定義的 my
public class My {

    private String[] ipList;

    public My(String[] ipList) {
        this.ipList = ipList;
    }

    public String[] getIpList() {
        return ipList;
    }

    public void setIpList(String[] ipList) {
        this.ipList = ipList;
    }
}

這樣配置文件的信息就保存在了這個(gè)實(shí)體類里面
在 Controller 里面比對(duì) IP

@Controller
public class LoginController {

    @Autowired
    private My myIpList;

    @PostMapping("/login")
    @ResponseBody
    public String login(@RequestBody LoginForm loginForm, HttpServletRequest request) {
        String [] ipList = myIpList.getIpList();

        String IPAddress = loginForm.getIpAddress();
    	// 如果前端傳遞過(guò)來(lái)的 IP 在白名單里面,就返回 OK,如果不在,就返回 error
        for (String s : ipList) {
            if (s.equals(IPAddress)) {
                return "OK";
            }
        }
        return "error";
    }

}

方式二:限制 IP 訪問(wèn)的次數(shù)

這個(gè)是利用了 aop 的切面編程,如果同一個(gè) IP 訪問(wèn)一個(gè)地址一分鐘之內(nèi)超過(guò)10次,就會(huì)把這個(gè) IP 拉入黑名單,在自定義的時(shí)間內(nèi)是不能再次訪問(wèn)這個(gè)網(wǎng)站的。

第一步,在 application.yml 中配置 Redis 相關(guān)設(shè)置

spring:
  redis:
    # 超時(shí)時(shí)間
    timeout: 10000ms
    # 服務(wù)器地址
    host: 192.168.1.1
    # 服務(wù)器端口
    port: 6379
    # 數(shù)據(jù)庫(kù)
    database: 0
    # 密碼
    password: xxxxxxx
    lettuce:
      pool:
        # 最大連接數(shù),默認(rèn)為 8
        max-active: 1024
        # 最大連接阻塞等待時(shí)間,默認(rèn) -1
        max-wait: 10000ms
        # 最大空閑連接
        max-idle: 200
        # 最小空閑連接
        min-idle: 5

第一步,自定義一個(gè)注解

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
@Documented
@Order(Ordered.HIGHEST_PRECEDENCE)
public @interface RequestLimit {

    /**
     * 允許訪問(wèn)的最大次數(shù)
     */
    int count() default Integer.MAX_VALUE;

    /**
     * 時(shí)間段,單位為毫秒,默認(rèn)值一分鐘
     */
    long time() default 60000;
}

第二步:序列化 redis 類

@Configuration
@Slf4j
public class RedisConfiguration {

    @Bean
    @ConditionalOnMissingBean
    public RedisTemplate redisTemplate(RedisConnectionFactory connectionFactory) {
        System.err.println("調(diào)用了 Redis 配置類");
        RedisTemplate<String, Object> redisTemplate = new RedisTemplate<>();
        // String 類型 key 序列器
        redisTemplate.setKeySerializer(new StringRedisSerializer());
        // String 類型 value 序列器
        redisTemplate.setValueSerializer(new GenericJackson2JsonRedisSerializer());
        // Hash 類型 value 序列器
        redisTemplate.setHashKeySerializer(new StringRedisSerializer());
        // Hash 類型 value 序列器
        redisTemplate.setHashValueSerializer(new GenericJackson2JsonRedisSerializer());
        redisTemplate.setConnectionFactory(connectionFactory);
        return redisTemplate;
    }
}

第三步:創(chuàng)建一個(gè)切面類

@Aspect
@Component
@Slf4j
public class RequestLimitContract {


    private static final Logger logger = LoggerFactory.getLogger("requestLimitLogger");

    @Autowired
    private RedisTemplate<String, Object> redisTemplate;
    @Autowired
    private ObjectMapper objectMapper;

    @Before("within(@org.springframework.stereotype.Controller *) && @annotation(limit)")
    public void requestLimit(final JoinPoint joinPoint , RequestLimit limit) throws RequestLimitException {
        try {
            LoginForm loginForm = new LoginForm();
            Object[] args = joinPoint.getArgs();
            HttpServletRequest request = null;
            for (int i = 0; i < args.length; i++) {
                if (args[i] instanceof HttpServletRequest) {
                    request = (HttpServletRequest) args[i];
                    break;
                } else if (args[i] instanceof LoginForm) {
                    loginForm = (LoginForm) args[i];
                }

            }
            if (request == null) {
                throw new RequestLimitException("方法中缺失HttpServletRequest參數(shù)");
            }

            //獲取請(qǐng)求中的ip與url鏈接參數(shù) 用于拼接key存放redis中
            String ip = loginForm.getIpAddress();
            String url = request.getRequestURL().toString();
            Long  interview_time = new Date().getTime();
            String key = "req_limit_".concat(url).concat("---").concat(ip);
            System.err.println("準(zhǔn)備保存在redis中的數(shù)據(jù)為-->");
            Map<String, Long> form = new HashMap<>();
            form.put("size", 1L);
            form.put("saveRedisTime", interview_time);

            if (redisTemplate.opsForValue().get(key) == null) {
                System.err.println(form);
                redisTemplate.opsForValue().set(key, form);
            } else {
                //用于進(jìn)行ip訪問(wèn)的計(jì)數(shù)
                Map<String, Long> result = (Map<String, Long>) redisTemplate.opsForValue().get(key);
                System.err.println("從redis取到的數(shù)據(jù)(內(nèi)部)");
                System.out.println(result);

                assert result != null;
                result.put("size", result.get("size") + 1);
                redisTemplate.opsForValue().set(key, result);


                if (result.get("size") > 10) {
                    logger.info("用戶IP[" + ip + "]訪問(wèn)地址[" + url + "]超過(guò)了限定的次數(shù)[" + limit.count() + "]");
                    throw new RequestLimitException();
                }

                // 如果訪問(wèn)次數(shù)小于 10 次,那么一分鐘過(guò)后就直接刪除這個(gè)節(jié)點(diǎn)
                if (result.get("size") <= limit.count()) {
                    //創(chuàng)建一個(gè)定時(shí)器
                    Timer timer = new Timer();
                    TimerTask timerTask = new TimerTask() {
                        @Override
                        public void run() {
                            redisTemplate.delete(key);
                        }
                    };
                    //這個(gè)定時(shí)器設(shè)定在time規(guī)定的時(shí)間之后會(huì)執(zhí)行上面的remove方法,也就是說(shuō)在這個(gè)時(shí)間后它可以重新訪問(wèn)
                    timer.schedule(timerTask, limit.time());
                }
            }
        }catch (RequestLimitException e){
            throw e;
        }catch (Exception e){
            logger.error("發(fā)生異常",e);
        }
    }
}

第四步,創(chuàng)建一個(gè)定時(shí)器

記住要在啟動(dòng)類上面開啟啟動(dòng)定時(shí)器注解

@Component
public class ScheduledTask {

    @Autowired
    private RedisTemplate<String, Object> redisTemplate;

//    @Value("${properties.continueTime}")
    private final long continueTime = 120;  // 這是是黑名單的保存時(shí)間,在這個(gè)時(shí)間內(nèi),同一個(gè)IP將不能繼續(xù)訪問(wèn)
    //    @Scheduled(cron = "0 0 0 * * ?") // 每天凌晨觸發(fā)一次
    @Scheduled(fixedRate = 1000000) // 每 30s 執(zhí)行一次
    public void deleteDataScheduled() {
        Set<String> keys = redisTemplate.keys("*");
        if (keys == null || keys.size() == 0) {
            return;
        }
        System.out.println("redis里面所有的key為:" + keys.toString());

        long now_time = new Date().getTime();

        for (String key : keys) {
            Map<String, Long> result = (Map<String, Long>) redisTemplate.opsForValue().get(key);
            assert result != null;
            System.err.println(result);
            // 計(jì)算出時(shí)間差
            long createTime = result.get("saveRedisTime");
            System.err.println("創(chuàng)建時(shí)間為:" + createTime);
            long l = (now_time - createTime) / 1000L;
            System.err.println("時(shí)間差為:" + l);
            if (l > continueTime) {
                System.out.println("禁止時(shí)間結(jié)束,解除時(shí)間限制!?。?);
                redisTemplate.delete(key);
                return;
            }
            int s = Math.toIntExact(result.get("size"));
            System.out.println("s===>" + s + "   l===>" + l);
            if (s <= 10) {
                if (l > 60) {
                    System.out.println("一分鐘結(jié)束,刪除節(jié)點(diǎn),重新計(jì)時(shí)");
                    redisTemplate.delete(key);
                }
            }
        }
    }
}

第五步:在需要的類上使用自己自定義的注解

@PostMapping("/login")
    @RequestLimit(count=10,time=60000)   // 這個(gè)注解就是開啟IP限制的注解,這個(gè)注解的業(yè)務(wù)都是自己寫的
    @ResponseBody
    public String login(@RequestBody LoginForm loginForm, HttpServletRequest request) {

        System.out.println("執(zhí)行登錄代碼");

        String name = loginForm.getUsername();
        String IPAddress = loginForm.getIpAddress();
        String timestamp = String.valueOf(new Date().getTime());
        String info = Arrays.toString(ipList);

        request.setAttribute("userName", name);
        request.setAttribute("ipAddress", IPAddress);

        return "OK1";
    }

總結(jié):在這里針對(duì) IP 的限制就結(jié)束了,總而言之還是比較簡(jiǎn)單的,沒(méi)有什么特別難的點(diǎn),如果大家在你們本地跑不起來(lái),或者有其他問(wèn)題,歡迎大家的留言。。。。文章來(lái)源地址http://www.zghlxwxcb.cn/news/detail-801495.html

到了這里,關(guān)于基于Springboot 限制IP訪問(wèn)指定的網(wǎng)址的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來(lái)自互聯(lián)網(wǎng)用戶投稿,該文觀點(diǎn)僅代表作者本人,不代表本站立場(chǎng)。本站僅提供信息存儲(chǔ)空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請(qǐng)注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實(shí)不符,請(qǐng)點(diǎn)擊違法舉報(bào)進(jìn)行投訴反饋,一經(jīng)查實(shí),立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費(fèi)用

相關(guān)文章

  • Jtti:Ubuntu怎么限制指定端口和IP訪問(wèn)

    在 Ubuntu 系統(tǒng)中,可以使用防火墻規(guī)則來(lái)限制特定的端口和IP訪問(wèn)。常用的防火墻管理工具是 iptables,以下是使用 iptables 來(lái)限制指定端口和IP訪問(wèn)的步驟: 安裝 iptables: 如果系統(tǒng)中沒(méi)有安裝 iptables,可以使用以下命令進(jìn)行安裝: sudo apt-get update sudo apt-get install iptables 添加規(guī)則

    2024年02月12日
    瀏覽(20)
  • Oracle11gR2限制指定IP訪問(wèn)

    Oracle數(shù)據(jù)庫(kù)版本: Oracle11gR2 安裝位置: E:appproduct 編輯文件:E:appproduct11.2.0dbhome_1NETWORKADMINsqlnet.ora 配置說(shuō)明 配置后,如果非允許的主機(jī)IP連接數(shù)據(jù)庫(kù)時(shí),會(huì)提示 ORA-12537: TNS:lost contact 或中文提示 ORA-12537: TNS:連接關(guān)閉 E:appproduct11.2.0dbhome_1NETWORKADMINtnsnames.ora 1. PL/SQL

    2024年01月16日
    瀏覽(23)
  • 如何用Nginx實(shí)現(xiàn)對(duì)城市以及指定IP的訪問(wèn)限制?

    如何用Nginx實(shí)現(xiàn)對(duì)城市以及指定IP的訪問(wèn)限制?

    在【如何用Nginx代理MySQL連接,并限制可訪問(wèn)IP】一文中,我們實(shí)現(xiàn)了通過(guò)Nginx代理MySQL連接,并限制了指定IP才能通過(guò)Nginx進(jìn)行連接,以提高數(shù)據(jù)安全性。 該場(chǎng)景適用于根據(jù)具體的IP地址來(lái)進(jìn)行訪問(wèn)限制,假如我們要上線一個(gè)新的功能,但是只想在某些地區(qū)進(jìn)行小規(guī)模的測(cè)試,

    2024年02月05日
    瀏覽(17)
  • windows服務(wù)器限制特定ip訪問(wèn)指定端口(服務(wù)器ip白名單)

    windows服務(wù)器限制特定ip訪問(wèn)指定端口(服務(wù)器ip白名單)

    有些時(shí)候我們需要限制特定的ip白名單來(lái)訪問(wèn)服務(wù)器的指定端口,來(lái)防止dos攻擊或其他危險(xiǎn)訪問(wèn),我們可以通過(guò)防火墻來(lái)實(shí)現(xiàn)這一需求,下面一起看一下: ps:開啟防火墻可能有些端口會(huì)無(wú)法訪問(wèn),比如80、443等,需要添加入棧規(guī)則才能恢復(fù),參考下面步驟的入站規(guī)則 新建入站

    2024年02月05日
    瀏覽(30)
  • Springboot接口添加IP白名單限制

    Springboot接口添加IP白名單限制

    實(shí)現(xiàn)流程: 自定義攔截器——注入攔截器——獲取請(qǐng)求IP——對(duì)比IP是否一致——請(qǐng)求返回 文章背景: 接口添加IP白名單限制,只有規(guī)定的IP可以訪問(wèn)項(xiàng)目。 實(shí)現(xiàn)思路: 添加攔截器,攔截項(xiàng)目所有的請(qǐng)求,獲取請(qǐng)求的網(wǎng)絡(luò)IP,查詢IP是否在白名單之中,白名單設(shè)置在數(shù)據(jù)庫(kù)中

    2024年02月04日
    瀏覽(21)
  • SpringBoot限制接口訪問(wèn)頻率 - 這些錯(cuò)誤千萬(wàn)不能犯

    最近在基于SpringBoot做一個(gè)面向普通用戶的系統(tǒng),為了保證系統(tǒng)的穩(wěn)定性,防止被惡意攻擊,我想控制用戶訪問(wèn)每個(gè)接口的頻率。為了實(shí)現(xiàn)這個(gè)功能,可以設(shè)計(jì)一個(gè)annotation,然后借助AOP在調(diào)用方法之前檢查當(dāng)前ip的訪問(wèn)頻率,如果超過(guò)設(shè)定頻率,直接返回錯(cuò)誤信息。 在開始介

    2024年02月05日
    瀏覽(17)
  • 只允許訪問(wèn)固定網(wǎng)址,如何讓電腦只能上指定的網(wǎng)站

    只允許訪問(wèn)固定網(wǎng)址,如何讓電腦只能上指定的網(wǎng)站

    在企業(yè)管理中,確保員工在工作時(shí)能夠?qū)W⒂谥付ǖ娜蝿?wù)和資源至關(guān)重要。為了實(shí)現(xiàn)這一目標(biāo),許多企業(yè)選擇限制員工電腦的訪問(wèn)權(quán)限,只允許他們?cè)L問(wèn)固定的網(wǎng)址或網(wǎng)站。 這種策略不僅有助于提高工作效率,還能減少因不當(dāng)上網(wǎng)行為帶來(lái)的安全風(fēng)險(xiǎn)。那么,企業(yè)該如何設(shè)置

    2024年02月19日
    瀏覽(21)
  • SpringBoot后端統(tǒng)計(jì)網(wǎng)站的IP訪問(wèn)次數(shù)及地區(qū)

    ? ? ? ? ?項(xiàng)目是用SpringBoot+Vue實(shí)現(xiàn),前后端分離的,前端是用nginx部署的,雖說(shuō)可以通過(guò)Nginx的日志來(lái)統(tǒng)計(jì)網(wǎng)站的IP的訪問(wèn)次數(shù),但想在前端用圖形化的方式來(lái)展示是不太可行的,所以我想著是在SpringBoot后端來(lái)實(shí)時(shí)統(tǒng)計(jì)訪問(wèn)的網(wǎng)站的IP及其次數(shù)和地區(qū),然后存儲(chǔ)在數(shù)據(jù)庫(kù)中,前

    2023年04月08日
    瀏覽(14)
  • 限制Linux指定用戶訪問(wèn)某個(gè)文件夾,禁止其訪問(wèn)指定文件夾

    限制Linux指定用戶訪問(wèn)某個(gè)文件夾,禁止其訪問(wèn)指定文件夾

    ? ? ?默認(rèn)情況下用戶本身就只能讀寫執(zhí)行自己目錄下自己創(chuàng)建的文件,自己主目錄以外的文件都沒(méi)有寫權(quán)限、執(zhí)行權(quán)限;自己主目錄以外的目錄,則只有r和x權(quán)限,沒(méi)有w權(quán)限,對(duì)于合法的ssh用戶,這樣的權(quán)限就已經(jīng)足夠了。 否則如果去該系統(tǒng)目錄和文件的權(quán)限,可能會(huì)引起

    2024年02月06日
    瀏覽(92)
  • springboot 項(xiàng)目啟動(dòng)后,localhost加端口可以訪問(wèn),但是外網(wǎng)IP不行

    springboot 項(xiàng)目啟動(dòng)后,localhost加端口可以訪問(wèn),但是外網(wǎng)IP不行

    現(xiàn)象 java springboot項(xiàng)目啟動(dòng)后,localhost(或127.0.0.1)加端口可以訪問(wèn),但是使用外網(wǎng)IP卻無(wú)法訪問(wèn)。 原因及解決方法 springboot 的配置文件(yml 或 properties) 中缺少 server.address 的設(shè)置。 解決方法: 在springboot 的配置文件中增加 server.address 的配置。yml 配置文件如下所示: server.ad

    2024年02月16日
    瀏覽(25)

覺(jué)得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請(qǐng)作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包