成人在线亚洲_国产日韩视频一区二区三区_久久久国产精品_99国内精品久久久久久久

您的位置:首頁(yè)技術(shù)文章
文章詳情頁(yè)

Spring Security OAuth2 授權(quán)碼模式的實(shí)現(xiàn)

瀏覽:151日期:2023-08-20 15:46:13

寫在前邊

在文章OAuth 2.0 概念及授權(quán)流程梳理 中我們談到OAuth 2.0的概念與流程,這里我準(zhǔn)備分別記一記這幾種授權(quán)模式的demo,一方面為自己的最近的學(xué)習(xí)做個(gè)總結(jié),另一方面做下知識(shí)輸出,如果文中有錯(cuò)誤的地方,請(qǐng)?jiān)u論指正,在此不勝感激

受眾前提

閱讀本文,默認(rèn)讀者已經(jīng)過(guò)Spring Security有一定的了解,對(duì)OAuth2流程有一定了解

本文目標(biāo)

帶領(lǐng)讀者對(duì)Spring Security OAuth2框架的授權(quán)碼模式有一個(gè)比較直觀的概念,能使用框架搭建授權(quán)碼模式授權(quán)服務(wù)器與資源服務(wù)器(分離版本)

授權(quán)碼模式流程回顧

授權(quán)碼模式要求:用戶登錄并對(duì)第三方應(yīng)用(客戶端)進(jìn)行授權(quán),出示授權(quán)碼交給客戶端,客戶端憑授權(quán)碼換取access_token(訪問(wèn)憑證)

此模式要求授權(quán)服務(wù)器與用戶直接交互,在此過(guò)程中,第三方應(yīng)用是無(wú)法獲取到用戶輸入的密碼等信息的,這個(gè)模式也是OAuth 2.0中最安全的一個(gè)

Demo基本結(jié)構(gòu)

Spring Security OAuth2 授權(quán)碼模式的實(shí)現(xiàn)

這里主要關(guān)注authorization-code-authorization-server與authorization-code-resource-server這兩個(gè)模塊

本文以及后續(xù)文章的demo均放在GitHub上,歡迎大家Star & Fork,源碼地址:https://github.com/hellxz/spring-security-oauth2-learn

authorization-code-client-resttemplate-jdbc這個(gè)項(xiàng)目是用來(lái)測(cè)試非OAuth2服務(wù)使用RestTemplate與JdbcTemplate對(duì)接OAuth2授權(quán)服務(wù)的,流程這里不講,有興趣可以debug看看,可能會(huì)讓您對(duì)整個(gè)流程會(huì)有更清晰的感受

Maven依賴

<!--Spring Security--> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-security</artifactId> </dependency> <!--Spring Boot Starter Web 所有demo均使用web--> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <!-- Spring Security OAuth2 --> <dependency> <groupId>org.springframework.security.oauth</groupId> <artifactId>spring-security-oauth2</artifactId> <version>${spring-security-oauth2.version}</version> </dependency>

搭建授權(quán)服務(wù)器(Authorization Server)

文中服務(wù)器均使用demo級(jí)別配置,請(qǐng)勿直接使用到生產(chǎn)環(huán)境

授權(quán)服務(wù)器結(jié)構(gòu)主體如下:

Spring Security OAuth2 授權(quán)碼模式的實(shí)現(xiàn)

啟動(dòng)類自不多說(shuō),先說(shuō)下SecurityConfig

package com.github.hellxz.oauth2.config;import org.springframework.context.annotation.Bean;import org.springframework.context.annotation.Configuration;import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;import org.springframework.security.config.annotation.web.builders.HttpSecurity;import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;import org.springframework.security.crypto.password.PasswordEncoder;import java.util.Collections;@Configuration@EnableWebSecuritypublic class SecurityConfig extends WebSecurityConfigurerAdapter { @Bean public PasswordEncoder passwordEncoder(){ return new BCryptPasswordEncoder(); } @Override protected void configure(AuthenticationManagerBuilder auth) throws Exception { // @formatter: off auth.inMemoryAuthentication() .withUser('hellxz') .password(passwordEncoder().encode('xyz')) .authorities(Collections.emptyList()); // @formatter: on } @Override protected void configure(HttpSecurity http) throws Exception { http.authorizeRequests() .anyRequest().authenticated() //所有請(qǐng)求都需要通過(guò)認(rèn)證 .and() .httpBasic() //Basic登錄 .and() .csrf().disable(); //關(guān)跨域保護(hù) }}

通過(guò)@Configuration 和@EnableWebSecurity開(kāi)啟Spring Security配置,繼承WebSecurityConfigurerAdapter的方法,實(shí)現(xiàn)個(gè)性化配置,這里我們使用內(nèi)存保存一個(gè)名為hellxz、密碼為xyz的用戶,與授權(quán)服務(wù)器交互的用戶就是他了

除了配置用戶,我們需要對(duì)服務(wù)的資源進(jìn)行保護(hù),這里將所有的請(qǐng)求都要求通過(guò)認(rèn)證才可以訪問(wèn),用戶登錄需要使用httpBasic形式(就是那種網(wǎng)頁(yè)彈個(gè)窗要求登錄的那種😄)

Spring Security 5.x版本后,要求顯示聲明使用的密碼器,就是PasswordEncoder了,常用BCryptPasswordEncoder,簡(jiǎn)單的可以認(rèn)為它是使用時(shí)間戳和鹽進(jìn)行加密的一種算法,同一個(gè)密碼被加密后也不會(huì)相同

接著看看授權(quán)服務(wù)器的配置,畫重點(diǎn)

package com.github.hellxz.oauth2.config;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.context.annotation.Configuration;import org.springframework.security.crypto.password.PasswordEncoder;import org.springframework.security.oauth2.config.annotation.configurers.ClientDetailsServiceConfigurer;import org.springframework.security.oauth2.config.annotation.web.configuration.AuthorizationServerConfigurerAdapter;import org.springframework.security.oauth2.config.annotation.web.configuration.EnableAuthorizationServer;import org.springframework.security.oauth2.config.annotation.web.configurers.AuthorizationServerSecurityConfigurer;//授權(quán)服務(wù)器配置@Configuration@EnableAuthorizationServer //開(kāi)啟授權(quán)服務(wù)public class AuthorizationConfig extends AuthorizationServerConfigurerAdapter { @Autowired private PasswordEncoder passwordEncoder; @Override public void configure(AuthorizationServerSecurityConfigurer security) throws Exception { //允許表單提交 security.allowFormAuthenticationForClients() .checkTokenAccess('isAuthenticated()'); } @Override public void configure(ClientDetailsServiceConfigurer clients) throws Exception { // @formatter: off clients.inMemory() .withClient('client-a') //client端唯一標(biāo)識(shí) .secret(passwordEncoder.encode('client-a-secret')) //客戶端的密碼,這里的密碼應(yīng)該是加密后的 .authorizedGrantTypes('authorization_code') //授權(quán)模式標(biāo)識(shí) .scopes('read_user_info') //作用域 .resourceIds('resource1') //資源id .redirectUris('http://localhost:9001/callback'); //回調(diào)地址 // @formatter: on }}

1.通過(guò)@Configuration 和EnableAuthorizationServer開(kāi)啟授權(quán)服務(wù)器配置,通過(guò)重寫AuthorizationServerConfigurerAdapter的方法來(lái)完成自定義授權(quán)服務(wù)器

2.OAuth2授權(quán)碼模式中,要求不僅僅用戶需要登錄,還要求客戶端也需要登錄,這里就需要在configure(ClientDetailsServiceConfigurer clients)這個(gè)方法中配置客戶端(第三方應(yīng)用)的登錄信息,

withClient中配置的是客戶端id(client_id)secret為客戶端的密碼,要求使用加密器進(jìn)行加密授權(quán)碼的authorizedGrantTypes必須配置有'authorization_code'(授權(quán)碼模式),這里是可以同時(shí)支持多種授權(quán)模式的,為了簡(jiǎn)單只寫一個(gè)scopes,請(qǐng)求資源作用域,用于限制客戶端與用戶無(wú)法訪問(wèn)沒(méi)有作用域的資源resourceIds,可選,資源id,可以對(duì)應(yīng)一個(gè)資源服務(wù)器,個(gè)人理解為某個(gè)資源服務(wù)器的所有資源標(biāo)識(shí)redirectUris,回調(diào)地址,有兩個(gè)作用:1.回調(diào)客戶端地址,返回授權(quán)碼; 2.校驗(yàn)是否是同一個(gè)客戶端

redirectUris校驗(yàn)是否同一個(gè)客戶端這個(gè),可能說(shuō)的不是很準(zhǔn)確,說(shuō)下大體流程,我們?cè)谑跈?quán)服務(wù)器上配置了這個(gè)回調(diào)地址,授權(quán)服務(wù)器在用戶授權(quán)成功后,返回授權(quán)碼的地址就是它,另外我們后續(xù)申請(qǐng)token時(shí),也需要傳遞這個(gè)回調(diào)地址,所以我的理解是校驗(yàn)是否是同一客戶端發(fā)來(lái)的第二次請(qǐng)求(換token時(shí))

3.configure(AuthorizationServerSecurityConfigurer security)這里配置資源客戶端(第三方應(yīng)用)的表單提交權(quán)限,類似Spring Security配置的permitAll()等權(quán)限控制標(biāo)識(shí),如果不配置,客戶端將無(wú)法換取token

4.application.properties

這里我只配置了server.port=8080

這樣我們就配置了相當(dāng)簡(jiǎn)易的授權(quán)服務(wù)器,啟動(dòng)測(cè)試下

Spring Security OAuth2 授權(quán)碼模式的實(shí)現(xiàn)

獲取授權(quán)碼的流程,一般是由客戶端使用自己的client_id與密碼+response_type=code拼接url,讓瀏覽器跳轉(zhuǎn)完成的,用戶的登錄與授權(quán)過(guò)程都需要在瀏覽器中完成,啟動(dòng)項(xiàng)目后訪問(wèn)下列url

http://localhost:8080/oauth/authorize?client_id=client-a&client_secret=client-a-secret&response_type=code

登錄用戶/密碼: hellxz/xyz ,選擇Approve表示接受授權(quán),Deny反之,如下動(dòng)圖所示

Spring Security OAuth2 授權(quán)碼模式的實(shí)現(xiàn)

最后我們得到了回調(diào)地址http://localhost:9001/callback?code=2e6450

這里的code就是授權(quán)碼,接下來(lái)我們使用授權(quán)碼進(jìn)行換取token

POST請(qǐng)求,http://localhost:8080/oauth/token,參數(shù)如圖

Spring Security OAuth2 授權(quán)碼模式的實(shí)現(xiàn)

BasicAuth:這里填的是客戶端配置的client_id和client_secret的值,相當(dāng)于curl --user client_id:client_secret,配置后會(huì)在Header中添加Authorization:Basic Y2xpZW50LWE6Y2xpZW50LWEtc2VjcmV0,Basic空格 后的是client_id:client_secret具體值被Base64后得到的值

請(qǐng)求參數(shù)列表:

code=授權(quán)碼 grant_type=authorization_code redirect_uri=回調(diào)url ,要與配置處和獲取授權(quán)碼處相同 scope=作用域

最后我們獲得了授權(quán)服務(wù)的響應(yīng),包含token的json

{ 'access_token': '99435e13-f9fe-438a-a94e-3b00d549b329', //訪問(wèn)token 'token_type': 'bearer', //token類型,使用時(shí)需要拼接在token前并在token前加空格 'expires_in': 43199, //過(guò)期時(shí)間 'scope': 'read_user_info' //作用域}

在access_token未過(guò)期之前,同一個(gè)用戶名使用同一個(gè)客戶端訪問(wèn)都會(huì)是同一個(gè)access_token

授權(quán)服務(wù)器先放在這里,不要關(guān)服,接下來(lái)搭建資源服務(wù)器

搭建資源服務(wù)器(Resource Server)

資源服務(wù)器結(jié)構(gòu)

Spring Security OAuth2 授權(quán)碼模式的實(shí)現(xiàn)

入口類不多說(shuō),先搭建資源服務(wù)器主要配置,這里直接使用ResourceConfig進(jìn)行配置

package com.github.hellxz.oauth2.config;import org.springframework.context.annotation.Bean;import org.springframework.context.annotation.Configuration;import org.springframework.context.annotation.Primary;import org.springframework.security.config.annotation.web.builders.HttpSecurity;import org.springframework.security.config.http.SessionCreationPolicy;import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;import org.springframework.security.crypto.password.PasswordEncoder;import org.springframework.security.oauth2.config.annotation.web.configuration.EnableResourceServer;import org.springframework.security.oauth2.config.annotation.web.configuration.ResourceServerConfigurerAdapter;import org.springframework.security.oauth2.config.annotation.web.configurers.ResourceServerSecurityConfigurer;import org.springframework.security.oauth2.provider.token.RemoteTokenServices;@Configuration@EnableResourceServerpublic class ResourceConfig extends ResourceServerConfigurerAdapter { @Bean public PasswordEncoder passwordEncoder() { return new BCryptPasswordEncoder(); } @Primary @Bean public RemoteTokenServices remoteTokenServices() { final RemoteTokenServices tokenServices = new RemoteTokenServices(); //設(shè)置授權(quán)服務(wù)器check_token端點(diǎn)完整地址 tokenServices.setCheckTokenEndpointUrl('http://localhost:8080/oauth/check_token'); //設(shè)置客戶端id與secret,注意:client_secret值不能使用passwordEncoder加密! tokenServices.setClientId('client-a'); tokenServices.setClientSecret('client-a-secret'); return tokenServices; } @Override public void configure(HttpSecurity http) throws Exception { //設(shè)置創(chuàng)建session策略 http.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.IF_REQUIRED); //@formatter:off //所有請(qǐng)求必須授權(quán) http.authorizeRequests() .anyRequest().authenticated(); //@formatter:on } @Override public void configure(ResourceServerSecurityConfigurer resources) { resources.resourceId('resource1').stateless(true); }}

1.通過(guò)@Configuration 和@EnableResourceServer這兩個(gè)注解標(biāo)識(shí)服務(wù)是一個(gè)資源服務(wù)器,重寫ResourceServerConfigurerAdapter來(lái)實(shí)現(xiàn)自定義授權(quán)服務(wù)器

2.配置configure(HttpSecurity http)方法,這里可以代替Spring Security同名方法配置,開(kāi)啟所有請(qǐng)求需要授權(quán)才可訪問(wèn)

3.配置資源相關(guān)設(shè)置configure(ResourceServerSecurityConfigurer resources),這里只設(shè)置resourceId

后續(xù)的使用redis校驗(yàn)token也在這里設(shè)置

4.校驗(yàn)token的配置,這里使用了遠(yuǎn)程調(diào)用授權(quán)服務(wù)器幫忙校驗(yàn)token的方式,只需要顯示注入RemoteTokenServices remoteTokenServices()的Bean,就可以調(diào)用授權(quán)服務(wù)器的/oauth/check_token端點(diǎn),設(shè)置客戶端配置的值,詳見(jiàn)注釋

這樣一來(lái)我們就配置好了資源服務(wù)器,當(dāng)然光有配置是不夠的,我們搞一個(gè)資源接口做測(cè)試用

上邊的ResourceController與UserVO都比較簡(jiǎn)單,傳入一個(gè)名稱,返回用戶對(duì)象,包含用戶名和郵箱信息

package com.github.hellxz.oauth2.web.controller;import com.github.hellxz.oauth2.web.vo.UserVO;import org.springframework.web.bind.annotation.GetMapping;import org.springframework.web.bind.annotation.PathVariable;import org.springframework.web.bind.annotation.RestController;@RestControllerpublic class ResourceController { @GetMapping('/user/{username}') public UserVO user(@PathVariable String username){ return new UserVO(username, username + '@foxmail.com'); }}

package com.github.hellxz.oauth2.web.vo;public class UserVO { private String username; private String email; public UserVO(String username, String email) { this.username = username; this.email = email; } public String getUsername() { return username; } public void setUsername(String username) { this.username = username; } public String getEmail() { return email; } public void setEmail(String email) { this.email = email; }}

application.properties中配置了與授權(quán)服務(wù)器不同的端口:8081

server.port=8081

啟動(dòng)資源服務(wù)測(cè)試

什么也不傳,直接訪問(wèn)接口,提示資源需要授權(quán)

Spring Security OAuth2 授權(quán)碼模式的實(shí)現(xiàn)

復(fù)制之前獲取到的token,添加token訪問(wèn)接口http://localhost:8081/user/hellxz001

Spring Security OAuth2 授權(quán)碼模式的實(shí)現(xiàn)

Bearer Token相當(dāng)于在Headers中添加Authorization:Bearer空格access_token

至此我們成功的搭建并測(cè)試了授權(quán)碼模式下的最簡(jiǎn)單的授權(quán)服務(wù)與資源服務(wù)分離的demo

尾聲

授權(quán)碼模式就先在這里告一段落,寫的比較基礎(chǔ),自認(rèn)為該說(shuō)到的點(diǎn)都說(shuō)到了,后續(xù)還會(huì)寫其它模式的文章,如文中有何遺漏,請(qǐng)不吝評(píng)論反饋,本人會(huì)盡快改正,謝謝

本文以及后續(xù)文章的demo均放在GitHub上,歡迎大家Star & Fork,源碼地址:https://github.com/hellxz/spring-security-oauth2-learn ,Demo中的README文檔寫得比較詳細(xì),也可堪一看

原文出處https://www.cnblogs.com/hellxz/p/oauth2_oauthcode_pattern.html

到此這篇關(guān)于Spring Security OAuth2 授權(quán)碼模式的實(shí)現(xiàn)的文章就介紹到這了,更多相關(guān)Spring Security OAuth2 授權(quán)碼模式內(nèi)容請(qǐng)搜索好吧啦網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持好吧啦網(wǎng)!

標(biāo)簽: Spring
相關(guān)文章:
成人在线亚洲_国产日韩视频一区二区三区_久久久国产精品_99国内精品久久久久久久
在线天堂一区av电影| 欧美日韩在线精品一区二区三区激情| 久久综合狠狠综合久久综青草| 国产精品二区一区二区aⅴ污介绍| 国产福利一区二区| 欧美日韩国产123区| 欧美96一区二区免费视频| 久久蜜桃资源一区二区老牛| 亚洲一区二区欧美日韩| 亚洲美女网站| 亚洲视频在线观看一区| 91丨porny丨国产| 久久午夜羞羞影院免费观看| eeuss鲁片一区二区三区| 日韩精品一区二区三区在线观看 | 婷婷中文字幕一区三区| 亚洲欧美久久久| 亚洲高清三级视频| 久久xxxx| 亚洲bt欧美bt精品| 色噜噜狠狠色综合欧洲selulu| 亚洲国产wwwccc36天堂| 久久香蕉精品| 免费一级片91| 欧美日韩在线精品一区二区三区激情 | 欧美日韩国产综合网| 国产精品欧美一区二区三区| 国产专区一区| 亚洲六月丁香色婷婷综合久久| 日韩亚洲一区在线播放| 亚洲国产日韩一级| 久久精品123| 久久精品国产99久久6| 欧美日韩一区二区三区不卡| 国产精品一区二区久激情瑜伽| 日韩精品一区二| 99国产精品视频免费观看| 国产精品网站在线观看| 夜夜爽www精品| 日韩国产欧美在线播放| 欧美人伦禁忌dvd放荡欲情| 懂色av中文字幕一区二区三区| 国产性色一区二区| 韩国免费一区| 亚洲一线二线三线视频| 欧美亚洲一区二区在线| 懂色av一区二区三区蜜臀| 国产欧美日韩不卡免费| 伊人久久婷婷| 五月婷婷激情综合| 欧美日韩性生活| caoporen国产精品视频| 国产日韩欧美不卡| 99精品视频免费观看| 日本成人在线网站| 7777精品伊人久久久大香线蕉完整版| 成人教育av在线| 国产精品免费视频一区| 国产伦精品一区二区| 久久99精品久久只有精品| 日韩免费电影一区| 国产精品啊啊啊| 午夜伦理一区二区| 91精品婷婷国产综合久久竹菊| 91麻豆免费视频| 一区二区三区四区在线播放| 欧美三级电影在线观看| av电影一区二区| 亚洲精品成人悠悠色影视| 欧美亚洲一区二区三区四区| 99久久婷婷国产综合精品电影 | 日韩毛片精品高清免费| 欧美亚洲禁片免费| 91蝌蚪国产九色| 五月婷婷综合网| 精品国产乱码久久久久久老虎| 亚洲小说区图片区| 六月丁香婷婷久久| 日本一二三不卡| 色视频欧美一区二区三区| 成人动漫一区二区| 亚洲综合丁香婷婷六月香| 欧美日韩在线精品一区二区三区激情| 91一区在线观看| 图片区小说区区亚洲影院| 精品国产一区二区国模嫣然| 久久av最新网址| 大白屁股一区二区视频| 一区二区三区美女| 日韩免费高清av| 欧美在线综合| 91亚洲午夜精品久久久久久| 一区二区三区四区激情| 日韩精品专区在线影院重磅| 亚洲毛片播放| 国产成人av电影在线| 一区二区三区四区视频精品免费| 91精品国产色综合久久不卡蜜臀 | 国产日韩欧美三级| 国产成人av电影在线观看| 亚洲色图自拍偷拍美腿丝袜制服诱惑麻豆 | 99精品福利视频| 顶级嫩模精品视频在线看| 亚洲欧美韩国综合色| 欧美一区二区高清| 国产一区二区三区成人欧美日韩在线观看| 国产在线精品免费| 一区二区在线观看av| 欧美大白屁股肥臀xxxxxx| 午夜一区不卡| 午夜久久资源| 国产一区二区三区黄视频| 亚洲一区二区三区三| 久久亚洲免费视频| 欧日韩精品视频| 尤妮丝一区二区裸体视频| 国产不卡视频一区| 亚洲成人一区二区在线观看| 久久青草欧美一区二区三区| 欧美无人高清视频在线观看| 一区二区三区四区五区在线| 色综合色狠狠综合色| 精品一二三四在线| 亚洲sss视频在线视频| 国产精品国产自产拍在线| 欧美一区二区三区视频免费播放| 亚洲综合国产| 伊甸园精品99久久久久久| 播五月开心婷婷综合| 久久精品999| 亚洲成av人片观看| 亚洲欧洲三级电影| 精品国产乱码久久| 欧美系列在线观看| 国产伦精品一区二区三区视频黑人| 欧美在线网站| 成人激情电影免费在线观看| 蜜臀99久久精品久久久久久软件| 亚洲精品一卡二卡| 欧美激情一区二区三区蜜桃视频| 欧美电影免费观看高清完整版在线 | 欧美资源在线| 亚洲激情综合| 欧美成人高清| a级精品国产片在线观看| 国产美女精品一区二区三区| 蜜桃免费网站一区二区三区| 日韩黄色免费电影| 亚洲高清不卡在线| 一区二区久久久| 亚洲精品视频免费看| 国产精品卡一卡二卡三| 26uuu国产一区二区三区| 91精品国产黑色紧身裤美女| 色婷婷激情综合| 久久高清一区| 亚洲影音一区| 亚洲作爱视频| 亚洲理论在线| 99国产精品久久久久老师| 国产精品vip| 91在线码无精品| 不卡免费追剧大全电视剧网站| 国产成人在线影院| 国产一区二区三区蝌蚪| 国产真实乱对白精彩久久| 美女网站在线免费欧美精品| 日韩1区2区3区| 日本最新不卡在线| 首页国产欧美久久| 日韩二区在线观看| 日本中文在线一区| 麻豆国产精品777777在线| 奇米777欧美一区二区| 免费av网站大全久久| 看国产成人h片视频| 精品一区二区三区久久| 国产一区二三区| 国产精品中文有码| 国产超碰在线一区| 本田岬高潮一区二区三区| av在线这里只有精品| 99久久综合99久久综合网站| 97久久超碰精品国产| 欧美福利一区二区三区| 精品1区2区| 国产伦精品一区二区三区| 久久国产99| 色呦呦一区二区三区| 欧洲亚洲精品在线| 在线91免费看| 欧美一区二区三区在线看| 精品精品国产高清a毛片牛牛| 久久麻豆一区二区| 中文字幕视频一区| 一卡二卡欧美日韩| 青娱乐精品在线视频| 国产最新精品免费| 成人动漫在线一区| 国内精品久久久久国产盗摄免费观看完整版 |