一区二区三区在线-一区二区三区亚洲视频-一区二区三区亚洲-一区二区三区午夜-一区二区三区四区在线视频-一区二区三区四区在线免费观看

服務(wù)器之家:專注于服務(wù)器技術(shù)及軟件下載分享
分類導(dǎo)航

PHP教程|ASP.NET教程|Java教程|ASP教程|編程技術(shù)|正則表達(dá)式|C/C++|IOS|C#|Swift|Android|VB|R語言|JavaScript|易語言|vb.net|

服務(wù)器之家 - 編程語言 - Java教程 - spring boot 1.5.4 集成shiro+cas,實(shí)現(xiàn)單點(diǎn)登錄和權(quán)限控制

spring boot 1.5.4 集成shiro+cas,實(shí)現(xiàn)單點(diǎn)登錄和權(quán)限控制

2020-11-23 11:01追極 Java教程

這篇文章主要介紹了spring boot 1.5.4 集成shiro+cas,實(shí)現(xiàn)單點(diǎn)登錄和權(quán)限控制,需要的朋友可以參考下

1.添加maven依賴(先安裝好cas-server-3.5.2,安裝步驟請查看本文參考文章)

 
?
1
 
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<dependency>
  <groupId>org.apache.shiro</groupId>
  <artifactId>shiro-spring</artifactId>
  <version>1.2.4</version>
</dependency>
<dependency>
  <groupId>org.apache.shiro</groupId>
  <artifactId>shiro-ehcache</artifactId>
  <version>1.2.4</version>
</dependency>
<dependency>
  <groupId>org.apache.shiro</groupId>
  <artifactId>shiro-cas</artifactId>
  <version>1.2.4</version>
</dependency>

2.啟動累添加@ServletComponentScan注解

 
?
1
 
2
3
4
5
6
7
8
9
10
11
12
13
@SpringBootApplication
public class Application {
  /**
   * main function
   * @param args params
   */
  public static void main(String[] args){
    ConfigurableApplicationContext context = SpringApplication.run(Application.class,args);
    //test if a xml bean inject into springcontext successful
    User user = (User)context.getBean("user1");
    System.out.println(JSONObject.toJSONString(user));
  }
}

 3.配置shiro+cas

 
?
1
 
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
package com.hdwang.config.shiroCas;
import com.hdwang.dao.UserDao;
import org.apache.shiro.cache.ehcache.EhCacheManager;
import org.apache.shiro.cas.CasFilter;
import org.apache.shiro.cas.CasSubjectFactory;
import org.apache.shiro.spring.LifecycleBeanPostProcessor;
import org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor;
import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
import org.apache.shiro.web.filter.authc.LogoutFilter;
import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
import org.jasig.cas.client.session.SingleSignOutFilter;
import org.jasig.cas.client.session.SingleSignOutHttpSessionListener;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.boot.web.servlet.ServletListenerRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.Ordered;
import org.springframework.web.filter.DelegatingFilterProxy;
import javax.servlet.Filter;
import javax.servlet.annotation.WebListener;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.Map;
/**
 * Created by hdwang on 2017/6/20.
 * shiro+cas 配置
 */
@Configuration
public class ShiroCasConfiguration {
  private static final Logger logger = LoggerFactory.getLogger(ShiroCasConfiguration.class);
  // cas server地址
  public static final String casServerUrlPrefix = "https://localhost:8443/cas";
  // Cas登錄頁面地址
  public static final String casLoginUrl = casServerUrlPrefix + "/login";
  // Cas登出頁面地址
  public static final String casLogoutUrl = casServerUrlPrefix + "/logout";
  // 當(dāng)前工程對外提供的服務(wù)地址
  public static final String shiroServerUrlPrefix = "http://localhost:8081";
  // casFilter UrlPattern
  public static final String casFilterUrlPattern = "/cas";
  // 登錄地址
  public static final String loginUrl = casLoginUrl + "?service=" + shiroServerUrlPrefix + casFilterUrlPattern;
  // 登出地址
  public static final String logoutUrl = casLogoutUrl+"?service="+shiroServerUrlPrefix;
  // 登錄成功地址
  public static final String loginSuccessUrl = "/home";
  // 權(quán)限認(rèn)證失敗跳轉(zhuǎn)地址
  public static final String unauthorizedUrl = "/error/403.html";
  @Bean
  public EhCacheManager getEhCacheManager() {
    EhCacheManager em = new EhCacheManager();
    em.setCacheManagerConfigFile("classpath:ehcache-shiro.xml");
    return em;
  }
  @Bean(name = "myShiroCasRealm")
  public MyShiroCasRealm myShiroCasRealm(EhCacheManager cacheManager) {
    MyShiroCasRealm realm = new MyShiroCasRealm();
    realm.setCacheManager(cacheManager);
    //realm.setCasServerUrlPrefix(ShiroCasConfiguration.casServerUrlPrefix);
    // 客戶端回調(diào)地址
    //realm.setCasService(ShiroCasConfiguration.shiroServerUrlPrefix + ShiroCasConfiguration.casFilterUrlPattern);
    return realm;
  }
  /**
   * 注冊單點(diǎn)登出listener
   * @return
   */
  @Bean
  public ServletListenerRegistrationBean singleSignOutHttpSessionListener(){
    ServletListenerRegistrationBean bean = new ServletListenerRegistrationBean();
    bean.setListener(new SingleSignOutHttpSessionListener());
//    bean.setName(""); //默認(rèn)為bean name
    bean.setEnabled(true);
    //bean.setOrder(Ordered.HIGHEST_PRECEDENCE); //設(shè)置優(yōu)先級
    return bean;
  }
  /**
   * 注冊單點(diǎn)登出filter
   * @return
   */
  @Bean
  public FilterRegistrationBean singleSignOutFilter(){
    FilterRegistrationBean bean = new FilterRegistrationBean();
    bean.setName("singleSignOutFilter");
    bean.setFilter(new SingleSignOutFilter());
    bean.addUrlPatterns("/*");
    bean.setEnabled(true);
    //bean.setOrder(Ordered.HIGHEST_PRECEDENCE);
    return bean;
  }
  /**
   * 注冊DelegatingFilterProxy(Shiro)
   *
   * @return
   * @author SHANHY
   * @create 2016年1月13日
   */
  @Bean
  public FilterRegistrationBean delegatingFilterProxy() {
    FilterRegistrationBean filterRegistration = new FilterRegistrationBean();
    filterRegistration.setFilter(new DelegatingFilterProxy("shiroFilter"));
    // 該值缺省為false,表示生命周期由SpringApplicationContext管理,設(shè)置為true則表示由ServletContainer管理
    filterRegistration.addInitParameter("targetFilterLifecycle", "true");
    filterRegistration.setEnabled(true);
    filterRegistration.addUrlPatterns("/*");
    return filterRegistration;
  }
  @Bean(name = "lifecycleBeanPostProcessor")
  public LifecycleBeanPostProcessor getLifecycleBeanPostProcessor() {
    return new LifecycleBeanPostProcessor();
  }
  @Bean
  public DefaultAdvisorAutoProxyCreator getDefaultAdvisorAutoProxyCreator() {
    DefaultAdvisorAutoProxyCreator daap = new DefaultAdvisorAutoProxyCreator();
    daap.setProxyTargetClass(true);
    return daap;
  }
  @Bean(name = "securityManager")
  public DefaultWebSecurityManager getDefaultWebSecurityManager(MyShiroCasRealm myShiroCasRealm) {
    DefaultWebSecurityManager dwsm = new DefaultWebSecurityManager();
    dwsm.setRealm(myShiroCasRealm);
//   <!-- 用戶授權(quán)/認(rèn)證信息Cache, 采用EhCache 緩存 -->
    dwsm.setCacheManager(getEhCacheManager());
    // 指定 SubjectFactory
    dwsm.setSubjectFactory(new CasSubjectFactory());
    return dwsm;
  }
  @Bean
  public AuthorizationAttributeSourceAdvisor getAuthorizationAttributeSourceAdvisor(DefaultWebSecurityManager securityManager) {
    AuthorizationAttributeSourceAdvisor aasa = new AuthorizationAttributeSourceAdvisor();
    aasa.setSecurityManager(securityManager);
    return aasa;
  }
  /**
   * CAS過濾器
   *
   * @return
   * @author SHANHY
   * @create 2016年1月17日
   */
  @Bean(name = "casFilter")
  public CasFilter getCasFilter() {
    CasFilter casFilter = new CasFilter();
    casFilter.setName("casFilter");
    casFilter.setEnabled(true);
    // 登錄失敗后跳轉(zhuǎn)的URL,也就是 Shiro 執(zhí)行 CasRealm 的 doGetAuthenticationInfo 方法向CasServer驗(yàn)證tiket
    casFilter.setFailureUrl(loginUrl);// 我們選擇認(rèn)證失敗后再打開登錄頁面
    return casFilter;
  }
  /**
   * ShiroFilter<br/>
   * 注意這里參數(shù)中的 StudentService 和 IScoreDao 只是一個例子,因?yàn)槲覀冊谶@里可以用這樣的方式獲取到相關(guān)訪問數(shù)據(jù)庫的對象,
   * 然后讀取數(shù)據(jù)庫相關(guān)配置,配置到 shiroFilterFactoryBean 的訪問規(guī)則中。實(shí)際項(xiàng)目中,請使用自己的Service來處理業(yè)務(wù)邏輯。
   *
   * @param securityManager
   * @param casFilter
   * @param userDao
   * @return
   * @author SHANHY
   * @create 2016年1月14日
   */
  @Bean(name = "shiroFilter")
  public ShiroFilterFactoryBean getShiroFilterFactoryBean(DefaultWebSecurityManager securityManager, CasFilter casFilter, UserDao userDao) {
    ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();
    // 必須設(shè)置 SecurityManager
    shiroFilterFactoryBean.setSecurityManager(securityManager);
    // 如果不設(shè)置默認(rèn)會自動尋找Web工程根目錄下的"/login.jsp"頁面
    shiroFilterFactoryBean.setLoginUrl(loginUrl);
    // 登錄成功后要跳轉(zhuǎn)的連接
    shiroFilterFactoryBean.setSuccessUrl(loginSuccessUrl);
    shiroFilterFactoryBean.setUnauthorizedUrl(unauthorizedUrl);
    // 添加casFilter到shiroFilter中
    Map<String, Filter> filters = new HashMap<>();
    filters.put("casFilter", casFilter);
    // filters.put("logout",logoutFilter());
    shiroFilterFactoryBean.setFilters(filters);
    loadShiroFilterChain(shiroFilterFactoryBean, userDao);
    return shiroFilterFactoryBean;
  }
  /**
   * 加載shiroFilter權(quán)限控制規(guī)則(從數(shù)據(jù)庫讀取然后配置),角色/權(quán)限信息由MyShiroCasRealm對象提供doGetAuthorizationInfo實(shí)現(xiàn)獲取來的
   *
   * @author SHANHY
   * @create 2016年1月14日
   */
  private void loadShiroFilterChain(ShiroFilterFactoryBean shiroFilterFactoryBean, UserDao userDao){
    /////////////////////// 下面這些規(guī)則配置最好配置到配置文件中 ///////////////////////
    Map<String, String> filterChainDefinitionMap = new LinkedHashMap<String, String>();
    // authc:該過濾器下的頁面必須登錄后才能訪問,它是Shiro內(nèi)置的一個攔截器org.apache.shiro.web.filter.authc.FormAuthenticationFilter
    // anon: 可以理解為不攔截
    // user: 登錄了就不攔截
    // roles["admin"] 用戶擁有admin角色
    // perms["permission1"] 用戶擁有permission1權(quán)限
    // filter順序按照定義順序匹配,匹配到就驗(yàn)證,驗(yàn)證完畢結(jié)束。
    // url匹配通配符支持:? * **,分別表示匹配1個,匹配0-n個(不含子路徑),匹配下級所有路徑
    //1.shiro集成cas后,首先添加該規(guī)則
    filterChainDefinitionMap.put(casFilterUrlPattern, "casFilter");
    //filterChainDefinitionMap.put("/logout","logout"); //logut請求采用logout filter
    //2.不攔截的請求
    filterChainDefinitionMap.put("/css/**","anon");
    filterChainDefinitionMap.put("/js/**","anon");
    filterChainDefinitionMap.put("/login", "anon");
    filterChainDefinitionMap.put("/logout","anon");
    filterChainDefinitionMap.put("/error","anon");
    //3.攔截的請求(從本地數(shù)據(jù)庫獲取或者從casserver獲取(webservice,http等遠(yuǎn)程方式),看你的角色權(quán)限配置在哪里)
    filterChainDefinitionMap.put("/user", "authc"); //需要登錄
    filterChainDefinitionMap.put("/user/add/**", "authc,roles[admin]"); //需要登錄,且用戶角色為admin
    filterChainDefinitionMap.put("/user/delete/**", "authc,perms[\"user:delete\"]"); //需要登錄,且用戶有權(quán)限為user:delete
    //4.登錄過的不攔截
    filterChainDefinitionMap.put("/**", "user");
    shiroFilterFactoryBean.setFilterChainDefinitionMap(filterChainDefinitionMap);
  }
}
 
?
1
 
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
package com.hdwang.config.shiroCas;
import javax.annotation.PostConstruct;
import com.hdwang.dao.UserDao;
import com.hdwang.entity.User;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.cas.CasRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import java.util.HashSet;
import java.util.Set;
/**
 * Created by hdwang on 2017/6/20.
 * 安全數(shù)據(jù)源
 */
public class MyShiroCasRealm extends CasRealm{
  private static final Logger logger = LoggerFactory.getLogger(MyShiroCasRealm.class);
  @Autowired
  private UserDao userDao;
  @PostConstruct
  public void initProperty(){
//   setDefaultRoles("ROLE_USER");
    setCasServerUrlPrefix(ShiroCasConfiguration.casServerUrlPrefix);
    // 客戶端回調(diào)地址
    setCasService(ShiroCasConfiguration.shiroServerUrlPrefix + ShiroCasConfiguration.casFilterUrlPattern);
  }
//  /**
//   * 1、CAS認(rèn)證 ,驗(yàn)證用戶身份
//   * 2、將用戶基本信息設(shè)置到會話中(不用了,隨時可以獲取的)
//   */
//  @Override
//  protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) {
//
//    AuthenticationInfo authc = super.doGetAuthenticationInfo(token);
//
//    String account = (String) authc.getPrincipals().getPrimaryPrincipal();
//
//    User user = userDao.getByName(account);
//    //將用戶信息存入session中
//    SecurityUtils.getSubject().getSession().setAttribute("user", user);
//
//    return authc;
//  }
  /**
   * 權(quán)限認(rèn)證,為當(dāng)前登錄的Subject授予角色和權(quán)限
   * @see 經(jīng)測試:本例中該方法的調(diào)用時機(jī)為需授權(quán)資源被訪問時
   * @see 經(jīng)測試:并且每次訪問需授權(quán)資源時都會執(zhí)行該方法中的邏輯,這表明本例中默認(rèn)并未啟用AuthorizationCache
   * @see 經(jīng)測試:如果連續(xù)訪問同一個URL(比如刷新),該方法不會被重復(fù)調(diào)用,Shiro有一個時間間隔(也就是cache時間,在ehcache-shiro.xml中配置),超過這個時間間隔再刷新頁面,該方法會被執(zhí)行
   */
  @Override
  protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
    logger.info("##################執(zhí)行Shiro權(quán)限認(rèn)證##################");
    //獲取當(dāng)前登錄輸入的用戶名,等價于(String) principalCollection.fromRealm(getName()).iterator().next();
    String loginName = (String)super.getAvailablePrincipal(principalCollection);
    //到數(shù)據(jù)庫查是否有此對象(1.本地查詢 2.可以遠(yuǎn)程查詢casserver 3.可以由casserver帶過來角色/權(quán)限其它信息)
    User user=userDao.getByName(loginName);// 實(shí)際項(xiàng)目中,這里可以根據(jù)實(shí)際情況做緩存,如果不做,Shiro自己也是有時間間隔機(jī)制,2分鐘內(nèi)不會重復(fù)執(zhí)行該方法
    if(user!=null){
      //權(quán)限信息對象info,用來存放查出的用戶的所有的角色(role)及權(quán)限(permission)
      SimpleAuthorizationInfo info=new SimpleAuthorizationInfo();
      //給用戶添加角色(讓shiro去驗(yàn)證)
      Set<String> roleNames = new HashSet<>();
      if(user.getName().equals("boy5")){
        roleNames.add("admin");
      }
      info.setRoles(roleNames);
      if(user.getName().equals("李四")){
        //給用戶添加權(quán)限(讓shiro去驗(yàn)證)
        info.addStringPermission("user:delete");
      }
      // 或者按下面這樣添加
      //添加一個角色,不是配置意義上的添加,而是證明該用戶擁有admin角色
//      simpleAuthorInfo.addRole("admin");
      //添加權(quán)限
//      simpleAuthorInfo.addStringPermission("admin:manage");
//      logger.info("已為用戶[mike]賦予了[admin]角色和[admin:manage]權(quán)限");
      return info;
    }
    // 返回null的話,就會導(dǎo)致任何用戶訪問被攔截的請求時,都會自動跳轉(zhuǎn)到unauthorizedUrl指定的地址
    return null;
  }
}
 
?
1
 
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
package com.hdwang.controller;
import com.hdwang.config.shiroCas.ShiroCasConfiguration;
import com.hdwang.entity.User;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import javax.servlet.http.HttpSession;
/**
 * Created by hdwang on 2017/6/21.
 * 跳轉(zhuǎn)至cas server去登錄(一個入口)
 */
@Controller
@RequestMapping("")
public class CasLoginController {
  /**
   * 一般用不到
   * @param model
   * @return
   */
  @RequestMapping(value="/login",method= RequestMethod.GET)
  public String loginForm(Model model){
    model.addAttribute("user", new User());
//   return "login";
    return "redirect:" + ShiroCasConfiguration.loginUrl;
  }
  @RequestMapping(value = "logout", method = { RequestMethod.GET,
      RequestMethod.POST })
  public String loginout(HttpSession session)
  {
    return "redirect:"+ShiroCasConfiguration.logoutUrl;
  }
}
 
?
1
 
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
package com.hdwang.controller;
import com.alibaba.fastjson.JSONObject;
import com.hdwang.entity.User;
import com.hdwang.service.datajpa.UserService;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.mgt.SecurityManager;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.RequestMapping;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
/**
 * Created by hdwang on 2017/6/19.
 */
@Controller
@RequestMapping("/home")
public class HomeController {
  @Autowired
  UserService userService;
  @RequestMapping("")
  public String index(HttpSession session, ModelMap map, HttpServletRequest request){
//    User user = (User) session.getAttribute("user");
    System.out.println(request.getUserPrincipal().getName());
    System.out.println(SecurityUtils.getSubject().getPrincipal());
    User loginUser = userService.getLoginUser();
    System.out.println(JSONObject.toJSONString(loginUser));
    map.put("user",loginUser);
    return "home";
  }
}

 4.運(yùn)行驗(yàn)證

登錄

訪問:http://localhost:8081/home

跳轉(zhuǎn)至:https://localhost:8443/cas/login?service=http://localhost:8081/cas

輸入正確用戶名密碼登錄跳轉(zhuǎn)回:http://localhost:8081/cas?ticket=ST-203-GUheN64mOZec9IWZSH1B-cas01.example.org

最終跳回:http://localhost:8081/home

登出

訪問:http://localhost:8081/logout

跳轉(zhuǎn)至:https://localhost:8443/cas/logout?service=http://localhost:8081

由于未登錄,又執(zhí)行登錄步驟,所以最終返回https://localhost:8443/cas/login?service=http://localhost:8081/cas

這次登錄成功后返回:http://localhost:8081/

cas server端登出(也行)

訪問:https://localhost:8443/cas/logout

再訪問:http://localhost:8081/home 會跳轉(zhuǎn)至登錄頁,perfect!

以上所述是小編給大家介紹的spring boot 1.5.4 集成shiro+cas,實(shí)現(xiàn)單點(diǎn)登錄和權(quán)限控制,希望對大家有所幫助,如果大家有任何疑問請給我留言,小編會及時回復(fù)大家的。在此也非常感謝大家對服務(wù)器之家網(wǎng)站的支持!

原文鏈接:http://www.cnblogs.com/hdwang/archive/2017/06/22/7064492.html

延伸 · 閱讀

精彩推薦
主站蜘蛛池模板: 激情乱文 | 日韩精品在线视频观看 | 体检小说 | 欧美综合国产精品日韩一 | 亚洲小视频在线 | 久久久91精品国产一区二区 | 星空无限传媒xk8027穆娜 | 日韩欧美一卡二区 | caoporn人人 | www.av色| 无人区1免费完整观看 | 美女福利视频一区二区 | julia ann全部在线hd | 免费在线视频网站 | а天堂中文最新版在线官网视频 | 2022av小四郎的最新地址 | 波多野结衣在线免费观看 | 精品久久久久久久久久久 | 三级伦理影院 | 三级理论在线播放大全 | 亚洲精品久久久打桩机 | 国产1区二区| 羞羞视频动漫 | 第一福利在线观看永久视频 | 4455四色永久免费 | 亚洲第一色视频 | 福利视频一区青娱 | 国产在线麻豆波多野结衣 | 天天做天天爱天天一爽一毛片 | 97热久久免费频精品99国产成人 | 美女全身体光羞羞漫画 | 色综合久久天天综合 | 操岳母逼小说 | 国产在线精品成人一区二区三区 | 日韩国产成人精品视频 | 成人激情 | 成人啪啪漫画全文阅读 | 涩涩国产精品福利在线观看 | 久久热r在线视频精品 | 女子张腿让男人桶免费 | 闺蜜的样子小说安沁在线阅读 |