国产秋霞理论久久久电影-婷婷色九月综合激情丁香-欧美在线观看乱妇视频-精品国avA久久久久久久-国产乱码精品一区二区三区亚洲人-欧美熟妇一区二区三区蜜桃视频

Spring Boot 整合 Spring Security 實戰(zhàn)!

共 46901字,需瀏覽 94分鐘

 ·

2021-04-11 22:40

作者:Sans_

鏈接:juejin.cn/post/6844903974546456590

一、說明

SpringSecurity是一個用于Java 企業(yè)級應(yīng)用程序的安全框架,主要包含用戶認(rèn)證和用戶授權(quán)兩個方面.相比較Shiro而言,Security功能更加的強大,它可以很容易地擴展以滿足更多安全控制方面的需求,但也相對它的學(xué)習(xí)成本會更高,兩種框架各有利弊.實際開發(fā)中還是要根據(jù)業(yè)務(wù)和項目的需求來決定使用哪一種.

JWT是在Web應(yīng)用中安全傳遞信息的規(guī)范,從本質(zhì)上來說是Token的演變,是一種生成加密用戶身份信息的Token,特別適用于分布式單點登陸的場景,無需在服務(wù)端保存用戶的認(rèn)證信息,而是直接對Token進行校驗獲取用戶信息,使單點登錄更為簡單靈活.

更多 Spring Boot 實戰(zhàn)可以關(guān)注公眾號「Java后端」,回復(fù) 666 即可。

二、項目環(huán)境

SpringBoot版本:2.1.6

SpringSecurity版本: 5.1.5

MyBatis-Plus版本: 3.1.0

JDK版本:1.8

數(shù)據(jù)表(SQL文件在項目中): 數(shù)據(jù)庫中測試號的密碼進行了加密,密碼皆為123456:

Maven依賴如下:

<dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <scope>runtime</scope>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
        <!--Security依賴 -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-security</artifactId>
        </dependency>
        <!-- MybatisPlus 核心庫 -->
        <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus-boot-starter</artifactId>
            <version>3.1.0</version>
        </dependency>
        <!-- 引入阿里數(shù)據(jù)庫連接池 -->
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid</artifactId>
            <version>1.1.6</version>
        </dependency>
        <!-- StringUtilS工具 -->
        <dependency>
            <groupId>org.apache.commons</groupId>
            <artifactId>commons-lang3</artifactId>
            <version>3.5</version>
        </dependency>
        <!-- JSON工具 -->
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>fastjson</artifactId>
            <version>1.2.45</version>
        </dependency>
        <!-- JWT依賴 -->
        <dependency>
            <groupId>org.springframework.security</groupId>
            <artifactId>spring-security-jwt</artifactId>
            <version>1.0.9.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>io.jsonwebtoken</groupId>
            <artifactId>jjwt</artifactId>
            <version>0.9.0</version>
        </dependency>
</dependencies>

配置如下:

# 配置端口
server:
  port: 8764
spring:
  # 配置數(shù)據(jù)源
  datasource:
    driver-class-name: com.mysql.cj.jdbc.Driver
    url: jdbc:mysql://localhost:3306/sans_security?serverTimezone=UTC&useUnicode=true&characterEncoding=utf-8&zeroDateTimeBehavior=convertToNull&useSSL=false
    username: root
    password: 123456
    type: com.alibaba.druid.pool.DruidDataSource
# JWT配置
jwt:
  # 密匙KEY
  secret: JWTSecret
  # HeaderKEY
  tokenHeader: Authorization
  # Token前綴字符
  tokenPrefix: Sans-
  # 過期時間 單位秒 1天后過期=86400 7天后過期=604800
  expiration: 86400
  # 配置不需要認(rèn)證的接口
  antMatchers: /index/**,/login/**,/favicon.ico
# Mybatis-plus相關(guān)配置
mybatis-plus:
  # xml掃描,多個目錄用逗號或者分號分隔(告訴 Mapper 所對應(yīng)的 XML 文件位置)
  mapper-locations: classpath:mapper/*.xml
  # 以下配置均有默認(rèn)值,可以不設(shè)置
  global-config:
    db-config:
      #主鍵類型 AUTO:"數(shù)據(jù)庫ID自增" INPUT:"用戶輸入ID",ID_WORKER:"全局唯一ID (數(shù)字類型唯一ID)", UUID:"全局唯一ID UUID";
      id-type: AUTO
      #字段策略 IGNORED:"忽略判斷" NOT_NULL:"非 NULL 判斷") NOT_EMPTY:"非空判斷"
      field-strategy: NOT_EMPTY
      #數(shù)據(jù)庫類型
      db-type: MYSQL
  configuration:
    # 是否開啟自動駝峰命名規(guī)則映射:從數(shù)據(jù)庫列名到Java屬性駝峰命名的類似映射
    map-underscore-to-camel-case: true
    # 返回map時true:當(dāng)查詢數(shù)據(jù)為空時字段返回為null,false:不加這個查詢數(shù)據(jù)為空時,字段將被隱藏
    call-setters-on-nulls: true
    # 這個配置會將執(zhí)行的sql打印出來,在開發(fā)或測試的時候可以用
    log-impl: org.apache.ibatis.logging.stdout.StdOutImpl

三、編寫項目基礎(chǔ)類

Entity,Dao,Service,及等SpringSecurity用戶的Entity,Service類等在這里省略,請參考源碼

編寫JWT工具類

/**
 * JWT工具類
 * @Author Sans
 * @CreateTime 2019/10/2 7:42
 */

@Slf4j
public class JWTTokenUtil {

    /**
     * 生成Token
     * @Author Sans
     * @CreateTime 2019/10/2 12:16
     * @Param  selfUserEntity 用戶安全實體
     * @Return Token
     */

    public static String createAccessToken(SelfUserEntity selfUserEntity){
        // 登陸成功生成JWT
        String token = Jwts.builder()
                // 放入用戶名和用戶ID
                .setId(selfUserEntity.getUserId()+"")
                // 主題
                .setSubject(selfUserEntity.getUsername())
                // 簽發(fā)時間
                .setIssuedAt(new Date())
                // 簽發(fā)者
                .setIssuer("sans")
                // 自定義屬性 放入用戶擁有權(quán)限
                .claim("authorities", JSON.toJSONString(selfUserEntity.getAuthorities()))
                // 失效時間
                .setExpiration(new Date(System.currentTimeMillis() + JWTConfig.expiration))
                // 簽名算法和密鑰
                .signWith(SignatureAlgorithm.HS512, JWTConfig.secret)
                .compact();
        return token;
    }
}

編寫暫無權(quán)限處理類

/**
 * @Description 暫無權(quán)限處理類
 * @Author Sans
 * @CreateTime 2019/10/3 8:39
 */

@Component
public class UserAuthAccessDeniedHandler implements AccessDeniedHandler{
    /**
     * 暫無權(quán)限返回結(jié)果
     * @Author Sans
     * @CreateTime 2019/10/3 8:41
     */

    @Override
    public void handle(HttpServletRequest request, HttpServletResponse response, AccessDeniedException exception){
        ResultUtil.responseJson(response,ResultUtil.resultCode(403,"未授權(quán)"));
    }
}

編寫登錄失敗處理類

/**
 * @Description 登錄失敗處理類
 * @Author Sans
 * @CreateTime 2019/10/3 9:06
 */

@Slf4j
@Component
public class UserLoginFailureHandler implements AuthenticationFailureHandler {
    /**
     * 登錄失敗返回結(jié)果
     * @Author Sans
     * @CreateTime 2019/10/3 9:12
     */

    @Override
    public void onAuthenticationFailure(HttpServletRequest request, HttpServletResponse response, AuthenticationException exception){
        // 這些對于操作的處理類可以根據(jù)不同異常進行不同處理
        if (exception instanceof UsernameNotFoundException){
            log.info("【登錄失敗】"+exception.getMessage());
            ResultUtil.responseJson(response,ResultUtil.resultCode(500,"用戶名不存在"));
        }
        if (exception instanceof LockedException){
            log.info("【登錄失敗】"+exception.getMessage());
            ResultUtil.responseJson(response,ResultUtil.resultCode(500,"用戶被凍結(jié)"));
        }
        if (exception instanceof BadCredentialsException){
            log.info("【登錄失敗】"+exception.getMessage());
            ResultUtil.responseJson(response,ResultUtil.resultCode(500,"用戶名密碼不正確"));
        }
        ResultUtil.responseJson(response,ResultUtil.resultCode(500,"登錄失敗"));
    }
}

編寫登錄成功處理類

/**
 * @Description 登錄成功處理類
 * @Author Sans
 * @CreateTime 2019/10/3 9:13
 */

@Slf4j
@Component
public class UserLoginSuccessHandler implements AuthenticationSuccessHandler {
    /**
     * 登錄成功返回結(jié)果
     * @Author Sans
     * @CreateTime 2019/10/3 9:27
     */

    @Override
    public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication){
        // 組裝JWT
        SelfUserEntity selfUserEntity = (SelfUserEntity) authentication.getPrincipal();
        String token = JWTTokenUtil.createAccessToken(selfUserEntity);
        token = JWTConfig.tokenPrefix + token;
        // 封裝返回參數(shù)
        Map<String,Object> resultData = new HashMap<>();
        resultData.put("code","200");
        resultData.put("msg", "登錄成功");
        resultData.put("token",token);
        ResultUtil.responseJson(response,resultData);
    }
}

編寫登出成功處理類

/**
 * 用戶登出類
 * @Author Sans
 * @CreateTime 2019/10/3 9:42
 */

@Component
public class UserLogoutSuccessHandler implements LogoutSuccessHandler {
    /**
     * 用戶登出返回結(jié)果
     * 這里應(yīng)該讓前端清除掉Token
     * @Author Sans
     * @CreateTime 2019/10/3 9:50
     */

    @Override
    public void onLogoutSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication){
        Map<String,Object> resultData = new HashMap<>();
        resultData.put("code","200");
        resultData.put("msg", "登出成功");
        SecurityContextHolder.clearContext();
        ResultUtil.responseJson(response,ResultUtil.resultSuccess(resultData));
    }
}

四、編寫Security核心類

編寫自定義登錄驗證類

/**
 * 自定義登錄驗證
 * @Author Sans
 * @CreateTime 2019/10/1 19:11
 */

@Component
public class UserAuthenticationProvider implements AuthenticationProvider {
    @Autowired
    private SelfUserDetailsService selfUserDetailsService;
    @Autowired
    private SysUserService sysUserService;
    @Override
    public Authentication authenticate(Authentication authentication) throws AuthenticationException {
        // 獲取表單輸入中返回的用戶名
        String userName = (String) authentication.getPrincipal();
        // 獲取表單中輸入的密碼
        String password = (String) authentication.getCredentials();
        // 查詢用戶是否存在
        SelfUserEntity userInfo = selfUserDetailsService.loadUserByUsername(userName);
        if (userInfo == null) {
            throw new UsernameNotFoundException("用戶名不存在");
        }
        // 我們還要判斷密碼是否正確,這里我們的密碼使用BCryptPasswordEncoder進行加密的
        if (!new BCryptPasswordEncoder().matches(password, userInfo.getPassword())) {
            throw new BadCredentialsException("密碼不正確");
        }
        // 還可以加一些其他信息的判斷,比如用戶賬號已停用等判斷
        if (userInfo.getStatus().equals("PROHIBIT")){
            throw new LockedException("該用戶已被凍結(jié)");
        }
        // 角色集合
        Set<GrantedAuthority> authorities = new HashSet<>();
        // 查詢用戶角色
        List<SysRoleEntity> sysRoleEntityList = sysUserService.selectSysRoleByUserId(userInfo.getUserId());
        for (SysRoleEntity sysRoleEntity: sysRoleEntityList){
            authorities.add(new SimpleGrantedAuthority("ROLE_" + sysRoleEntity.getRoleName()));
        }
        userInfo.setAuthorities(authorities);
        // 進行登錄
        return new UsernamePasswordAuthenticationToken(userInfo, password, authorities);
    }
    @Override
    public boolean supports(Class<?> authentication) {
        return true;
    }
}

編寫自定義PermissionEvaluator注解驗證

/**
 * 自定義權(quán)限注解驗證
 * @Author Sans
 * @CreateTime 2019/10/6 13:31
 */

@Component
public class UserPermissionEvaluator implements PermissionEvaluator {
    @Autowired
    private SysUserService sysUserService;
    /**
     * hasPermission鑒權(quán)方法
     * 這里僅僅判斷PreAuthorize注解中的權(quán)限表達式
     * 實際中可以根據(jù)業(yè)務(wù)需求設(shè)計數(shù)據(jù)庫通過targetUrl和permission做更復(fù)雜鑒權(quán)
     * @Author Sans
     * @CreateTime 2019/10/6 18:25
     * @Param  authentication 用戶身份
     * @Param  targetUrl 請求路徑
     * @Param  permission 請求路徑權(quán)限
     * @Return boolean 是否通過
     */

    @Override
    public boolean hasPermission(Authentication authentication, Object targetUrl, Object permission) {
        // 獲取用戶信息
        SelfUserEntity selfUserEntity =(SelfUserEntity) authentication.getPrincipal();
        // 查詢用戶權(quán)限(這里可以將權(quán)限放入緩存中提升效率)
        Set<String> permissions = new HashSet<>();
        List<SysMenuEntity> sysMenuEntityList = sysUserService.selectSysMenuByUserId(selfUserEntity.getUserId());
        for (SysMenuEntity sysMenuEntity:sysMenuEntityList) {
            permissions.add(sysMenuEntity.getPermission());
        }
        // 權(quán)限對比
        if (permissions.contains(permission.toString())){
            return true;
        }
        return false;
    }
    @Override
    public boolean hasPermission(Authentication authentication, Serializable targetId, String targetType, Object permission) {
        return false;
    }
}

編寫SpringSecurity核心配置類

/**
 * SpringSecurity核心配置類
 * @Author Sans
 * @CreateTime 2019/10/1 9:40
 */

@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true) //開啟權(quán)限注解,默認(rèn)是關(guān)閉的
public class SecurityConfig extends WebSecurityConfigurerAdapter {
    /**
     * 自定義登錄成功處理器
     */

    @Autowired
    private UserLoginSuccessHandler userLoginSuccessHandler;
    /**
     * 自定義登錄失敗處理器
     */

    @Autowired
    private UserLoginFailureHandler userLoginFailureHandler;
    /**
     * 自定義注銷成功處理器
     */

    @Autowired
    private UserLogoutSuccessHandler userLogoutSuccessHandler;
    /**
     * 自定義暫無權(quán)限處理器
     */

    @Autowired
    private UserAuthAccessDeniedHandler userAuthAccessDeniedHandler;
    /**
     * 自定義未登錄的處理器
     */

    @Autowired
    private UserAuthenticationEntryPointHandler userAuthenticationEntryPointHandler;
    /**
     * 自定義登錄邏輯驗證器
     */

    @Autowired
    private UserAuthenticationProvider userAuthenticationProvider;
    
    /**
     * 加密方式
     * @Author Sans
     * @CreateTime 2019/10/1 14:00
     */

    @Bean
    public BCryptPasswordEncoder bCryptPasswordEncoder(){
        return new BCryptPasswordEncoder();
    }
    /**
     * 注入自定義PermissionEvaluator
     */

    @Bean
    public DefaultWebSecurityExpressionHandler userSecurityExpressionHandler(){
        DefaultWebSecurityExpressionHandler handler = new DefaultWebSecurityExpressionHandler();
        handler.setPermissionEvaluator(new UserPermissionEvaluator());
        return handler;
    }
    
    /**
     * 配置登錄驗證邏輯
     */

    @Override
    protected void configure(AuthenticationManagerBuilder auth){
        //這里可啟用我們自己的登陸驗證邏輯
        auth.authenticationProvider(userAuthenticationProvider);
    }
    /**
     * 配置security的控制邏輯
     * @Author Sans
     * @CreateTime 2019/10/1 16:56
     * @Param  http 請求
     */

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.authorizeRequests()
                //不進行權(quán)限驗證的請求或資源(從配置文件中讀取)
               .antMatchers(JWTConfig.antMatchers.split(",")).permitAll()
                //其他的需要登陸后才能訪問
                .anyRequest().authenticated()
                .and()
                //配置未登錄自定義處理類
                .httpBasic().authenticationEntryPoint(userAuthenticationEntryPointHandler)
                .and()
                //配置登錄地址
                .formLogin()
                .loginProcessingUrl("/login/userLogin")
                //配置登錄成功自定義處理類
                .successHandler(userLoginSuccessHandler)
                //配置登錄失敗自定義處理類
                .failureHandler(userLoginFailureHandler)
                .and()
                //配置登出地址
                .logout()
                .logoutUrl("/login/userLogout")
                //配置用戶登出自定義處理類
                .logoutSuccessHandler(userLogoutSuccessHandler)
                .and()
                //配置沒有權(quán)限自定義處理類
                .exceptionHandling().accessDeniedHandler(userAuthAccessDeniedHandler)
                .and()
                // 開啟跨域
                .cors()
                .and()
                // 取消跨站請求偽造防護
                .csrf().disable();
        // 基于Token不需要session
        http.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS);
        // 禁用緩存
        http.headers().cacheControl();
        // 添加JWT過濾器
        http.addFilter(new JWTAuthenticationTokenFilter(authenticationManager()));
    }
}

五、編寫JWT攔截類

編寫JWT接口請求校驗攔截器

/**
 * JWT接口請求校驗攔截器
 * 請求接口時會進入這里驗證Token是否合法和過期
 * @Author Sans
 * @CreateTime 2019/10/5 16:41
 */

@Slf4j
public class JWTAuthenticationTokenFilter extends BasicAuthenticationFilter {
    public JWTAuthenticationTokenFilter(AuthenticationManager authenticationManager) {
        super(authenticationManager);
    }
    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
        // 獲取請求頭中JWT的Token
        String tokenHeader = request.getHeader(JWTConfig.tokenHeader);
        if (null!=tokenHeader && tokenHeader.startsWith(JWTConfig.tokenPrefix)) {
            try {
                // 截取JWT前綴
                String token = tokenHeader.replace(JWTConfig.tokenPrefix, "");
                // 解析JWT
                Claims claims = Jwts.parser()
                        .setSigningKey(JWTConfig.secret)
                        .parseClaimsJws(token)
                        .getBody();
                // 獲取用戶名
                String username = claims.getSubject();
                String userId=claims.getId();
                if(!StringUtils.isEmpty(username)&&!StringUtils.isEmpty(userId)) {
                    // 獲取角色
                    List<GrantedAuthority> authorities = new ArrayList<>();
                    String authority = claims.get("authorities").toString();
                    if(!StringUtils.isEmpty(authority)){
                        List<Map<String,String>> authorityMap = JSONObject.parseObject(authority, List.class);
                        for(Map<String,String> role : authorityMap){
                            if(!StringUtils.isEmpty(role)) {
                                authorities.add(new SimpleGrantedAuthority(role.get("authority")));
                            }
                        }
                    }
                    //組裝參數(shù)
                    SelfUserEntity selfUserEntity = new SelfUserEntity();
                    selfUserEntity.setUsername(claims.getSubject());
                    selfUserEntity.setUserId(Long.parseLong(claims.getId()));
                    selfUserEntity.setAuthorities(authorities);
                    UsernamePasswordAuthenticationToken authentication = new UsernamePasswordAuthenticationToken(selfUserEntity, userId, authorities);
                    SecurityContextHolder.getContext().setAuthentication(authentication);
                }
            } catch (ExpiredJwtException e){
                log.info("Token過期");
            } catch (Exception e) {
                log.info("Token無效");
            }
        }
        filterChain.doFilter(request, response);
        return;
    }
}

六、權(quán)限注解和hasPermission權(quán)限擴展

Security允許我們在定義URL方法訪問所應(yīng)有的注解權(quán)限時使用SpringEL表達式,在定義所需的訪問權(quán)限時如果對應(yīng)的表達式返回結(jié)果為true則表示擁有對應(yīng)的權(quán)限,反之則沒有權(quán)限,會進入到我們配置的UserAuthAccessDeniedHandler(暫無權(quán)限處理類)中進行處理.這里舉一些例子,代碼中注釋有對應(yīng)的描述。

表達式

/**
     * 管理端信息
     * @Author Sans
     * @CreateTime 2019/10/2 14:22
     * @Return Map<String,Object> 返回數(shù)據(jù)MAP
     */

    @PreAuthorize("hasRole('ADMIN')")
    @RequestMapping(value = "/info",method = RequestMethod.GET)
    public Map<String,Object> userLogin(){
        Map<String,Object> result = new HashMap<>();
        SelfUserEntity userDetails = SecurityUtil.getUserInfo();
        result.put("title","管理端信息");
        result.put("data",userDetails);
        return ResultUtil.resultSuccess(result);
    }
    /**
     * 擁有ADMIN或者USER角色可以訪問
     * @Author Sans
     * @CreateTime 2019/10/2 14:22
     * @Return Map<String,Object> 返回數(shù)據(jù)MAP
     */

    @PreAuthorize("hasAnyRole('ADMIN','USER')")
    @RequestMapping(value = "/list",method = RequestMethod.GET)
    public Map<String,Object> list(){
        Map<String,Object> result = new HashMap<>();
        List<SysUserEntity> sysUserEntityList = sysUserService.list();
        result.put("title","擁有用戶或者管理員角色都可以查看");
        result.put("data",sysUserEntityList);
        return ResultUtil.resultSuccess(result);
    }
    /**
     * 擁有ADMIN和USER角色可以訪問
     * @Author Sans
     * @CreateTime 2019/10/2 14:22
     * @Return Map<String,Object> 返回數(shù)據(jù)MAP
     */

    @PreAuthorize("hasRole('ADMIN') and hasRole('USER')")
    @RequestMapping(value = "/menuList",method = RequestMethod.GET)
    public Map<String,Object> menuList(){
        Map<String,Object> result = new HashMap<>();
        List<SysMenuEntity> sysMenuEntityList = sysMenuService.list();
        result.put("title","擁有用戶和管理員角色都可以查看");
        result.put("data",sysMenuEntityList);
        return ResultUtil.resultSuccess(result);
    }

通常情況下使用hasRole和hasAnyRole基本可以滿足大部分鑒權(quán)需求,但是有時候面對更復(fù)雜的場景上述常規(guī)表示式無法完成權(quán)限認(rèn)證,Security也為我們提供了解決方案.通過hasPermission()來擴展表達式.使用hasPermission()首先要實現(xiàn)PermissionEvaluator接口

/**
 * 自定義權(quán)限注解驗證
 * @Author Sans
 * @CreateTime 2019/10/6 13:31
 */

@Component
public class UserPermissionEvaluator implements PermissionEvaluator {
    @Autowired
    private SysUserService sysUserService;
    /**
     * hasPermission鑒權(quán)方法
     * 這里僅僅判斷PreAuthorize注解中的權(quán)限表達式
     * 實際中可以根據(jù)業(yè)務(wù)需求設(shè)計數(shù)據(jù)庫通過targetUrl和permission做更復(fù)雜鑒權(quán)
     * 當(dāng)然targetUrl不一定是URL可以是數(shù)據(jù)Id還可以是管理員標(biāo)識等,這里根據(jù)需求自行設(shè)計
     * @Author Sans
     * @CreateTime 2019/10/6 18:25
     * @Param  authentication 用戶身份(在使用hasPermission表達式時Authentication參數(shù)默認(rèn)會自動帶上)
     * @Param  targetUrl 請求路徑
     * @Param  permission 請求路徑權(quán)限
     * @Return boolean 是否通過
     */

    @Override
    public boolean hasPermission(Authentication authentication, Object targetUrl, Object permission) {
        // 獲取用戶信息
        SelfUserEntity selfUserEntity =(SelfUserEntity) authentication.getPrincipal();
        // 查詢用戶權(quán)限(這里可以將權(quán)限放入緩存中提升效率)
        Set<String> permissions = new HashSet<>();
        List<SysMenuEntity> sysMenuEntityList = sysUserService.selectSysMenuByUserId(selfUserEntity.getUserId());
        for (SysMenuEntity sysMenuEntity:sysMenuEntityList) {
            permissions.add(sysMenuEntity.getPermission());
        }
        // 權(quán)限對比
        if (permissions.contains(permission.toString())){
            return true;
        }
        return false;
    }
    @Override
    public boolean hasPermission(Authentication authentication, Serializable targetId, String targetType, Object permission) {
        return false;
    }
}

在請求方法上添加hasPermission示例

/**
     * 擁有sys:user:info權(quán)限可以訪問
     * hasPermission 第一個參數(shù)是請求路徑 第二個參數(shù)是權(quán)限表達式
     * @Author Sans
     * @CreateTime 2019/10/2 14:22
     * @Return Map<String,Object> 返回數(shù)據(jù)MAP
     */

    @PreAuthorize("hasPermission('/admin/userList','sys:user:info')")
    @RequestMapping(value = "/userList",method = RequestMethod.GET)
    public Map<String,Object> userList(){
        Map<String,Object> result = new HashMap<>();
        List<SysUserEntity> sysUserEntityList = sysUserService.list();
        result.put("title","擁有sys:user:info權(quán)限都可以查看");
        result.put("data",sysUserEntityList);
        return ResultUtil.resultSuccess(result);
    }

hasPermission可以也可以和其他表達式聯(lián)合使用

/**
     * 擁有ADMIN角色和sys:role:info權(quán)限可以訪問
     * @Author Sans
     * @CreateTime 2019/10/2 14:22
     * @Return Map<String,Object> 返回數(shù)據(jù)MAP
     */

    @PreAuthorize("hasRole('ADMIN') and hasPermission('/admin/adminRoleList','sys:role:info')")
    @RequestMapping(value = "/adminRoleList",method = RequestMethod.GET)
    public Map<String,Object> adminRoleList(){
        Map<String,Object> result = new HashMap<>();
        List<SysRoleEntity> sysRoleEntityList = sysRoleService.list();
        result.put("title","擁有ADMIN角色和sys:role:info權(quán)限可以訪問");
        result.put("data",sysRoleEntityList);
        return ResultUtil.resultSuccess(result);
    }

七、測試

創(chuàng)建賬戶這里用戶加密使用了Security推薦的bCryptPasswordEncoder方法

/**
     * 注冊用戶
     */

    @Test
    public void contextLoads() 
{
        // 注冊用戶
        SysUserEntity sysUserEntity = new SysUserEntity();
        sysUserEntity.setUsername("sans");
        sysUserEntity.setPassword(bCryptPasswordEncoder.encode("123456"));
        // 設(shè)置用戶狀態(tài)
        sysUserEntity.setStatus("NORMAL");
        sysUserService.save(sysUserEntity);
        // 分配角色 1:ADMIN 2:USER
        SysUserRoleEntity sysUserRoleEntity = new SysUserRoleEntity();
        sysUserRoleEntity.setRoleId(2L);
        sysUserRoleEntity.setUserId(sysUserEntity.getUserId());
        sysUserRoleService.save(sysUserRoleEntity);
    }

登錄USER角色賬號,登錄成功后我們會獲取到身份認(rèn)證的Token

訪問USER角色的接口,把上一步獲取到的Token設(shè)置在Headers中,Key為Authorization,我們之前實現(xiàn)的JWTAuthenticationTokenFilter攔截器會根據(jù)請求頭中的Authorization獲取并解析Token

使用USER角色Token訪問ADMIN角色的接口,會被拒絕,告知未授權(quán)(暫無權(quán)限會進入我們定義的UserAuthAccessDeniedHandler這個類進行處理)

更換ADMIN角色進行登錄并訪問ADMIN接口

八.項目源碼

碼云:gitee.com/liselotte/spring-boot-security-demo

GitHub:github.com/xuyulong2017/my-java-demo


點擊閱讀全文前往微服務(wù)電商教程
瀏覽 66
點贊
評論
收藏
分享

手機掃一掃分享

分享
舉報
評論
圖片
表情
推薦
點贊
評論
收藏
分享

手機掃一掃分享

分享
舉報

感谢您访问我们的网站,您可能还对以下资源感兴趣:

国产秋霞理论久久久电影-婷婷色九月综合激情丁香-欧美在线观看乱妇视频-精品国avA久久久久久久-国产乱码精品一区二区三区亚洲人-欧美熟妇一区二区三区蜜桃视频 校园春色亚洲色图| 嘿嘿av| 日本少妇BBW| 神马午夜精品95| 亚洲成人无码视频在线观看| 婷婷精品视频| 欧美一级片免费观看| 黄骗免费网站| 亚州黄色电影| 日韩操B视频| 黄色av影院| 成人免费A片喷| 波多野结衣视频在线播放| 日本一级黄| 色九九九| 成人黄色免费在线| 久热精品视频在线观看| 日韩1区2区| 黄色成人在线视频| 免费在线观看AV片| 亚洲热视频| 日韩在线成人中文字幕亚洲| 少妇视频| 中文字幕在线码| 青娱乐国产在线| 日韩欧美亚洲一区二区三区| 国产有码| 夸克看成人片一级A片| 国产无遮挡又黄又爽又色学生软件| 日韩日韩日韩日韩日韩| 狠狠网| 在线播放www| 亚洲四区| 精品视频在线观看免费| 国产浮力草草| 亚洲AV无码精品成人| 国产精品探花熟女AV| 日韩一区在线视频| 久久草视频在线播放| a网站在线观看| 高清无码内射视频| 国产suv精品一区二区6| 青青免费在线视频| 91视频美女模特| 逼特逼视频在线| 成人毛片18毛片女人| 丁香五月激情五月| 黄色视频网站观看| 天天干天天操| 一本大道东京热AV| 日韩三级在线免费观看| av片在线免费观看| 国产日逼片| 欧美日屄| 97人人色| 日韩人妻精品一区二区| 99免费在线观看| 激情丁香五月婷婷| 国产亚洲久一区二区| 色婷婷激情视频| 天堂在线观看AV| 99久久99九九99九九九| 久草免费福利| 日本久久久久久久久视频在线观看| 久久污| 色就是亚洲| 日韩av电影在线观看| 亚洲午夜久久久久久久久| 俺来也官网欧美久久精品| 一区二区三区无码免费| 欧美性爱AAA| 亚洲免费婷婷| 无码秘人妻一区二区三-百度| 久久亚洲AV无码午夜麻豆| 国产黄片免费观看| 熟女人妻在线观看| 北岛玲视频在线| 亚洲无码影音先锋| 四虎AV在线| 白嫩无码| 天天干天天操天天| 无码秘人妻一区二区三-百度| 三级乱伦视频| 男人天堂网站| 亚洲乱伦中文字幕| 人人看人人艹| 黄色操逼网站| 欧美A在线| 人人干超碰| 国产高清做爱免费在线视频| 色午夜| 日韩精品成人免费观看视频 | 狠狠干狠狠艹| 中文成人在线| 国产成人精品在线观看| 亚洲精品久久久久久久久豆丁网| 日本成人一区二区| а√天堂中文最新版8| 边摸边操| 国产AV直播| 逼逼爱插插网站| 加勒比色综合| 国产又爽又黄免费网站在线| 午夜在线无码| 亚洲国产一区二区在线| 特级特黄AAAAAAAA片| 欧美亚洲自拍偷拍| 久久超碰99| 免费看一级高潮毛片| 天天日天天干天天日| 天天干国产| 97色色网站| 狠狠躁日日躁夜夜躁A片视频| 精品人无码一区二区三区下载| 99久久婷婷国产综合精品hsex | 亚洲无码成人片| 日本69AV| 国产一级AA片| 天天玩夜夜玩天天玩国产99 | 日韩成人无码人妻| 成人片毛片| 亚洲黄色在线播放| 日韩欧美日本| 97超碰人人| 黄片无遮挡| 成人精品一区日本无码网站suv/ | 成人毛片100免费观看| 日韩免费精品视频| 老熟女网站| 日日撸视频| 香蕉福利视频| 国产成人av在线| 欧美内射网站| 亚洲一级黄色大片| 操美女的网站| 男女怕怕网站| 日韩高清国产一区在线| 操逼的网站| 狠狠色丁香| 亚洲成人在线无码| 欧美成人三级在线播放| 日韩天堂在线播放| 日韩操大屌| 国产成人久久| 人人爽人人爽人人爽| x88AV吊钟奶熟女| h片网站在线观看| 91aV视频| 日韩中文字幕一区二区| 99久久婷婷国产综合精品青牛牛 | 无码乱伦| 狠久久| 岛国免费av| 草逼视频网| 日韩高清无码三级片| 99re国产视频| 国产成人精品无码片子的价格| 嫩草久久| 成人免费无码A片免费| 韩国日本美国免费毛片| 成人无码视频| 亚洲欧美久久| 在线观看91| 激情动态视频| 欧美熟妇精品黑人巨大一二三区| 波多野结衣一二三区| 国产久久性爱| 无码一区二区区| 91国产免费视频| 最新中文字幕在线播放| 精品AV无码一区二区三区| 亚洲成人中文字幕| 黄片www| 日逼无码| 自拍偷拍综合| 双飞少妇| 少妇特黄A一区二区三区| 亚洲无码网址| 色五月天婷婷| 日本A片免费看| 狼人狠狠干| 色情电影网站| 天天爽夜夜爽人人爽| 好逼123| 黄色视频在线观看网站| 91视频亚洲| 成人在线三级片| 国产精品色色| 国产欧美日韩在线视频| 亚洲无码AV在线观看| 亚洲中文字幕免费观看| 日韩人妻无码一区二区| 亚洲高清无码免费| 久久这里有精品视频| 午夜亚洲视频| 国产一级a毛片| 一个色综合网| 黄片www| 中文字幕在线欧美| 成人五区| 老太色HD色老太HD| 狠狠撸视频| 91人妻无码一区二区久久| 中文字幕性爱电影| 91av久久| 国产成人AV网站| 91精品综合久久久久久五月丁香| 国产aaaaaaaaaaaaa| 亚洲精品视频免费在线观看| 久久99嫩草熟妇人妻蜜臀| 天天干天天操天天射| 麻豆精品传媒国产剧的特点 | 国内自拍2025| 韩国无码一区二区| 91免费在线看| 国产乱妇乱子伦视频免费观看| 91夜夜夜| 国产操骚逼| 超碰天天爱| 欧美日韩一区二区三区| 天天夜夜狠狠| 探花在线综合| 中文字幕日韩在线观看| 国产精品久久久久久久免牛肉蒲 | 欧美一级特黄真人做受| 水果派中文解说AⅤ| 一级免费黄片| 日韩一级无码毛片| 青娱乐网站| 一级日逼片| 免费高清无码| 国产无码操逼视频| 乱子伦国产精品一区二区| 日韩无码中文字幕| 欧美成人中文字幕| 国內精品久久久久久久| 亚洲一区二区三区在线| 国产乱伦不卡| 成人综合娱乐网| 亚洲欧美国产视频| AV无码在线观看| 91成人免费在线观看| 日本精品黄色| 囯产精品宾馆在线精品酒店| 天天撸免费视频| 怡春院视频| 午夜AV无码| 狠狠爱av| 亚洲黄色Av| 天天撸天天干| 日本视频网| 男人天堂视频在线| 一道本高清无码| 轻轻操内射无码| 欧美粗大| 日韩v在线| 亚洲AV在线人妻| 激情小视频在线观看| 日韩毛片在线播放| 日韩理论片| 中文一区在线观看| 婷婷五月丁香花| 人妻人玩| 成年人视频网| 日韩人妻在线视频| 操逼AⅤ| 一本色道久久无码人妻精品69| av超碰| brazzers疯狂作爱| 亚洲色青| 日韩十八禁| A片久久| 41ts午夜福利| 午夜精品秘一区二区三区| AV在线大香蕉| 日韩精品人妻无码| 日本爱爱视频| 1000部毛片A片免费视频| 肉乳无码A片av| 六月丁香欧美综合| 操逼爽| 五月丁香中文字幕| 欧美日韩岛国| 国产精品粉嫩福利在线| 青青草原av| 超碰在线图片| 日韩高清无码电影| 蜜臀久久99精品久久一区二区 | 九一成人电影| 日韩中文字幕无码| 婷婷丁香花| 亚洲天堂在线观看免费| ⅴA日本成人| www亚洲视频| 女人的天堂av| 性性性性性XXXXX| 亚洲AV无码乱码国产精品蜜芽| 亚洲图片激情乱伦小说| 成人网站www污污污网站公司 | 91人妻无码成人精品一区二区| www五月天com| 夜操| 韩剧《邻居的妻子》电视剧 | 一级片在线视频| 国产精品色情A级片| 免费观看高清无码| 亚洲国产成人精品女人| 色资源在线观看| 中文字幕在线有码| 欧美成人福利视频| 91成人国产| 国产精品怡红院有限公司| 欧美三级理论片| AV在线免费播放| 亚洲AV无码乱码国产| 成人小说在线观看| 五月天激情啪啪| 国产棈品久久久久久久久久九秃| 精品国产一区二区三区性色AV| 午夜啪啪视频| 三级视频在线观看| 国产精品你懂得| 91av在线看| 91嫖妓站街按店老熟女| 蜜臀999| AV婷婷在线| 蜜芽成人在线| 亚洲精品一区二区三区四区高清| 色色婷婷五月| 欧美AAAAAA视频| 不卡无线在一区| 91探花足浴店按摩店| 亚洲精品久久久久毛片A级绿茶 | 东京热精品| 国产精品在线免费观看| 成人一级电影| 年轻女教师高潮2| 亚洲天堂精品在线观看| 欧美日韩a片| 国产VA| 在线观看免费人成视频| 人人妻人人操人人| 岛国免费视频| 视色网| 韩国成人免费无码免费视频| 欧美激情亚洲| 五月丁香色色网| 日本爱爱小视频| xxxx亚洲| 欧美精品久久久久| 91精品国产亚洲| 日韩中文欧美| 一级黄片在线| 欧美日韩A| 国产精品美女久久久| 99免费在线观看| 香蕉福利网| 91精品久久香蕉国产线看观看| 嫩草在线播放| 99色| 日韩在线成人中文字幕亚洲| 91视频播放| 日韩,变态,另类,中文,人妻| 伊人午夜| 少妇搡BBBB搡BBB搡造水多/ | 青青青草视频在线| 国产一毛a一毛a在线观看| 欧美精品区| 91精品国产综合久久久蜜臀粉嫩 | 狼友无码| 大色鬼在线天堂精品| 三级三级久久三级久久18| 看A片在线| 国产人成一区二区三区影院| 韩国无码高清视频| 免费无码AV| 尤物av在线| 国产熟妇婬乱A片免费看牛牛| 爱搞搞就要爱搞搞| 欧美一级特黄A片免费看视频小说 东北嫖老熟女一区二区视频网站 国产丨熟女丨国产熟女视频 | 亚洲一二三| 国产一级片电影| 欧美国产日韩综合在线观看170| 777.av| 亚洲福利天堂| 天堂在线中文| 狼友在线播放| 国产成人AV片| 亚洲大片在线观看| 在线不卡免费Av| 国产99久久九九精品无码免费| 人人操人人超碰| 亚洲高清无码在线播放| 精品欧美无人区乱码毛片| 亚洲精品mv| 91av免费在线观看| 国产欧美精品在线观看| 中文字幕av一区二区| 亚洲欧洲在线播放| 7777影视电视剧在线观看官网| 91麻豆成人精品国产| 久久视频精品| 亚洲免费小电影| 国产亚洲久一区二区^_^| 天天爱av| 黄色免费网站| 最新中文字幕在线观看视频| 日本无码久久嗯啊流水| 国产视频福利在线| 思思精品视频| 91麻豆精品传媒国产| 久久久久亚洲AV无码专区| 日本18禁网站| 三级无码片| www.青青草视频| 亚洲电影无码| 西西午夜视频| 不卡视频在线| 久久久波多野结衣| 国产香蕉视频| 精品久久一区二区| 成人a片在线免费观看| 精品视频久久久| 欧美精品成人网站| 日韩福利视频| 亚洲高清成人| 444444免费高清在线观看电视剧的注意| 久久久亚洲无码精品| 天堂av中文字幕| 欧美日韩高清在线| 88无码| 高颜值呻吟给力| 亚洲热视频在线观看| 91精品人妻一区二区三区| 无码A级片| 狠狠操一区| 亚洲成人性爱网| 婷婷午夜福利| 久久99精品国产麻豆婷婷洗澡| 天天日天天射天天操| 色色网站在线观看| 国产欧美综合视频一区二区在线| 91露脸熟女四川熟女在线观看| 无码av高清| 亚洲天堂视频在线观看| 黄色网页在线免费观看| 欧美成人综合一区| 久久精品一区| 亚洲性爱一区二区| 九九九网站| 欧洲尤物不卡播放六区| 亚洲无码一区二区三区| 亚洲在线资源| 久久99精品久久久久婷婷| www.一区二区三区| 亚洲网站免费观看| 国产成人高清在线| 久草综合视频| 性生活无码| 老鸭窝久久久| 日本不卡在线| 亚洲三级黄色视频| 中文字幕人妻丝袜二区电影| 色94色.欧美.setu| 亚洲色情在线观看| 韩国一区二区三区| 99热精品久久| 国产无码毛片| 国产免费高清视频| 超碰人人爱人人操| 亚洲精品乱码久久久久久按摩观| 成人免费在线观看| 亚洲精品久久久久毛片A级绿茶 | www.在线播放| 国产在线小电影| 成人无码免费看| jizz免费观看| 日韩黄色片| 一级片免费视频| 日本电影一区二区三区| 日韩av中文字幕在线播放| 亚洲天堂成人| 国产av毛片| 深夜福利一区二区| 好吊一区二区| 先锋无码| 成人黄色视频免费| 日韩免费高清无码视频| 看毛片视频| 亚洲免费在线观看视频| 亚洲成人五月天| 色哟哟视频| 国产精品久久久久久久久久二区三区 | A级黄色电影| 国产AⅤ无码一区二区| 国产变态另类| 苍井空一区| 五月丁香综合在线| 亚洲无码1| 夜夜操夜夜操| 免费无码毛片| 五月天丁香网| 91嫖妓站街按店老熟女| 无码不卡一区| 中文有码| 中文字幕一区二区三区四虎在线| 超碰福利在线| 在线免费中文字幕| 无码婬片A片AAA毛片艳谭| 人人干人人摸| 久久婷婷国产| 欧美成人午夜福利| 免费无码国产在线55| 黄色一级电影网| 蜜桃av秘一区二区三区| 18禁在线播放| 狠狠五月| 国产99久久九九精品无码免费| 在线男人天堂| 日韩欧美a片| 免费一级婬片AA片观看| 91人人妻| 激情国产在线| 国产乱伦对白| 国产男人天堂| 亚洲AV电影在线| 丰满少妇一级片| 综合久久99| 日本大香蕉视频| 亚洲高清无码在线视频| 成人免费网站黄| 久久久永久免费视频| 在线观看黄片网站| 午夜黄片| 国产一级二级三级| 久久91欧美特黄A片| 成人电影无码| 黄色动漫在线免费观看| 波多野结衣AV网站| 边吃奶边做爱| 亚洲综合在线视频| 亚洲一区在线视频| 欧美成人版| 大地99中文在线观看| 婷婷五月国产| 精品1区2区| 狠狠色噜噜狠狠狠7777米奇网| 久久欧洲成人精品无码区| 四虎精品一区二区三区| 日韩中文字幕有码| 亚洲激情四射| 韩国三级HD久久精品HD| 国产免费观看视频| 成人做爰100片免费视频| 久久久久少妇| 亚洲高清无码久久| 日韩小视频| 亚色天堂| 国产免费一区二区| 日本A片在线播放| 欧美日韩国产激情| 欧美A片免费| 亚洲婷婷AV| 亚洲欧美91| 欧美婷婷五月| 中文字幕在线观看福利视频| 中文字幕综合网| 边摸边做| 刘玥91精一区二区三区| 在线精品福利| 中文字幕一二三区| 久久成人无码| 日韩一| 欧美色图在线观看视频| 91在线无码精品秘软件| 婷婷开心色四房播播免费| 老女人操逼| 亚洲在线免费视频| 色色五月婷婷| 四虎成人视频| 国产精品视频免费看| 亚洲视频免费在线播放| 天天操天天射天天日| 国产一级片电影| 黄色福利视频在线观看| 欧美一级三级| 久久久老熟女一区二区三区91| 中午字幕在线观看| 特级毛片AAAAAA蜜桃| 国产黄色不卡| 内射视频网站| 久久中文网| 夜夜操夜夜爽| 欧美男人天堂| 久久性爱网| 黄片视频在线免费观看| 久久成人导航| 色先锋av| 日韩中文无| 日本中文字幕免费| 日本乱伦网| 国产精品高| 天天精品视频| 国产在线色| 男人天堂视频在线| 日日夜夜无码| 亚洲成人高清在线| 欧一美一婬一伦一区二区三区 | 色婷婷官网| 中文字幕乱码视频32| 最近中文字幕在线视频| 国产AV18岁| 蜜桃av.38| 日韩高清国产一区在线| 波多野结衣AV在线| 嫩草在线观看| 亚洲高清无码免费| 久久高清免费视频| 樱桃码一区二区三区| 国产成人精品在线观看| 先锋影音在线资源| 操碰97| 拍拍视频| 九九热精品在线| 天天干视频| 免费在线观看黄色视频| 唐山熟女工棚嗷嗷叫| 黑人毛片| 欧美精产国品一二三产品在哪买| 江苏妇搡BBBB搡BBBB小说| 成人一级电影| 成人在线免费视频观看| 欧美视频在线观看免费| 久久综合中文字幕| 无码一区在线观看| 日韩视频在线观看免费| 日批视频网站| 三级片在线看| 一区二区三区不卡视频| 欧美三级片视频| 亚洲一区二区无码| 天天操综合网| 91福利在线观看| 日本东京热视频| 婷婷色777777| 久久香蕉综合在线| 国产性交网站| 黄色3A片在线观看| 日韩乱伦毛片| 偷窥丶亚洲丶熟女| 免费黄色Av| 加勒比一区二区| 四虎影院最新地址| 九九re精品视频在线观看| 六十路老熟女码视频| 欧美成人精品激情在线观看| 欧美一级免费A片| 国产亚洲精品成人a| 一本加勒比HEZYO东京热无码 | av在线一区二区三区| 蜜桃传媒视频| 亚洲无码精品一区二区三区| 日韩美女在线| 成人首页| 久久AV影院| 人人澡人人干| 国产理论电影| 自拍偷拍综合| 国产乱子伦-区二区三区| 丁香五月天婷婷| 亚洲美女喷水视频| 国产精品久久久久久久久A| 国产AV网| 视频國产在线| 日韩亚洲在线视频| 操逼视频一级| 亚洲男人的天堂AV| 亚洲不卡中文字幕| 韩日中文字幕| 国产精品久久久久久亚洲影视| 午夜精品久久久久久久| 国产精品操逼视频| 性爱综合网| 骚逼视频聊天记录| 精品黄色毛片| 五月丁香视频在线| 婷婷成人在线| 丰满人妻一区二区三区四区不卡| 老太婆擦BBBB撩BBBB| 男人的天堂手机在线| 成人大香蕉网站精品免费| 亚洲无码一本道| 重庆美女揉BBBB搡BBBB| 亚洲日韩一区二区| 99视频在线| 一区无码免费| 蜜桃无码一区| 北京熟妇搡BBBB搡BBBB电影 | 日本色电影在线观看| 亚洲秘一区二区三区-精品亚洲二区- | 先锋影音资源站| 大香蕉亚洲成人| 免费日韩AV| 国产精品久久一区二区三区影音先锋 | 亚洲黄色激情| 国产乱╳╳AⅤ毛片| 在线免费观看网站| 久久久久精| 精品区| www在线| 色婷婷在线视频| 欧美成人不卡| 96精品| 97精品人妻一区二区| 日韩中文字幕免费在线观看| 国产精品成人影视| 陈冠希和张柏芝mv| 玩弄小怮女在线观看| 香蕉漫画在线观看18| 成人五月天黄色电影| 日本黄色电影在线播放| 欧美一本在线| 国产乱子伦-区二区三区四区| 亚洲精品第一页| 久久高清无码视频| 欧洲尤物不卡播放六区| 五月人妻| 中文字幕无码播放| 在线观看国产小视频| 国产毛片一区二区| 人人人人操| 日韩一区二区三区四区| 久久久久国产一区二区三区四区| 国产SUV精品一区二区| 青娱乐成人电影| 日韩在线视频免费播放| 91网站免费| 最新中文字幕在线| 正在播放李彩斐被洋老外| 一级黄色影院| 操逼超碰| 91大香蕉视频| 国产精品成人无码a无码| 人人爱人人插| 午夜操人妻| 精品一本道| 无码一区视频| 熟睡侵犯の奶水授乳在线| 日本免费中文字幕| 水蜜桃在线视频| 国产精选在线| 北京熟妇搡BBBB搡BBBB电影 | 亚洲五月天婷婷| 成人做爰黄A片免费看直播室动漫| 欧美激情视频一区二区三区不卡 | 国产在线a| 欧美一级a| 国产精品欧美性爱| 青青草原在线视频免费观看| 国产在线免费视频| 波多野结衣在线无码| 麻豆性爱| 一级黄色影院| 天天干天天操天天爽| 九九激情| 午夜精品无码| 另类老妇性BBBWBBW| 久久久久成人视频| 色欲网址| 久久成人综合| 日本无码一区二区三三| 久草在在线视频| 六十路老熟女码视频| 日本成人毛片| 日韩高清无码电影| 黄色视频| 在线日韩一区二区| 婷婷五月天丁香网| 黄色一级在线观看| 无码精品ThePorn| 国产精品三级在线| 性无码区| а√最新版在线中文8| 首页-91n| 色天使色天堂| 在线观看AV资源| 成人久久久久一级大黄毛片中国 | 无码精品一区二区三区在线播放| 日韩色情电影| 水蜜桃视频免费| 人人操操| 情趣视频网站| 欧美自拍第一页| 国产嫩草精品A88AV| 无码成人片| 安徽妇搡BBBB搡BBBB,另类老妇 | 婷婷五月天大香蕉| 日韩午夜成人电影| 麻豆一级片| 成年人免费看视频| 无码人妻精品一区二区蜜桃漫画| 色五月天婷婷| 亚洲成人视频在线观看| 在线观看黄色小电影| 91在线一区二区三区| 日韩欧美成人在线| 国产嫩草久久久一二三久久免费观看| 久久久久亚洲AV无码成人片| 欧洲精品视频在线观看| 日韩免费高清无码| 国产欧美日韩成人| 国产又爽又黄视频在线看| 成人电影一区二区| 99大香蕉| 黄色高清视频在线观看| 午夜AV福利| 欧美强开小嫩苞| 国产免费精彩视频| 亚洲AV无码久久久| 伊人狠狠蜜桃亚洲综合| 人人妻人人摸| 日本少妇中文字幕| 草草视频在线观看| 偷拍一区二区| 久久久久久久久久免费视频| 免费视频99| 国产一级a一级a免费视频| 亚洲九九| 免费观看在线黄片| 日本A片在线播放| 97中文字幕| 91精品国产乱码久久| 久久在线免费视频| 欧一美一婬一伦一区| 超碰997| 中文字幕在线观看日本| 日韩色| 超碰在线最新| 午夜啪啪视频| 精品香蕉视频| 亚洲中文视频免费| 亚洲成人性爱视频| 人人操av| 欧美在线观看网站18| 精品亚洲一区二区三区四区五区| 91人妻无码成人精品一区二区| 国外成人在线视频老鸭窝| 天天干天天天天| 黄色一级片网站| 日韩美女毛片| 国内精品久久久久久久久久| 91在线日韩| 免费无码在线看| 精品黄色视频| 97A片在线观看播放| 密臀福利导航| 国产成人影视在线观看| 99黄色视频| 少妇搡BBBB搡BBB搡打电话| 又黄又爽的视频| 日日干天天操| 免费AV资源在线观看| 高清无码网址| 成人精品在线| 黑种人配中国少妇HD| 日本三级韩三级99久久| 亚洲无码影视| 97干在线| www中文字幕| 51色片| 亚洲一级二级三级片| 日韩免费无码| 欧美成人福利视频| 精品无码三级在线观看视频| 亚洲天堂免费视频| 中文一区在线观看| 成人性爱在线| 欧美色色色网| 人人上人人摸| 黄色在线免费观看| 亚洲欧洲精品成人久久曰影片 | 欧美日韩国产精品| 韩国一区二区在线观看| 久久噜噜| 伊人婷婷色香综合| 国产麻豆一区二区三区| 亚洲专区视频| 久草a视频| 18AV在线观看| 日本欧美久久久久免费播放网| 亚洲黄色在线观看视频| 操逼影片| 欧美操日本| 超碰性爱| 91在线免费视频| 青青草原在线视频免费观看| 亚洲久久久久| 天天爱夜夜爱| 2018人人操| 亚洲Japanese办公室制服|