国产精品电影_久久视频免费_欧美日韩国产激情_成年人视频免费在线播放_日本久久亚洲电影_久久都是精品_66av99_九色精品美女在线_蜜臀a∨国产成人精品_冲田杏梨av在线_欧美精品在线一区二区三区_麻豆mv在线看

在 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-09 11:35:35

2024-10-15 10:38:32

2024-09-26 09:28:06

內存Spring

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在线| 亚洲宅男天堂在线观看无病毒| 亚洲国产精品影视| 亚洲三级国产| av一区二区三区在线观看| 亚洲成人偷拍| 在线亚洲国产精品网| 日韩免费影院| 欧美日韩国产综合久久| 中文字幕视频在线免费| 一区二区三区四区国产精品| 最近中文字幕2019第二页视频| 久久免费视频色| 久久久一本二本三本| 成人一区二区三区视频在线观看| 欧美一区二区在线| 亚洲一区久久| 一级特黄录像免费播放全99| 羞羞视频在线观看欧美| 久久久精品动漫| 久久国产精品久久久久久电车| 欧美裸体网站| 黄色日韩网站视频| av日韩在线看| 国产性色一区二区| 色播五月综合网| 亚洲精品久久久蜜桃| 日本wwwwwwwzzzzz视频| 亚洲国产综合人成综合网站| 玖玖在线免费视频| 精品久久久一区| 久草在线青青草| 欧美性感一类影片在线播放| 中文日本在线观看| 日韩欧美国产一区二区三区| 爱搞国产精品| 日韩在线观看免费全| 日韩高清在线| 欧美精品久久久久久久久久| 欧美激情15p| 国产欧美日韩综合精品| 黄色成人91| 蜜臀av.com| 国产精品久久久久久久浪潮网站| 手机福利视频欧美| 欧美日本在线视频| 欧美日韩亚洲国产| 国产91亚洲精品| 激情亚洲成人| 蜜桃传媒一区二区三区| 亚洲精品伦理在线| 在线观看h片| 中文字幕视频一区二区在线有码| 国产精品国产| av在线不卡观看| 精品写真视频在线观看| 成人www视频网站免费观看| 一本色道久久加勒比精品| 91超碰在线| 97在线视频免费播放| 一区二区激情| 欧美日韩国产精品激情在线播放| 亚洲精品国产一区二区三区四区在线| 中文日本在线观看| 欧美日韩成人在线观看| 亚洲人www| 99免费视频观看| 欧美视频日韩视频| 亚洲18在线| 加勒比在线一区二区三区观看| 国产伦精一区二区三区| 国产午夜在线| 日韩精品中文字幕有码专区| 国产精品免费大片| 伊人狠狠色丁香综合尤物| 国产精品国产成人国产三级| 欧美jizz18性欧美| 国内精品久久影院| 一本色道久久综合亚洲精品高清| 日韩精品―中文字幕| 91豆麻精品91久久久久久| 国产福利亚洲| 精品欧美一区二区在线观看视频 | 日韩精品在线免费播放| 国产成人三级| 日韩视频免费播放| 欧美日韩精品二区第二页| 日韩精品久久久久久久软件91| 国产精品久久久久免费| 国产精品无遮挡| 麻豆mv在线观看| 91在线网站视频| 国产人成一区二区三区影院| 国产免费拔擦拔擦8x高清在线人| 91网站在线免费观看| 国产欧美日韩三级| 中文字幕乱码中文乱码51精品| 粉嫩av一区二区三区免费观看| 国产精品久久免费看| 日韩高清成人| 日韩区国产区| 91黄视频在线| 欧美天天综合| 成人观看网站a| www.色综合| 国产成人在线色| 日本高清在线观看| av电影成人| 亚洲成在人线免费| 婷婷成人综合| 成人免费性视频| 日韩一级片网站| 狠狠爱综合网| 免费看男男www网站入口在线| 91精品国产91久久久久| 成人免费va视频| 1区2区在线| 日韩久久不卡| 欧美成人一区二区三区| 亚洲精品麻豆| 91ph在线| 欧美一区观看| 日韩欧美国产三级电影视频| 亚洲专区一区| 视频在线观看入口黄最新永久免费国产| 国产美女99p| 欧美三级电影在线看| 在线一区电影| 成人动漫在线免费观看| 91精品国产高清久久久久久91裸体| 午夜精品福利一区二区三区av| 欧美精选视频在线观看| 91短视频在线| 91在线短视频| 欧美一区二视频| 久久97超碰国产精品超碰| 国产在线精彩视频| 国产91在线亚洲| 国产亚洲一级高清| 久久只精品国产| 日韩欧美在线精品| 亚州色图欧美色图| 久久99精品久久久久久久青青日本| 日韩免费一区二区| 国产综合色视频| 日韩影片在线观看| 在线免费看黄av| 久久久久天天天天| 亚洲美女性视频| 国产精品私房写真福利视频| av永久不卡| 一区二区三区伦理| 国产精品免费看久久久无码| 欧美激情乱人伦| 色哟哟亚洲精品| 精品一区二区免费| 久久综合给合| 亚洲第一区视频| 日韩在线电影一区| 一区二区三区四区视频| 久久综合久久综合久久| 亚洲素人在线| 国产黄色在线| av在线观看地址| 日韩免费观看av| 欧美午夜女人视频在线| 欧美日韩专区| 欧美日韩国产网站| 精品欧美一区二区在线观看视频| 91精品国产综合久久精品图片 | 在线免费观看黄色av| 国产一区二区在线网站| 亚洲精品国产免费| aaa国产一区| 天天做天天爱天天爽综合网| 国产区在线观看| 日本三级中文字幕在线观看| 欧美性视频网站| 欧美综合视频在线观看| 国产精一区二区三区| 视频在线亚洲| 成人jjav| 国产人妻人伦精品| 91精品久久久久久久久久另类| 91精品办公室少妇高潮对白| 男女性色大片免费观看一区二区| 国产伦乱精品| 国产黄色片在线观看| 任你操这里只有精品| 国产精品自产拍在线观| 永久555www成人免费| 亚洲欧美在线另类| 肉色丝袜一区二区| 亚洲资源网你懂的| 老司机免费在线视频| 少妇高潮喷水在线观看| 国产精品日韩在线| 亚洲白虎美女被爆操|