精品欧美一区二区三区在线观看 _久久久久国色av免费观看性色_国产精品久久在线观看_亚洲第一综合网站_91精品又粗又猛又爽_小泽玛利亚一区二区免费_91亚洲精品国偷拍自产在线观看 _久久精品视频在线播放_美女精品久久久_欧美日韩国产成人在线

在 SpringBoot3.3 中攔截修改請求 Body 的多種正確方式

開發 前端
經處理的用戶輸入可能會包含惡意的 HTML 或 JavaScript 代碼,攻擊者可以利用這些代碼在用戶瀏覽器中執行惡意腳本,導致跨站腳本攻擊(XSS)。

在現代Web應用中,安全性和數據完整性是至關重要的,尤其是在處理用戶提交的數據時。請求的Body部分通常包含了關鍵的數據,如用戶輸入的表單信息、JSON數據、XML數據等,這些數據在傳輸和處理過程中如果沒有經過適當的驗證和安全檢查,可能會導致嚴重的安全漏洞。

例如,未經處理的用戶輸入可能會包含惡意的 HTML 或 JavaScript 代碼,攻擊者可以利用這些代碼在用戶瀏覽器中執行惡意腳本,導致跨站腳本攻擊(XSS)。此外,數據的完整性和準確性也可能受到篡改,這可能會導致應用程序在處理過程中出現錯誤或異常。

為了應對這些挑戰,開發人員通常需要攔截并修改請求 Body 的內容,對其進行驗證、過濾和格式化,以確保其安全性和可靠性。在Spring Boot 框架中,攔截和修改請求 Body 的方式有多種,常見的包括使用過濾器(Filter)、攔截器(Interceptor)、自定義HttpMessageConverter,以及直接在Controller中處理。

本文將深入探討在 Spring Boot 中攔截和修改請求 Body 的多種正確方式,結合代碼示例對每種方式進行詳細講解,并特別強調如何通過格式化和內容安全性檢測來防止 XSS 攻擊,確保應用程序的安全性和數據的完整性。我們還將介紹如何在這些方法中集成內容安全策略,增強對 HTML 和 JavaScript 標簽的檢測和處理,以防止潛在的安全威脅。這些技術不僅適用于一般的 Web 應用開發,還對構建高安全性的企業級應用有著重要的指導意義。

運行效果:

圖片

若想獲取項目完整代碼以及其他文章的項目源碼,且在代碼編寫時遇到問題需要咨詢交流,歡迎加入下方的知識星球。

項目結構

我們將創建一個 Spring Boot 項目,其中包含以下文件和配置:

  • pom.xml:項目依賴配置
  • application.yml:項目屬性配置
  • 前端頁面:使用 Thymeleaf 模板引擎,結合 Bootstrap 進行樣式美化
  • 控制器、過濾器、中間件:實現攔截和修改請求 Body 的功能

項目依賴配置(pom.xml)

首先,在pom.xml文件中添加必要的依賴項。我們的項目需要以下依賴:

<?xml versinotallow="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
	<modelVersion>4.0.0</modelVersion>
	<parent>
		<groupId>org.springframework.boot</groupId>
		<artifactId>spring-boot-starter-parent</artifactId>
		<version>3.3.3</version>
		<relativePath/> <!-- lookup parent from repository -->
	</parent>
	<groupId>com.icoderoad</groupId>
	<artifactId>request-body</artifactId>
	<version>0.0.1-SNAPSHOT</version>
	<name>request-body</name>
	<description>Demo project for Spring Boot</description>
	
	<properties>
		<java.version>17</java.version>
	</properties>
	<dependencies>

		<!-- Spring Boot Starter Web -->
	    <dependency>
	        <groupId>org.springframework.boot</groupId>
	        <artifactId>spring-boot-starter-web</artifactId>
	    </dependency>
	
	    <!-- Thymeleaf -->
	    <dependency>
	        <groupId>org.springframework.boot</groupId>
	        <artifactId>spring-boot-starter-thymeleaf</artifactId>
	    </dependency>
		
		<!-- Apache Commons Text (for string escape operations) -->
	    <dependency>
	        <groupId>org.apache.commons</groupId>
	        <artifactId>commons-text</artifactId>
	        <version>1.9</version>
	    </dependency>
	

	    <!-- Lombok (optional for reducing boilerplate code) -->
	    <dependency>
	        <groupId>org.projectlombok</groupId>
	        <artifactId>lombok</artifactId>
	        <scope>provided</scope>
	    </dependency>

		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-test</artifactId>
			<scope>test</scope>
		</dependency>
	</dependencies>

	<build>
		<plugins>
			<plugin>
				<groupId>org.springframework.boot</groupId>
				<artifactId>spring-boot-maven-plugin</artifactId>
			</plugin>
		</plugins>
	</build>

</project>

項目配置(application.yml)

接下來,在application.yml文件中進行一些基本配置。通常,我們可以在這里配置服務器端口、日志級別等信息:

server:
  port: 8080

spring:
  thymeleaf:
    cache: false
    mode: HTML
    suffix: .html
    prefix: classpath:/templates/

前端頁面(Thymeleaf模板)

為了演示請求攔截和修改的效果,我們可以創建一個簡單的表單頁面index.html,用戶可以在此頁面上提交數據。

<!DOCTYPE html>
<html lang="zh">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>請求表單</title>
    <!-- 引入Bootstrap CSS -->
    <link  rel="stylesheet">
    <!-- 引入jQuery -->
    <script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
</head>
<body>
    <div class="container">
        <h2>提交請求表單</h2>
        <form id="requestForm">
            <div class="mb-3">
                <label for="inputData" class="form-label">輸入數據</label>
                <textarea class="form-control" id="inputData" rows="3" required></textarea>
            </div>
            <button type="submit" class="btn btn-primary">提交</button>
        </form>

        <!-- 提示信息 -->
        <div id="resultMessage" class="alert mt-3" role="alert" style="display:none;"></div>
    </div>

    <script>
        $(document).ready(function() {
            $("#requestForm").on("submit", function(event) {
                event.preventDefault(); // 阻止表單的默認提交行為

                // 獲取用戶輸入的數據
                var inputData = $("#inputData").val();

                // 使用 jQuery 發送 AJAX 請求
                $.ajax({
                    url: "/submit",
                    type: "POST",
                    contentType: "application/json",
                    data: JSON.stringify({data: inputData}),
                    success: function(response) {
                        // 成功后在頁面上顯示提示信息
                        $("#resultMessage").removeClass("alert-danger").addClass("alert-success")
                            .text("提交成功: " + response.message)
                            .show();
                    },
                    error: function(xhr, status, error) {
                        // 失敗時顯示錯誤信息
                        $("#resultMessage").removeClass("alert-success").addClass("alert-danger")
                            .text("提交失敗: " + xhr.responseText)
                            .show();
                    }
                });
            });
        });
    </script>
</body>
</html>

攔截和修改請求Body的實現方式

創建過濾器配置類

創建一個 FilterConfig 配置類,在該類中注冊 RequestBodyFilter 過濾器。

import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.Ordered;

@Configuration
public class FilterConfig {

    @Bean
    public FilterRegistrationBean<RequestBodyFilter> requestBodyFilterRegistration() {
        FilterRegistrationBean<RequestBodyFilter> registrationBean = new FilterRegistrationBean<>();

        // 將自定義過濾器注冊為Bean
        registrationBean.setFilter(new RequestBodyFilter());
        
        // 過濾器應用于所有URL
        registrationBean.addUrlPatterns("/*");
        
        // 設置過濾器的優先級
        registrationBean.setOrder(Ordered.HIGHEST_PRECEDENCE);

        return registrationBean;
    }
}
使用過濾器(Filter)攔截請求Body

過濾器是一種常見的攔截HTTP請求的方式。我們可以通過實現jakarta.servlet.Filter接口來攔截請求并修改請求體。

package com.icoderoad.request_body.filter;

import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.nio.charset.StandardCharsets;

import org.apache.commons.text.StringEscapeUtils;
import org.springframework.stereotype.Component;

import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;

import jakarta.servlet.Filter;
import jakarta.servlet.FilterChain;
import jakarta.servlet.FilterConfig;
import jakarta.servlet.ServletException;
import jakarta.servlet.ServletInputStream;
import jakarta.servlet.ServletRequest;
import jakarta.servlet.ServletResponse;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletRequestWrapper;
import jakarta.servlet.http.HttpServletResponse;

@Component
public class RequestBodyFilter implements Filter {

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
        if (request instanceof HttpServletRequest && response instanceof HttpServletResponse) {
            HttpServletRequest httpRequest = (HttpServletRequest) request;

            // 使用自定義 HttpServletRequestWrapper 包裝請求
            CustomHttpServletRequestWrapper wrappedRequest = new CustomHttpServletRequestWrapper(httpRequest);

            // 確保請求體內容被讀取并緩存
            String originalBody = wrappedRequest.getBody();

            // 確認請求體內容
            System.out.println("Original Request Body: " + originalBody);

            // 對內容進行安全性處理:轉義HTML和JavaScript標簽
            String sanitizedBody = sanitizeBody(originalBody);

            // 將處理后的內容作為新的輸入流返回
            ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(sanitizedBody.getBytes(StandardCharsets.UTF_8));
            HttpServletRequest sanitizedRequest = new CustomHttpServletRequestWrapper(wrappedRequest) {
                @Override
                public ServletInputStream getInputStream() throws IOException {
                    return new CustomServletInputStream(byteArrayInputStream);
                }
            };

            // 繼續過濾鏈
            chain.doFilter(sanitizedRequest, response);
        } else {
            chain.doFilter(request, response);
        }
    }

    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        // 初始化Filter所需資源
    }

    @Override
    public void destroy() {
        // 釋放Filter所占用的資源
    }

    // 用于安全處理請求體內容
    private String sanitizeBody(String originalBody) {
        String sanitizedBody = StringEscapeUtils.escapeHtml4(originalBody);
        sanitizedBody = sanitizedBody.replaceAll("(?i)<script", "<script")
                                     .replaceAll("(?i)</script", "</script");
        
        ObjectMapper objectMapper = new ObjectMapper();
        try {
            JsonNode jsonNode = objectMapper.readTree(originalBody);
            // 對 JSON 數據進行處理(比如移除不必要的字段)
            return objectMapper.writeValueAsString(jsonNode);
        } catch (IOException e) {
            e.printStackTrace();
            // 處理 JSON 解析異常
            return sanitizedBody;
        }
    }

    // 自定義ServletInputStream類,簡化流操作
    private static class CustomServletInputStream extends ServletInputStream {
        private final ByteArrayInputStream inputStream;

        public CustomServletInputStream(ByteArrayInputStream inputStream) {
            this.inputStream = inputStream;
        }

        @Override
        public int read() throws IOException {
            return inputStream.read();
        }

        @Override
        public boolean isFinished() {
            return inputStream.available() == 0;
        }

        @Override
        public boolean isReady() {
            return true;
        }

        @Override
        public void setReadListener(jakarta.servlet.ReadListener readListener) {
            // 讀取監聽器設置,當前未實現
        }
    }

    // 自定義 HttpServletRequestWrapper 類
    private static class CustomHttpServletRequestWrapper extends HttpServletRequestWrapper {
        private final byte[] body;

        public CustomHttpServletRequestWrapper(HttpServletRequest request) throws IOException {
            super(request);
            // 讀取請求體內容并緩存
            InputStream inputStream = request.getInputStream();
            body = inputStream.readAllBytes();
        }

        @Override
        public ServletInputStream getInputStream() throws IOException {
            return new CustomServletInputStream(new ByteArrayInputStream(body));
        }

        public String getBody() {
            return new String(body, StandardCharsets.UTF_8);
        }
    }
}
使用Spring Interceptor攔截請求Body

Spring的攔截器(Interceptor)是另一種攔截HTTP請求的方式。它比過濾器更接近Spring的處理機制。

package com.icoderoad.request_body.interceptor;

import java.io.BufferedReader;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.nio.charset.StandardCharsets;

import org.apache.commons.text.StringEscapeUtils;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.util.ContentCachingRequestWrapper;

import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;

import jakarta.servlet.ReadListener;
import jakarta.servlet.ServletInputStream;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletRequestWrapper;
import jakarta.servlet.http.HttpServletResponse;

public class RequestBodyInterceptor implements HandlerInterceptor {

    private static final ObjectMapper objectMapper = new ObjectMapper();

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws IOException {
        // 使用 ContentCachingRequestWrapper 包裝 HttpServletRequest
        ContentCachingRequestWrapper cachingRequest = new ContentCachingRequestWrapper(request);

        // 讀取請求體內容
        String originalBody = readRequestBody(cachingRequest);
        if (originalBody == null || originalBody.isEmpty()) {
            return true; // 如果沒有請求體,直接返回
        }

        System.out.println("Original Request Body: " + originalBody);

        // 處理請求體內容
        String sanitizedBody = sanitizeBody(originalBody);

        // 使用自定義 HttpServletRequestWrapper 包裝請求
        HttpServletRequest wrappedRequest = new CustomHttpServletRequestWrapper(cachingRequest, sanitizedBody);

        // 替換請求對象
        request.setAttribute("wrappedRequest", wrappedRequest);

        return true;
    }

    private String readRequestBody(HttpServletRequest request) throws IOException {
        ContentCachingRequestWrapper wrapper = (ContentCachingRequestWrapper) request;
        byte[] buf = wrapper.getContentAsByteArray();
        if (buf.length > 0) {
            return new String(buf, 0, buf.length, wrapper.getCharacterEncoding());
        }
        return null;
    }

    private String sanitizeBody(String originalBody) {
        // 如果請求體是 JSON 格式,則對其進行特殊處理
        if (isJson(originalBody)) {
            try {
                JsonNode jsonNode = objectMapper.readTree(originalBody);
                // 對 JSON 數據進行處理(比如移除不必要的字段)
                return objectMapper.writeValueAsString(jsonNode);
            } catch (IOException e) {
                // 捕獲 JSON 解析異常,記錄錯誤并返回原始內容
                e.printStackTrace();
                return originalBody; // 返回原始內容
            }
        } else {
            // 對內容進行安全性處理:轉義HTML和JavaScript標簽
            String sanitizedBody = StringEscapeUtils.escapeHtml4(originalBody);
            sanitizedBody = sanitizedBody.replaceAll("(?i)<script", "<script")
                                         .replaceAll("(?i)</script", "</script>");
            return sanitizedBody;
        }
    }

    private boolean isJson(String content) {
        // 簡單檢查內容是否是 JSON 格式
        return content.trim().startsWith("{") || content.trim().startsWith("[");
    }

    private static class CustomHttpServletRequestWrapper extends HttpServletRequestWrapper {
        private final ByteArrayInputStream inputStream;

        public CustomHttpServletRequestWrapper(HttpServletRequest request, String body) {
            super(request);
            this.inputStream = new ByteArrayInputStream(body.getBytes(StandardCharsets.UTF_8));
        }

        @Override
        public ServletInputStream getInputStream() throws IOException {
            return new CustomServletInputStream(inputStream);
        }

        @Override
        public BufferedReader getReader() throws IOException {
            return new BufferedReader(new InputStreamReader(getInputStream(), StandardCharsets.UTF_8));
        }
    }

    private static class CustomServletInputStream extends ServletInputStream {
        private final ByteArrayInputStream inputStream;

        public CustomServletInputStream(ByteArrayInputStream inputStream) {
            this.inputStream = inputStream;
        }

        @Override
        public int read() throws IOException {
            return inputStream.read();
        }

        @Override
        public boolean isFinished() {
            return inputStream.available() == 0;
        }

        @Override
        public boolean isReady() {
            return true;
        }

        @Override
        public void setReadListener(ReadListener readListener) {
            // 讀取監聽器設置,當前未實現
        }
    }
}

創建配置類來注冊攔截器

在你的 Spring Boot 項目中創建一個配置類,配置 RequestBodyInterceptor:

package com.icoderoad.request_body.config;

import java.util.List;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.converter.AbstractHttpMessageConverter;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.icoderoad.request_body.converter.CustomHttpMessageConverter;
import com.icoderoad.request_body.interceptor.RequestBodyInterceptor;

@Configuration
public class WebConfig implements WebMvcConfigurer {

    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(new RequestBodyInterceptor());
    }
    
    @Bean
    public CustomHttpMessageConverter customHttpMessageConverter(ObjectMapper objectMapper) {
        return new CustomHttpMessageConverter(objectMapper);
    }

    @Override
    public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
        // 移除默認的 Jackson 2 HttpMessageConverter
        converters.removeIf(converter -> converter instanceof AbstractHttpMessageConverter);
        // 添加自定義的 HttpMessageConverter
        converters.add(customHttpMessageConverter(new ObjectMapper()));
    }
}
使用自定義HttpMessageConverter

Spring提供了HttpMessageConverter來處理請求體的轉換。我們可以自定義一個HttpMessageConverter來攔截和修改請求體。

package com.icoderoad.request_body.converter;

import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.apache.commons.text.StringEscapeUtils;
import org.springframework.http.HttpInputMessage;
import org.springframework.http.HttpOutputMessage;
import org.springframework.http.MediaType;
import org.springframework.http.converter.AbstractHttpMessageConverter;

import java.io.IOException;
import java.nio.charset.StandardCharsets;

public class CustomHttpMessageConverter extends AbstractHttpMessageConverter<Object> {

    private final ObjectMapper objectMapper;

    public CustomHttpMessageConverter(ObjectMapper objectMapper) {
        super(MediaType.APPLICATION_JSON);
        this.objectMapper = objectMapper;
    }

    @Override
    protected boolean supports(Class<?> clazz) {
        return true; // 支持所有類
    }

    @Override
    protected Object readInternal(Class<? extends Object> clazz, HttpInputMessage inputMessage) throws IOException {
        String body = new String(inputMessage.getBody().readAllBytes(), StandardCharsets.UTF_8);

        // 處理請求體內容
        String sanitizedBody = sanitizeBody(body);

        // 將處理后的內容轉換為對象
        return objectMapper.readValue(sanitizedBody, clazz);
    }

    @Override
    protected void writeInternal(Object object, HttpOutputMessage outputMessage) throws IOException {
        // 將對象轉換為 JSON 字符串
        String json = objectMapper.writeValueAsString(object);

        // 輸出處理后的 JSON 字符串
        outputMessage.getBody().write(json.getBytes(StandardCharsets.UTF_8));
    }

    private String sanitizeBody(String originalBody) {
        // 如果請求體是 JSON 格式,則對其進行特殊處理
        if (originalBody.trim().startsWith("{") || originalBody.trim().startsWith("[")) {
            try {
                JsonNode jsonNode = objectMapper.readTree(originalBody);
                // 對 JSON 數據進行處理(比如移除不必要的字段)
                return objectMapper.writeValueAsString(jsonNode);
            } catch (IOException e) {
                // 捕獲 JSON 解析異常,記錄錯誤并返回原始內容
                e.printStackTrace();
                return originalBody; // 返回原始內容
            }
        } else {
            // 對內容進行安全性處理:轉義HTML和JavaScript標簽
            String sanitizedBody = StringEscapeUtils.escapeHtml4(originalBody);
            sanitizedBody = sanitizedBody.replaceAll("(?i)<script", "<script")
                                         .replaceAll("(?i)</script", "</script>");
            return sanitizedBody;
        }
    }
}
在Controller中直接修改請求Body

最后一種方式是在Controller中直接讀取并修改請求體。

package com.icoderoad.request_body.controller;

import java.util.HashMap;
import java.util.Map;

import org.apache.commons.text.StringEscapeUtils;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class RequestController {

    @PostMapping("/submit")
    public ResponseEntity<Map<String, String>> submit(@RequestBody Map<String, String> requestData) {
        String data = requestData.get("data");
        
        String sanitizedBody = StringEscapeUtils.escapeHtml4(data);
        sanitizedBody = sanitizedBody.replaceAll("(?i)<script", "<script")
                                     .replaceAll("(?i)</script", "</script");

        
        // 在此處理接收到的數據(例如存儲、驗證等)
        // 這里我們假設處理成功并返回一條消息

        Map<String, String> response = new HashMap<>();
        response.put("message", "接收到的數據: " + sanitizedBody);

        // 返回200 OK響應和響應消息
        return ResponseEntity.ok(response);
    }
}

總結

以上介紹了在 Spring Boot3.3 中攔截和修改請求 Body 的多種方式,包括使用過濾器、攔截器、HttpMessageConverter 以及在控制器中直接修改請求體。每種方式都有其適用場景,可以根據實際需求選擇合適的方式。希望本文對大家在實際開發中有所幫助。

責任編輯:武曉燕 來源: 路條編程
相關推薦

2024-09-04 11:16:44

端口Spring配置類

2024-08-30 11:28:09

2024-09-06 10:05:47

SpELSpring權限

2024-09-03 10:44:32

2020-03-25 17:55:30

SpringBoot攔截器Java

2011-02-23 10:35:04

Konqueror

2024-08-02 08:21:52

Spring項目方式

2012-08-13 10:23:33

IBMdW

2025-05-09 08:20:50

2024-09-05 09:35:58

CGLIBSpring動態代理

2023-03-10 22:14:49

KustomizeKubernetes

2024-09-26 09:28:06

內存Spring

2024-09-09 11:35:35

2024-10-15 10:38:32

2024-09-29 10:39:48

RSocketWebSocket通信

2018-09-17 08:31:08

容器Docker雪球

2024-04-09 08:04:42

C#結構await

2018-06-19 08:12:25

2024-09-13 10:21:50

2024-10-07 08:18:05

SpringBOM管理
點贊
收藏

51CTO技術棧公眾號

午夜av不卡| 国产www免费观看| 色先锋久久影院av| 欧美日韩国产在线播放| 九色一区二区| 国产一级在线播放| 色先锋久久影院av| 欧美最新大片在线看| 亚洲日本精品国产第一区| 一区二区www| 中文字幕一区二区三区欧美日韩 | 91破解版在线观看| 91婷婷韩国欧美一区二区| 亚洲欧美另类人妖| 亚洲作爱视频| 欧美一区免费看| 亚洲 欧美 激情 小说 另类| 久久精品人人做人人爽电影蜜月| 国产午夜精品一区二区三区| 亚洲熟女乱色一区二区三区| 成人综合影院| 国产高清不卡一区| 国产91色在线|| 日本污视频网站| 一区二区在线免费播放| 色综合天天做天天爱| 潘金莲一级淫片aaaaa免费看| 欧美熟妇另类久久久久久不卡| 久久综合图片| 欧美激情一区二区三级高清视频| 9.1在线观看免费| 粉嫩av一区二区三区四区五区 | 亚洲精品一区在线观看香蕉| 精品久久久久久中文字幕2017| a级在线观看| 久久一区二区视频| 亚洲一区中文字幕在线观看| 国产99久久久| 亚洲国产裸拍裸体视频在线观看乱了中文 | 久久久久福利视频| 二区三区在线播放| k8久久久一区二区三区| 91美女福利视频高清| av图片在线观看| 国产精品vip| 日韩中文字幕在线| 欧美 日韩 成人| 国产一区二区三区亚洲| 欧美一区二区在线免费播放| 99久久国产宗和精品1上映| 色操视频在线| 亚洲欧美精品午睡沙发| 亚洲欧美日韩不卡一区二区三区| 姝姝窝人体www聚色窝| 国产一区二区三区四区五区入口 | 亚洲一区中文字幕在线观看| 一区二区小视频| 久久亚洲一区| 国产91|九色| 日韩精品一卡二卡| 欧美午夜视频| 色综合导航网站| 欧洲美女女同性互添| 成人免费av| 国产亚洲精品久久久久久| 久久久久国产精品区片区无码| 2021年精品国产福利在线| 欧美日韩黄色一区二区| 久久黄色免费看| 伊人久久精品一区二区三区| 性久久久久久久| www.av片| 中文字幕一区久| 亚洲第一搞黄网站| 国产精品久久中文字幕| 国产福利电影在线播放| 精品动漫一区二区三区| 五月丁香综合缴情六月小说| av2020不卡| 亚洲成人av资源| www.av毛片| 无遮挡爽大片在线观看视频 | 久久电影tv| 色狠狠桃花综合| 手机在线免费观看毛片| 欧美国产视频| 欧美一级理论性理论a| 国内av免费观看| 欧美高清你懂的| 日韩欧美久久久| 人妻 日韩 欧美 综合 制服| 51亚洲精品| 精品福利一区二区三区免费视频| 日韩av手机在线播放| 日本在线中文字幕一区| 亚洲色图av在线| 美女三级黄色片| 欧美成人午夜| 欧美一级电影免费在线观看| 国产一区免费看| 麻豆国产精品一区二区三区| 亚洲va国产va天堂va久久| 精品人妻一区二区三区四区不卡| 成人午夜av电影| 日韩高清av| 国产中文字幕在线观看| 亚洲图片你懂的| 免费一级淫片aaa片毛片a级| 都市激情亚洲一区| 3d成人h动漫网站入口| 国模无码视频一区| 久久在线电影| 欧美第一页在线| 日韩免费观看一区二区| 蜜臀久久99精品久久久久久9| 97久久天天综合色天天综合色hd| 日韩av资源| 中文字幕视频一区二区三区久| 99热久久这里只有精品| 欧美成人精品三级网站| 欧美一级免费大片| 国产艳妇疯狂做爰视频| 第九色区aⅴ天堂久久香| 欧美激情视频一区二区| 国产偷人爽久久久久久老妇app| 国产一区二区不卡在线| 欧美精品一区二区三区久久| a级影片在线| 色综合网色综合| 蜜臀aⅴ国产精品久久久国产老师| 午夜精品福利影院| 欧美另类69精品久久久久9999| 日日噜噜噜噜人人爽亚洲精品| 国产酒店精品激情| 日本在线视频不卡| 黄色激情在线播放| 日韩一区二区影院| 性少妇xx生活| 激情婷婷久久| 91久久综合亚洲鲁鲁五月天| 成人在线视频成人| 欧美日韩中文字幕| 亚洲最大视频网| 99国内精品久久久久久久| 欧美一区二区影院| 人妻少妇精品无码专区久久| 亚洲免费色视频| 久久精品.com| 国产精品xxx在线观看| 欧美老妇交乱视频| 91亚洲国产成人精品一区| 久久久91精品国产一区二区精品| 丰满的少妇愉情hd高清果冻传媒 | 国产69精品久久久久9| 国产免费一区二区三区最新不卡| 国产日产欧产精品推荐色 | 黄av在线播放| 欧美一a一片一级一片| 精品人妻一区二区三区日产乱码卜| 天堂网在线观看国产精品| 国产精品视频地址| freemovies性欧美| 欧美日精品一区视频| 鲁丝一区二区三区| 日韩精品欧美精品| 品久久久久久久久久96高清| 你懂得影院夜精品a| 国产婷婷色综合av蜜臀av| 国产精品6666| 99九九99九九九视频精品| 欧美美女黄色网| 日韩中文字幕| 欧美国产日韩免费| 亚洲女同志亚洲女同女播放| 亚洲日本中文字幕区| 国产91色在线观看| 国产真实有声精品录音| 国产精品狼人色视频一区| 97在线观看免费观看高清| 欧美性猛交xxxxxx富婆| 国产一区二区三区四区在线| 免费看日韩精品| 成人手机视频在线| 亚洲我射av| 欧美片一区二区三区| 偷拍25位美女撒尿视频在线观看| 色噜噜狠狠色综合欧洲selulu| 日本美女黄色一级片| 粉嫩蜜臀av国产精品网站| 777米奇影视第四色| 99久久久久久中文字幕一区| 黑人另类av| 日韩黄色碟片| 2019日本中文字幕| а√天堂在线官网| 亚洲欧美日韩精品久久亚洲区 | 永久久久久久| 日韩动漫一区| 91色精品视频在线| 欧美日韩国产v| 欧美大片免费看| 97电影在线观看| 日韩精品视频观看| 国产精品永久久久久久久久久| 天天色 色综合| 精品自拍偷拍视频| 久久综合精品国产一区二区三区 | 中文天堂在线视频| 午夜精品福利一区二区三区蜜桃| 久草福利资源在线| 久久蜜桃av一区二区天堂| 精品人妻一区二区乱码| 日本欧美一区二区在线观看| 免费在线观看亚洲视频| 亚洲五月综合| 亚洲不卡中文字幕| jazzjazz国产精品久久| 91免费电影网站| 97人人做人人爽香蕉精品| 欧美一区二区.| 丁香高清在线观看完整电影视频 | 性国裸体高清亚洲| 欧美激情精品久久久| 欧美边添边摸边做边爱免费| 日韩精品高清视频| 免费国产精品视频| 日韩一级免费观看| 国产免费福利视频| 欧美日韩大陆在线| 国产情侣呻吟对白高潮| 日韩欧美极品在线观看| 亚洲视频免费播放| 亚洲国产视频网站| 久久精品久久国产| 一区二区三区色| 国产精品白嫩白嫩大学美女| **性色生活片久久毛片| 午夜激情视频在线播放| 国产精品国产三级国产aⅴ无密码 国产精品国产三级国产aⅴ原创 | 丁香婷婷综合激情五月色| 亚洲热在线视频| 国产一区二区在线看| 日韩在线一区视频| 精品在线一区二区| 欧美日韩久久婷婷| 国产一二精品视频| 波多野吉衣在线视频| 国产伦精品一区二区三区免费 | 久久亚洲一区二区三区四区五区高| 成年人视频网站在线| 亚洲最大在线视频| 国产日韩欧美久久| 日本少妇一区二区三区| www.51av欧美视频| 欧美激情videos| 2019中文字幕在线电影免费 | 国产原创一区二区三区| 亚洲午夜精品一区| 国产一区二区网址| 香蕉久久久久久av成人| 97久久精品人人澡人人爽| 国产精品一区二区入口九绯色| 91久色porny| 日本性高潮视频| 国产精品久久久久久久久久久免费看| 日本美女黄色一级片| 一区二区成人在线| 国产女同在线观看| 欧洲精品中文字幕| 国产伦子伦对白视频| 精品国产3级a| 国产精品二线| 插插插亚洲综合网| 国产夫妻在线播放| 国产精品日韩在线一区| 久久wwww| 精品久久久久久中文字幕动漫 | 欧美一级欧美一级| 性欧美videos另类喷潮| 亚洲一级免费观看| 国产精品亚洲综合一区在线观看| fc2成人免费视频| 国产精品无人区| 国产亚洲精品久久久久久无几年桃 | 成人黄色在线网站| 麻豆精品免费视频| 一区二区中文视频| 欧美成人aaaaⅴ片在线看| 欧美性xxxxx极品少妇| 国内精品偷拍视频| 日韩国产中文字幕| 日本免费在线视频| 992tv成人免费视频| 四虎影视成人精品国库在线观看| 99久久久久国产精品免费| 精品久久久中文字幕| 免费的一级黄色片| 日本特黄久久久高潮| 中文成人无字幕乱码精品区| 国产精品天美传媒| av黄色在线播放| 欧美岛国在线观看| 春暖花开成人亚洲区| 性视频1819p久久| 久久久久毛片免费观看| 日本10禁啪啪无遮挡免费一区二区 | 精品久久在线| 精品国产乱码久久久久久丨区2区| 91嫩草亚洲精品| 成人午夜视频免费在线观看| 国产精品18久久久久久久网站| 亚洲无人区码一码二码三码的含义| 亚洲成人av电影| 99热在线只有精品| 中文字幕在线看视频国产欧美在线看完整 | 日本新janpanese乱熟| 成人看片黄a免费看在线| 四虎精品免费视频| 欧美色图天堂网| 欧美色图另类| 高清一区二区三区四区五区| 久久影院一区二区三区| 亚洲午夜激情| 日韩成人精品视频| 中文字幕在线观看网址| 午夜国产精品影院在线观看| 成人福利小视频| 欧美成aaa人片免费看| 国产精品99精品一区二区三区∴| 欧美日韩精品免费观看视一区二区| 黄色精品网站| 亚洲乱妇老熟女爽到高潮的片| 亚洲欧美日韩中文播放| 91影院在线播放| 日韩在线视频网站| 亚洲高清国产拍精品26u| 午夜午夜精品一区二区三区文| 久久婷婷麻豆| 少妇精品无码一区二区免费视频| 色婷婷av一区| h视频在线观看免费| 国产精品福利在线观看| 青青草91久久久久久久久| 密臀av一区二区三区| 国产日韩精品视频一区| 色婷婷久久综合中文久久蜜桃av| 国产亚洲一区二区在线| 日韩免费电影| 亚洲mv在线看| 国内精品免费**视频| 中文字幕另类日韩欧美亚洲嫩草| 日韩一区二区在线播放| 不卡av免费观看| 久久av二区| 久久字幕精品一区| 九一在线免费观看| 欧美一区二区三区播放老司机| 2024最新电影在线免费观看| 91视频99| 亚洲黄色在线| 51妺嘿嘿午夜福利| 欧美日韩在线播| 精品孕妇一区二区三区| 成人欧美一区二区三区黑人| 欧美成人69| a级在线观看视频| 在线观看亚洲一区| a视频在线免费看| 精品视频导航| 蜜桃精品在线观看| 欧美精品xxxxx| 亚洲精品一区中文| 日本欧美在线| 97中文字幕在线| 91视频www| 亚洲一级黄色大片| 国内免费精品永久在线视频| 自拍偷拍欧美一区| 色综合五月婷婷| 亚洲激情五月婷婷| 你懂的好爽在线观看| 成人免费网站在线观看| aa国产精品| 99热这里只有精品4| 亚洲成人激情在线| 亚洲成人激情社区| 欧美日韩激情四射| 久久久久久久综合日本| 国产人妖一区二区三区| 海角国产乱辈乱精品视频| 精品国产一区二区三区噜噜噜 | 26uuu亚洲婷婷狠狠天堂| 亚洲天堂国产精品| 午夜精品福利视频| 国产精品久久久久久麻豆一区软件 | 国产中文字幕乱人伦在线观看| 国产亚洲精品精华液| 精品久久久久中文慕人妻| 国产成人精品电影久久久| 国产一区观看|