<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    隨筆-193  評論-715  文章-1  trackbacks-0
    B/S通常我們的權限控制包括以下幾個方面:1,Web層訪問權限控制(包括URL級或Button/Link級);2,業務邏輯訪問控制,主要指業務邏輯中方法級的權限控制;3,數據訪問權限控制,主要指對Table, View的訪問控制,嚴格的控制會到Row級,甚至是Field級。

    問題引入:
    我們通常的系統中僅僅做了Web層訪問權限控制,因為大多系統只有Web方式的UI做為人機交互的接口,不提供其它的客戶端,所以業務邏輯訪問控制一般可以不用控制,數據訪問方面由于一般系統的要求目前尚未達到這一權限控制的必要,也沒有完整的進行控制。Web層的URL級控制通常采用J2EE規范中的Filter來解決,但由于JSF中的跳轉并不會重寫URL,默認采用Forward的方式,一般不會采用Redirect的方式,而且采用Redirect的時候,開發時會很不方便,很多Request參數無法傳遞,所以我們實際上在Filter中獲得的URI往往都不是真實的地址。

    實際案例:
    我們現在有一個畫面,假如從菜單中進入畫面的URI為“list.jsf”,畫面上有“新增”、“查詢”兩個Button,當點擊“查詢”這個Button時,查詢結果并顯示在“list.jsf”這個頁面上,當點擊“新增”這個Button時,跳轉到“add.jsf”這個頁面,新增畫面中還有一個“返回”Button。當我們點擊“新增”時,在Filter中得到的URI為“list.jsf”,實際上我們要跳轉到“add.jsf”這個頁面,當我們點擊“返回”Button時,Filter中得到URI的是“add.jsf”,這與我們實際要跳轉到的頁面“list.jsf”又不符。如果我們僅僅在Filter中根據URI來判斷權限,那么當一個用戶不具有新增權限時,就會出現可以操作新增功能的事情,這樣便未達到權限控制的目的。

    問題解決:
    JSF提供了自定義Application的可能,通過研究JSF的實現可以發現JSF控制頁面的跳轉都是在NavigationHandler中完成的。那么我們來試著實現一個自己的NavigationHandler,解決這一問題。先給出詳細的實現:
    ??1public?class?NavigationHandleWithAuthImpl?extends?NavigationHandler?{
    ??2
    ??3????/**
    ??4?????*?Field?DEBUGLOG.
    ??5?????*/

    ??6????private?static?final?Logger?DEBUGLOG?=?Logger.getLogger(Constant.LOG_DEBUG);
    ??7
    ??8????/**
    ??9?????*?Field?ERRORLOG.
    ?10?????*/

    ?11????private?static?final?Logger?ERRORLOG?=?Logger.getLogger(Constant.LOG_ERROR);
    ?12
    ?13????/**
    ?14?????*?Field?IGNORED_URI.
    ?15?????*/

    ?16????private?static?final?String?IGNORED_URI?=?"/login.faces;/send.faces;"
    ?17????????????+?"/mainlayout.faces;/backForward.faces";
    ?18
    ?19????/**
    ?20?????*?Application?associate?that?contains?navigation?mappings?loaded?from
    ?21?????*?configuration?file(s).
    ?22?????*/

    ?23????private?ApplicationAssociate?associate?=?null;
    ?24
    ?25????/**
    ?26?????*?This?constructor?uses?the?current?<code>Application</code>?instance?to
    ?27?????*?obtain?the?navigation?mappings?used?to?make?navigational?decisions.
    ?28?????*/

    ?29????public?NavigationHandleWithAuthImpl()?{
    ?30????????super();
    ?31????????if?(DEBUGLOG.isDebugEnabled())?{
    ?32????????????DEBUGLOG.debug("Created?NavigationHandler?instance?");
    ?33????????}

    ?34????????//?if?the?user?is?using?the?decorator?pattern,?this?would?cause
    ?35????????//?our?ApplicationAssociate?to?be?created,?if?it?isn't?already
    ?36????????//?created.
    ?37????????ApplicationFactory?aFactory?=?(ApplicationFactory)?FactoryFinder
    ?38????????????????.getFactory(FactoryFinder.APPLICATION_FACTORY);
    ?39????????aFactory.getApplication();
    ?40????????associate?=?ApplicationAssociate.getInstance(ConfigureListener
    ?41????????????????.getExternalContextDuringInitialize());
    ?42????}

    ?43
    ?44????/**
    ?45?????*?檢查URL權限
    ?46?????*?
    ?47?????*?@param?authList
    ?48?????*????????????List<FunctionVo>
    ?49?????*?@param?uri
    ?50?????*????????????String
    ?51?????*?@return?boolean
    ?52?????*/

    ?53????private?boolean?checkURL(List<FunctionVo>?authList,?String?uri)?{
    ?54????????if?(authList?==?null)?{
    ?55????????????return?false;
    ?56????????}

    ?57????????for?(FunctionVo?vo?:?authList)?{
    ?58????????????String?authUri?=?vo.getUrl();
    ?59????????????if?(authUri?!=?null?&&?!authUri.equals(""))?{
    ?60????????????????int?index?=?authUri.indexOf("?");
    ?61????????????????if?(index?>=?0)?{
    ?62????????????????????authUri?=?authUri.substring(0,?index);
    ?63????????????????}

    ?64????????????}

    ?65????????????if?(uri.equals("/"?+?authUri))?{
    ?66????????????????return?true;
    ?67????????????}

    ?68????????}

    ?69????????return?false;
    ?70????}

    ?71
    ?72????/**
    ?73?????*?Determine?the?next?view?based?on?the?current?view?
    ?74?????*?(<code>from-view-id</code>
    ?75?????*?stored?in?<code>FacesContext</code>),?<code>fromAction</code>?and
    ?76?????*?<code>outcome</code>.
    ?77?????*?
    ?78?????*?@param?context
    ?79?????*????????????The?<code>FacesContext</code>
    ?80?????*?@param?fromAction
    ?81?????*????????????the?action?reference?string
    ?82?????*?@param?outcome
    ?83?????*????????????the?outcome?string
    ?84?????*/

    ?85????public?void?handleNavigation(FacesContext?context,?String?fromAction,
    ?86????????????String?outcome)?{
    ?87????????if?(context?==?null)?{
    ?88????????????String?message?=?Util
    ?89????????????????????.getExceptionMessageString(Util.
    ?90????????????????????????????NULL_PARAMETERS_ERROR_MESSAGE_ID);
    ?91????????????message?=?message?+?"?context?"?+?context;
    ?92????????????throw?new?NullPointerException(message);
    ?93????????}

    ?94????????if?(outcome?==?null)?{
    ?95????????????if?(DEBUGLOG.isDebugEnabled())?{
    ?96????????????????DEBUGLOG.debug("No?navigation?rule?found?for?outcome?"
    ?97????????????????????????+?outcome?+?"and?viewId?"
    ?98????????????????????????+?context.getViewRoot().getViewId()
    ?99????????????????????????+?"?Explicitly?remain?on?the?current?view?");
    100????????????}

    101????????????return;?//?Explicitly?remain?on?the?current?view
    102????????}

    103????????CaseStruct?caseStruct?=?getViewId(context,?fromAction,?outcome);
    104????????ExternalContext?extContext?=?context.getExternalContext();
    105????????if?(caseStruct?!=?null)?{
    106????????????Object?obj?=?context.getExternalContext().getSessionMap().get(
    107????????????????????Constant.LOGIN_INFO_KEY);
    108????????????List?authList?=?null;
    109????????????if?(obj?!=?null)?{
    110????????????????authList?=?((LoginInfo)?obj).getAuthorityFunctionVoList();
    111????????????}

    112????????????String?uri?=?caseStruct.navCase.getToViewId().replace(".jsp",
    113????????????????????".faces");
    114????????????boolean?flag=true;
    115????????????if?(this.IGNORED_URI.indexOf(uri)?<?0)?{
    116????????????????if?(authList?!=?null?&&?!this.checkURL(authList,?uri))?{
    117????????????????????//?URI?is?invalid
    118????????????????????flag=false;
    119????????????????}

    120????????????}

    121
    122????????????ViewHandler?viewHandler?=?Util.getViewHandler(context);
    123????????????Util.doAssert(null?!=?viewHandler);
    124
    125????????????if?(caseStruct.navCase.hasRedirect())?{
    126????????????????//?perform?a?302?redirect.
    127????????????????String?newPath?=?viewHandler.getActionURL(context,
    128????????????????????????caseStruct.viewId);
    129
    130????????????????try?{
    131????????????????????if?(DEBUGLOG.isDebugEnabled())?{
    132????????????????????????DEBUGLOG.debug("Redirecting?to?path?"?+?newPath
    133????????????????????????????????+?"?for?outcome?"?+?outcome?+?"and?viewId?"
    134????????????????????????????????+?caseStruct.viewId);
    135????????????????????}

    136????????????????????extContext.redirect(newPath);
    137????????????????}
    ?catch?(java.io.IOException?ioe)?{
    138????????????????????String?message?=?"Redirect?to?"?+?newPath?+?"?failed.";
    139????????????????????ERRORLOG.error(message);
    140????????????????????throw?new?FacesException(message,?ioe);
    141????????????????}

    142????????????????context.responseComplete();
    143????????????????if?(DEBUGLOG.isDebugEnabled())?{
    144????????????????????DEBUGLOG
    145????????????????????????????.debug("Response?complete?for?"?
    146????????????????????????????????????+?caseStruct.viewId);
    147????????????????}

    148????????????}
    ?else?{
    149????????????????UIViewRoot?newRoot?=?null;
    150????????????????if?(flag)?{
    151????????????????????newRoot?=?viewHandler
    152????????????????????????.createView(context,?caseStruct.viewId);
    153????????????????}
    ?else?{
    154????????????????????newRoot?=?viewHandler.createView(context,
    155????????????????????????"/backForward.jsp");
    156????????????????}

    157????????????????context.setViewRoot(newRoot);
    158????????????????if?(DEBUGLOG.isDebugEnabled())?{
    159????????????????????DEBUGLOG.debug("Set?new?view?in?FacesContext?for?"
    160????????????????????????+?caseStruct.viewId);
    161????????????????}

    162????????????}

    163????????}

    164????}

    165
    166????/**
    167?????*?This?method?uses?helper?methods?to?determine?the?new?<code>view</code>
    168?????*?identifier.?Refer?to?section?7.4.2?of?the?specification?for?more?details.
    169?????*?
    170?????*?@param?context
    171?????*????????????The?Faces?Context
    172?????*?@param?fromAction
    173?????*????????????The?action?reference?string
    174?????*?@param?outcome
    175?????*????????????The?outcome?string
    176?????*?@return?The?<code>view</code>?identifier.
    177?????*/

    178????private?CaseStruct?getViewId(FacesContext?context,?String?fromAction,
    179????????????String?outcome)?{
    180????????//?String?nextViewId?=?null;
    181????????String?viewId?=?context.getViewRoot().getViewId();
    182????????CaseStruct?caseStruct?=?null;
    183
    184????????synchronized?(this)?{
    185????????????caseStruct?=?findExactMatch(viewId,?fromAction,?outcome);
    186
    187????????????if?(caseStruct?==?null)?{
    188????????????????caseStruct?=?findWildCardMatch(viewId,?fromAction,?outcome);
    189????????????}

    190
    191????????????if?(caseStruct?==?null)?{
    192????????????????caseStruct?=?findDefaultMatch(fromAction,?outcome);
    193????????????}

    194????????}

    195????????return?caseStruct;
    196????}

    197
    198????/**
    199?????*?This?method?finds?the?List?of?cases?for?the?current?<code>view</code>
    200?????*?identifier.?After?the?cases?are?found,?the?<code>from-action</code>?and
    201?????*?<code>from-outcome</code>?values?are?evaluated?to?determine?the?new
    202?????*?<code>view</code>?identifier.?Refer?to?section?7.4.2?of?the
    203?????*?specification?for?more?details.
    204?????*?
    205?????*?@param?viewId
    206?????*????????????The?current?<code>view</code>?identifier.
    207?????*?@param?fromAction
    208?????*????????????The?action?reference?string.
    209?????*?@param?outcome
    210?????*????????????The?outcome?string.
    211?????*?@return?The?<code>view</code>?identifier.
    212?????*/

    213
    214????private?synchronized?CaseStruct?findExactMatch(String?viewId,
    215????????????String?fromAction,?String?outcome)?{
    216????????//?String?returnViewId?=?null;
    217????????//?if?the?user?has?elected?to?replace?the?Application?instance
    218????????//?entirely
    219????????if?(null?==?associate)?{
    220????????????return?null;
    221????????}

    222????????Map?caseListMap?=?associate.getNavigationCaseListMappings();
    223????????Util.doAssert(null?!=?caseListMap);
    224????????List?caseList?=?(List)?caseListMap.get(viewId);
    225????????if?(caseList?==?null)?{
    226????????????return?null;
    227????????}

    228????????//?We've?found?an?exact?match?for?the?viewId.?Now?we?need?to?evaluate
    229????????//?from-action/outcome?in?the?following?order:
    230????????//?1)?elements?specifying?both?from-action?and?from-outcome
    231????????//?2)?elements?specifying?only?from-outcome
    232????????//?3)?elements?specifying?only?from-action
    233????????//?4)?elements?where?both?from-action?and?from-outcome?are?null
    234????????return?determineViewFromActionOutcome(caseList,?fromAction,?outcome);
    235????}

    236
    237????/**
    238?????*?This?method?traverses?the?wild?card?match?List?(containing
    239?????*?<code>from-view-id</code>?strings?and?finds?the?List?of?cases?for?each
    240?????*?<code>from-view-id</code>?string.?Refer?to?section?7.4.2?of?the
    241?????*?specification?for?more?details.
    242?????*?
    243?????*?@param?viewId
    244?????*????????????The?current?<code>view</code>?identifier.
    245?????*?@param?fromAction
    246?????*????????????The?action?reference?string.
    247?????*?@param?outcome
    248?????*????????????The?outcome?string.
    249?????*?@return?The?<code>view</code>?identifier.
    250?????*/

    251????private?synchronized?CaseStruct?findWildCardMatch(String?viewId,
    252????????????String?fromAction,?String?outcome)?{
    253????????CaseStruct?result?=?null;
    254
    255????????//?if?the?user?has?elected?to?replace?the?Application?instance
    256????????//?entirely
    257????????if?(null?==?associate)?{
    258????????????return?null;
    259????????}

    260
    261????????Map?caseListMap?=?associate.getNavigationCaseListMappings();
    262????????Util.doAssert(null?!=?caseListMap);
    263????????TreeSet?wildcardMatchList?=?associate.getNavigationWildCardList();
    264????????Util.doAssert(null?!=?wildcardMatchList);
    265
    266????????Iterator?iter?=?wildcardMatchList.iterator();
    267????????String?fromViewId;
    268????????List?caseList;
    269????????String?wcFromViewId?=?null;
    270????????while?(iter.hasNext())?{
    271????????????fromViewId?=?(String)?iter.next();
    272????????????//?See?if?the?entire?wildcard?string?(without?the?trailing?"*"?is
    273????????????//?contained?in?the?incoming?viewId.?Ex:?/foobar?is?contained?with
    274????????????//?/foobarbaz
    275????????????//?If?so,?then?we?have?found?our?largest?pattern?match..
    276????????????//?If?not,?then?continue?on?to?the?next?case;
    277
    278????????????if?(viewId.indexOf(fromViewId,?0)?==?-1)?{
    279????????????????continue;
    280????????????}

    281????????????//?Append?the?trailing?"*"?so?we?can?do?our?map?lookup;
    282????????????wcFromViewId?=?fromViewId?+?"*";
    283????????????caseList?=?(List)?caseListMap.get(wcFromViewId);
    284
    285????????????if?(caseList?==?null)?{
    286????????????????return?null;
    287????????????}

    288
    289????????????//?If?we've?found?a?match,?then?we?need?to?evaluate
    290????????????//?from-action/outcome?in?the?following?order:
    291????????????//?1)?elements?specifying?both?from-action?and?from-outcome
    292????????????//?2)?elements?specifying?only?from-outcome
    293????????????//?3)?elements?specifying?only?from-action
    294????????????//?4)?elements?where?both?from-action?and?from-outcome?are?null
    295
    296????????????result?=?determineViewFromActionOutcome(caseList,?fromAction,
    297????????????????????outcome);
    298????????????if?(result?!=?null)?{
    299????????????????break;
    300????????????}

    301????????}

    302????????return?result;
    303????}

    304
    305????/**
    306?????*?This?method?will?extract?the?cases?for?which?a?<code>from-view-id</code>
    307?????*?is?an?asterisk?"*".?Refer?to?section?7.4.2?of?the?specification?for?more
    308?????*?details.
    309?????*?
    310?????*?@param?fromAction
    311?????*????????????The?action?reference?string.
    312?????*?@param?outcome
    313?????*????????????The?outcome?string.
    314?????*?@return?The?<code>view</code>?identifier.
    315?????*/

    316
    317????private?synchronized?CaseStruct?findDefaultMatch(String?fromAction,
    318????????????String?outcome)?{
    319????????//?String?returnViewId?=?null;
    320????????//?if?the?user?has?elected?to?replace?the?Application?instance
    321????????//?entirely
    322????????if?(null?==?associate)?{
    323????????????return?null;
    324????????}

    325
    326????????Map?caseListMap?=?associate.getNavigationCaseListMappings();
    327????????Util.doAssert(null?!=?caseListMap);
    328
    329????????List?caseList?=?(List)?caseListMap.get("*");
    330
    331????????if?(caseList?==?null)?{
    332????????????return?null;
    333????????}

    334
    335????????//?We?need?to?evaluate?from-action/outcome?in?the?follow
    336????????//?order:?1)elements?specifying?both?from-action?and?from-outcome
    337????????//?2)?elements?specifying?only?from-outcome
    338????????//?3)?elements?specifying?only?from-action
    339????????//?4)?elements?where?both?from-action?and?from-outcome?are?null
    340
    341????????return?determineViewFromActionOutcome(caseList,?fromAction,?outcome);
    342????}

    343
    344????/**
    345?????*?This?method?will?attempt?to?find?the?<code>view</code>?identifier?based
    346?????*?on?action?reference?and?outcome.?Refer?to?section?7.4.2?of?the
    347?????*?specification?for?more?details.
    348?????*?
    349?????*?@param?caseList
    350?????*????????????The?list?of?navigation?cases.
    351?????*?@param?fromAction
    352?????*????????????The?action?reference?string.
    353?????*?@param?outcome
    354?????*????????????The?outcome?string.
    355?????*?@return?The?<code>view</code>?identifier.
    356?????*/

    357????private?synchronized?CaseStruct?determineViewFromActionOutcome(
    358????????????List?caseList,?String?fromAction,?String?outcome)?{
    359
    360????????String?cncFromAction?=?null;
    361????????String?fromOutcome?=?null;
    362????????String?toViewId?=?null;
    363????????CaseStruct?result?=?new?CaseStruct();
    364????????int?size=caseList.size();
    365????????ConfigNavigationCase?cnc?=?null;
    366????????for?(int?i?=?0;?i?<?size;?i++)?{
    367????????????cnc?=?(ConfigNavigationCase)?caseList.get(i);
    368????????????cncFromAction?=?cnc.getFromAction();
    369????????????fromOutcome?=?cnc.getFromOutcome();
    370????????????toViewId?=?cnc.getToViewId();
    371????????????if?((cncFromAction?!=?null)?&&?(fromOutcome?!=?null))?{
    372????????????????if?((cncFromAction.equals(fromAction))
    373????????????????????????&&?(fromOutcome.equals(outcome)))?{
    374????????????????????result.viewId?=?toViewId;
    375????????????????????result.navCase?=?cnc;
    376????????????????????return?result;
    377????????????????}

    378????????????}

    379????????}

    380????????for?(int?i?=?0;?i?<?size;?i++)?{
    381????????????cnc?=?(ConfigNavigationCase)?caseList.get(i);
    382????????????cncFromAction?=?cnc.getFromAction();
    383????????????fromOutcome?=?cnc.getFromOutcome();
    384????????????toViewId?=?cnc.getToViewId();
    385????????????if?((cncFromAction?==?null)?&&?(fromOutcome?!=?null))?{
    386????????????????if?(fromOutcome.equals(outcome))?{
    387????????????????????result.viewId?=?toViewId;
    388????????????????????result.navCase?=?cnc;
    389????????????????????return?result;
    390????????????????}

    391????????????}

    392????????}

    393
    394????????for?(int?i?=?0;?i?<?size;?i++)?{
    395????????????cnc?=?(ConfigNavigationCase)?caseList.get(i);
    396????????????cncFromAction?=?cnc.getFromAction();
    397????????????fromOutcome?=?cnc.getFromOutcome();
    398????????????toViewId?=?cnc.getToViewId();
    399????????????if?((cncFromAction?!=?null)?&&?(fromOutcome?==?null))?{
    400????????????????if?(cncFromAction.equals(fromAction))?{
    401????????????????????result.viewId?=?toViewId;
    402????????????????????result.navCase?=?cnc;
    403????????????????????return?result;
    404????????????????}

    405????????????}

    406????????}

    407
    408????????for?(int?i?=?0;?i?<?size;?i++)?{
    409????????????cnc?=?(ConfigNavigationCase)?caseList.get(i);
    410????????????cncFromAction?=?cnc.getFromAction();
    411????????????fromOutcome?=?cnc.getFromOutcome();
    412????????????toViewId?=?cnc.getToViewId();
    413????????????if?((cncFromAction?==?null)?&&?(fromOutcome?==?null))?{
    414????????????????result.viewId?=?toViewId;
    415????????????????result.navCase?=?cnc;
    416????????????????return?result;
    417????????????}

    418????????}

    419
    420????????return?null;
    421????}

    422
    423????/**
    424?????*?@author?robin
    425?????*/

    426????class?CaseStruct?{
    427
    428????????/**
    429?????????*?Field?viewId.
    430?????????*/

    431????????protected?String?viewId;
    432
    433????????/**
    434?????????*?Field?navCase.
    435?????????*/

    436????????protected?ConfigNavigationCase?navCase;
    437????}

    438
    439}

    440

    來看看其中的關鍵部分,149行起:
    UIViewRoot?newRoot?=?null;
    if?(flag)?{?????
    ?????
    //當檢查URL通過時,使用CaseStruct,即faces-config.xml中的配置跳轉
    ????newRoot?=?viewHandler
    ????????.createView(context,?caseStruct.viewId);
    }
    ?else?{??????
    ????
    //未通過URL檢查時,直接到權限不足頁面或你指定的頁面
    ????newRoot?=?viewHandler.createView(context,
    ????????
    "/backForward.jsp");
    }

    context.setViewRoot(newRoot);

    當然別忘了在faces-config.xml中加入自定義Application Navigation的配置,如下:
    ?1<faces-config>
    ?2????<application>
    ?3????????<navigation-handler?id="navigationWithAuth">
    ?4????????????com.***.framework.NavigationHandleWithAuthImpl
    ?5????????</navigation-handler>
    ?6????</application>
    ?7
    ?8
    ?9
    10
    11</faces-config>


    注意:
    在NavigationHandler中,當發現檢查URL權限未能通過時,千萬不要直接去修改當前的那個CaseStruts,因為JSF自己會緩存整個跳轉的配置,以提高執行效率,請使用viewHandler.createView()來創建一個新CaseStruts,否則會發生跳轉不正常的情況。
    posted on 2007-10-16 14:07 Robin's Programming World 閱讀(8694) 評論(6)  編輯  收藏 所屬分類: Java

    評論:
    # re: JSF深入--控制跳轉 2007-10-16 14:39 | cooky
    你好! 為什么不用飯否呢?
    just an advice :)  回復  更多評論
      
    # re: JSF深入--控制跳轉 2007-10-16 15:11 | Robin's Java World
    @cooky
    飯否?
    什么意思?沒明白。  回復  更多評論
      
    # re: JSF深入--控制跳轉 2007-10-16 17:46 | Robin's Java World
    @cooky
    明白了。飯否也還不錯。呵呵!  回復  更多評論
      
    # re: JSF深入--控制跳轉 2007-10-17 12:56 | Alexander.Yu
    一個跳轉就要寫500多行...暈倒.  回復  更多評論
      
    # re: JSF深入--控制跳轉 2007-10-18 12:05 | Robin's Java World
    @Alexander.Yu
    其實這是參照JSF官方實現來做的,大部分代碼都是原來的官方的代碼,沒有改動,只是改了記LOG的方式和一些關鍵的部分。
      回復  更多評論
      
    # re: JSF深入--控制跳轉 2008-04-01 18:05 | gembin
    關注JSF  回復  更多評論
      
    主站蜘蛛池模板: h视频免费高清在线观看| 亚洲av午夜成人片精品电影| 一级特黄色毛片免费看| 亚洲影视自拍揄拍愉拍| 久久综合日韩亚洲精品色| 亚洲国产天堂久久久久久| 成人黄18免费视频| av无码久久久久不卡免费网站 | 欧美a级成人网站免费| 美女视频黄a视频全免费网站色窝 美女被cao网站免费看在线看 | 亚洲AV无码精品蜜桃| 香蕉蕉亚亚洲aav综合| 国产精品亚洲二区在线观看| 日本特黄a级高清免费大片| 日日摸日日碰夜夜爽亚洲| 亚洲国产一区在线| 亚洲av成人一区二区三区在线观看| 午夜理伦剧场免费| 美女被爆羞羞网站免费| 亚洲日韩中文字幕| MM131亚洲国产美女久久| 毛片免费在线观看网站| 久久青草免费91线频观看不卡 | 亚洲精华国产精华精华液| 亚洲国产精品久久久天堂| 久久亚洲欧洲国产综合| 四虎永久成人免费| 国产免费牲交视频| 免费人成无码大片在线观看| 又黄又爽一线毛片免费观看| 国产免费一区二区三区VR| 四虎影在线永久免费四虎地址8848aa| 四色在线精品免费观看| 免费看的黄色大片| 国产免费啪嗒啪嗒视频看看| 四虎影在线永久免费观看| 亚洲精品国产精品乱码不卞| 国产精品V亚洲精品V日韩精品| 中文字幕人成人乱码亚洲电影 | 亚洲AV无码一区二区乱子仑| 久久亚洲精品高潮综合色a片|