日韩av黄I国产麻豆传媒I国产91av视频在线观看I日韩一区二区三区在线看I美女国产在线I麻豆视频国产在线观看I成人黄色短片

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 综合教程 >内容正文

综合教程

1.spring security简单的demo-适合萌新

發布時間:2023/12/3 综合教程 46 生活家
生活随笔 收集整理的這篇文章主要介紹了 1.spring security简单的demo-适合萌新 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

文章目錄

  • 1.spring security入門
    • 1.創建項目,引入依賴
    • 2.security的其他配置方式
      • 2.2基于內存
      • 2.3HttpSecurity(入門配置此文件)
      • 2.4多個HttpSecurity的配置(復雜業務場景下)---security
      • 2.5配置方法安全
      • 2.6基于數據庫的認證(基礎入門)-----sercuty-db/sercurity-dy
        • 1.定義實體類user(繼承UserDetails)和role
        • 2.配置SecurityConfig
        • 3.動態權限配置的Security寫法
          • 1. 1.先定義MyFilter實現FilterInvocationSecurityMetadataSource
          • 3.1SecurityConfig的寫法
      • 2.7spring security整合oauth2---oauth2
        • 2.7.1配置資源服務器 ResourceServerConfig
        • 2.7.2授權服務器 AuthorizationServerConfig
        • 2.7.3security配置文件
        • 2.7.4 MyFilter
        • 2.7.5 MyAccessDecisionManager
        • 2.7.6 postman測試 -請求token
      • 2.8spring security支持json登錄---security-dy/security-db/oauth2
        • 2.8.1重寫UsernamePasswordAuthenticationFilter方法
        • 2.8.2注入重寫的方法
        • 2.8.3配置登錄成功后的轉跳和失敗后轉跳
      • 2.9spring security整合jwt --jwt-demo
        • 2.9.1 JwtLoginFilter _登錄的時候給用戶token_
        • 2.9.2. _訪問系統的時候效驗token_
        • 2.9.3增加security的相關配置 configure_(_HttpSecurity http_) _
      • 2.10 oauth2 整合jwt+swagger ---swcurity-swagger/ 松哥例子swagger-jwt
        • 2.10.1.AccessTokenConfig
        • 2.10.2AuthorizationServer
        • 2.10.3ResourceServerConfig
        • 2.10.4 GlobalCorsConfiguration ---支持跨域
      • 2.11configure其他配置

1.spring security入門

decurity-demo.sql 數據庫驗證的文件

密碼是123或者123456/ 可以使用 new BCryptPasswordEncoder_().encode(“123”)_;加密出來
模板項目地址https://gitee.com/find_me/java-findme

1.創建項目,引入依賴

  <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-security</artifactId>
</dependency>
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId>
</dependency>

引入依賴后,項目中所有的接口就會被保護起來,項目默認用戶名為user,密碼為啟動后隨即生成的,在控制臺打印的密碼

2.security的其他配置方式

spring:security:user: name: find mepassword: 123456roles: admin

2.2基于內存

當然,開發者也可以自定義類繼承自WebSecurityConfigurerAdapter ,進而實現對 Spring Security
更多的自定義配置,例如基于內存的認證,配置方式如下:

@Configuration public class MyWebSecurityConfig extends WebSecurityConfigurerAdapter { // 密碼不加密的配置 ,過時的方法@Bean //PasswordEncoder passwordEncoder () { //return NoOpPasswordEncoder. getlnstance () ; // }// 密碼需要加密@BeanPasswordEncoder passwordEncoder() {return new BCryptPasswordEncoder();}//基于內存的配置@Overrideprotected void configure(AuthenticationManagerBuilder auth) throws Exception {auth.inMemoryAuthentication().withUser("javaboy").password("$2a$10$KlbLLUVVyvP0/vuhlabv0upg/ALdCrVEhUJOJDEND5ZtZJ.nGfVCm").roles("admin").and().withUser("findme").password("$2a$10$KlbLLUVVyvP0/vuhlabv0upg/ALdCrVEhUJOJDEND5ZtZJ.nGfVCm").roles("user");}

代碼解釋:
·自定義 MyWebSecurityConfig 繼承自 WebSecurityConfigurerAdapter ,并重寫configure(AuthenticationManagerBuilder auth)方法,在該方法中配直兩個用戶,一個用戶名是
admin,密碼123 ,具備兩個角色 ADMIN USER 另一個用戶名是 findme,密碼是 123 ,具備一個角色USER
Spring Security 本是 0.6 Spring Security 中引入了 多種密碼加密方式,開發者必須指定其中一種, NoOpPasswordEncoder ,即不對密碼進行加密。

注意:基于配置和內存的方式在配置角色的時候不需要添加"ROLE_".基于數據庫的需要

2.3HttpSecurity(入門配置此文件)

根據實際情況進行角色配置

@Configuration
public class SecurityConfig extends WebSecurityConfigurerAdapter {@Resourceprivate ObjectMapper objectMapper;@BeanPasswordEncoder passwordEncoder() {return new BCryptPasswordEncoder();}// 配置登錄的賬號@Overrideprotected void configure(AuthenticationManagerBuilder auth) throws Exception {auth.inMemoryAuthentication().withUser("javaboy").password("$2a$10$KlbLLUVVyvP0/vuhlabv0upg/ALdCrVEhUJOJDEND5ZtZJ.nGfVCm").roles("admin").and().withUser("findme").password("$2a$10$KlbLLUVVyvP0/vuhlabv0upg/ALdCrVEhUJOJDEND5ZtZJ.nGfVCm").roles("user");}//基本的httpSecurity配置// 1.請求路徑角色// 2.配置表單登錄// 3.配置登錄成功,失敗或者登出的處理方式// authentication里面存放登錄成功后的信息//      {//            "password": null, 密碼//             "username": "javaboy",//             "authorities": [ 具備的角色//            {//                "authority": "ROLE_admin" //            }//        ],//            "accountNonExpired": true, 賬戶沒有過期,//                "accountNonLocked": true, 賬戶沒有鎖定//                "credentialsNonExpired": true, 密碼沒有過期//                "enabled": true 賬戶可用//        },@Overrideprotected void configure(HttpSecurity http) throws Exception {http.authorizeRequests()//開啟配置.antMatchers("/admin/**").hasRole("admin")//路徑符合這個需要admin角色
//                .antMatchers("user/**").hasAnyRole("admin", "user")//路徑符合這個,需要這兩個的任意一個.antMatchers("/user/**").access("hasAnyRole('user','admin')").anyRequest().authenticated()//其他請求,登錄后就可以訪問.and().formLogin()//表單登錄.loginProcessingUrl("/doLogin")//處理登錄請求的地址.loginPage("/login")//配置登錄頁面(實際上還是一個請求地址) 前后端分類不存在這種頁面 這里還是訪問的應該請求,會根據這請求去返回登錄頁面.usernameParameter("uname")//修改登錄的key.passwordParameter("passwd")//修改登錄的key.successHandler(new AuthenticationSuccessHandler() { //登錄成功的處理@Override// authentication保存了登錄成功后的信息public void onAuthenticationSuccess(HttpServletRequest req, HttpServletResponse resp,Authentication authentication) throws IOException, ServletException {resp.setContentType("application/json;charset=utf-8");PrintWriter out = resp.getWriter();Map<String, Object> map = new HashMap<>();map.put("status", 200);map.put("msg", authentication.getPrincipal());out.write(new ObjectMapper().writeValueAsString(map));out.flush();out.close();}}).failureHandler(new AuthenticationFailureHandler() {//登錄失敗的處理@Override // e登錄失敗的異常public void onAuthenticationFailure(HttpServletRequest req, HttpServletResponse resp,AuthenticationException e) throws IOException, ServletException {resp.setContentType("application/json;charset=utf-8");PrintWriter out = resp.getWriter();Map<String, Object> map = new HashMap<>();map.put("status", 401);if (e instanceof LockedException) {map.put("msg", "賬戶被鎖定,登錄失敗!");} else if (e instanceof BadCredentialsException) {map.put("msg", "用戶名或密碼輸入錯誤,登錄失敗!");} else if (e instanceof DisabledException) {map.put("msg", "賬戶被禁用,登錄失敗!");} else if (e instanceof AccountExpiredException) {map.put("msg", "賬戶過期,登錄失敗!");} else if (e instanceof CredentialsExpiredException) {map.put("msg", "密碼過期,登錄失敗!");} else {map.put("msg", "登錄失敗!");}out.write(new ObjectMapper().writeValueAsString(map));out.flush();out.close();}}).permitAll().and().logout().logoutUrl("/logout") //配置注銷請求的地址.logoutSuccessHandler(new LogoutSuccessHandler() {//注銷成功后的回調@Overridepublic void onLogoutSuccess(HttpServletRequest req, HttpServletResponse resp,Authentication authentication) throws IOException, ServletException {resp.setContentType("application/json;charset=utf-8");PrintWriter out = resp.getWriter();Map<String, Object> map = new HashMap<>();map.put("status", 200);map.put("msg", "注銷登錄成功!");out.write(new ObjectMapper().writeValueAsString(map));out.flush();out.close();}}).and().csrf().disable();/*** 權限不足處理*/http.exceptionHandling().accessDeniedHandler(new AccessDeniedHandler() {@Overridepublic void handle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, AccessDeniedException e) throws IOException {httpServletResponse.setContentType(MediaType.APPLICATION_JSON_UTF8_VALUE);Map<String, Object> failureMap = new HashMap<>();failureMap.put("code", 403);failureMap.put("msg", "權限不足!");httpServletResponse.getWriter().println(objectMapper.writeValueAsString(failureMap));}});
//        /**
//         * 未登陸處理
//         */
//        http.exceptionHandling().authenticationEntryPoint(new AuthenticationEntryPoint() {
//            @Override
//            public void commence(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, AuthenticationException e) throws IOException {
//
//
//                httpServletResponse.setContentType(MediaType.APPLICATION_JSON_UTF8_VALUE);
//
//                Map<String, Object> failureMap = new HashMap<>();
//                failureMap.put("code", 401);
//                failureMap.put("msg", "請先登錄!");
//
//                httpServletResponse.getWriter().println(objectMapper.writeValueAsString(failureMap));
//
//            }
//        });}
}

2.4多個HttpSecurity的配置(復雜業務場景下)—security

參考項目 spring-security-me/security
采用靜態內部類的方式 采用order設置優先級,數字越小,優先級越大

@Configuration
@EnableGlobalMethodSecurity(prePostEnabled = true,securedEnabled = true) //開啟方法安全
public class MultiHttpSecurityConfig {@BeanPasswordEncoder passwordEncoder() {return new BCryptPasswordEncoder();}@Autowiredprotected void configure(AuthenticationManagerBuilder auth) throws Exception {auth.inMemoryAuthentication().withUser("javaboy").password("$2a$10$G3kVAJHvmRrr6sOj.j4xpO2Dsxl5EG8rHycPHFWyi9UMIhtdSH15u").roles("admin").and().withUser("").password("$2a$10$kWjG2GxWhm/2tN2ZBpi7bexXjUneIKFxIAaMYJzY7WcziZLCD4PZS").roles("user");}@Configuration@Order(1)public static class AdminSecurityConfig extends WebSecurityConfigurerAdapter{@Overrideprotected void configure(HttpSecurity http) throws Exception {http.antMatcher("/admin/**").authorizeRequests().anyRequest().hasAnyRole("admin");//只有這種格式的路徑才會去要求角色}}@Configurationpublic static class OtherSecurityConfig extends WebSecurityConfigurerAdapter{@Overrideprotected void configure(HttpSecurity http) throws Exception {http.authorizeRequests().anyRequest().authenticated().and().formLogin().loginProcessingUrl("/doLogin").permitAll().and().csrf().disable();}}
}

2.5配置方法安全

在Security上面加上

@EnableGlobalMethodSecurity(prePostEnabled = true,securedEnabled = true) //開啟方法安全
然后在方法上加PreAuthorize注解

@Service
public class MethodService {@PreAuthorize("hasRole('admin')")// 這個方法需要admin角色public String admin() {return "hello admin";}@Secured("ROLE_user")  //需要user角色public String user() {return "hello user";}@PreAuthorize("hasAnyRole('admin','user')")//需要兩者之一public String hello() {return "hello hello";}
}

2.6基于數據庫的認證(基礎入門)-----sercuty-db/sercurity-dy

權限模型

權限實際開發模型

1.定義實體類user(繼承UserDetails)和role

security-demo.sql


public class User implements UserDetails {private Integer id;private String username;private String password;private Boolean enabled;private Boolean locked;private List<Role> roles;public List<Role> getRoles() {return roles;}public void setRoles(List<Role> roles) {this.roles = roles;}public Integer getId() {return id;}public void setId(Integer id) {this.id = id;}// 返回用戶所有的角色@Overridepublic Collection<? extends GrantedAuthority> getAuthorities() {List<SimpleGrantedAuthority> authorities = new ArrayList<>();// 重新整理一下 角色認證要以ROLE_開始 數據庫沒有就要在這里手動拼接for (Role role : roles) {authorities.add(new SimpleGrantedAuthority(role.getName()));}return authorities;}@Overridepublic String getPassword() {return password;}public void setPassword(String password) {this.password = password;}@Overridepublic String getUsername() {return username;}// 賬戶是否未過期 目前數據庫沒有就直說true@Overridepublic boolean isAccountNonExpired() {return true;}// 賬戶是否未鎖定@Overridepublic boolean isAccountNonLocked() {return !locked;}// 密碼是否未過期@Overridepublic boolean isCredentialsNonExpired() {return true;}// 是否可用@Overridepublic boolean isEnabled() {return enabled;}public void setUsername(String username) {this.username = username;}public void setEnabled(Boolean enabled) {this.enabled = enabled;}public void setLocked(Boolean locked) {this.locked = locked;}
}

2.配置SecurityConfig

@Configuration
public class SecurityConfig extends WebSecurityConfigurerAdapter {@AutowiredUserService userService;@BeanPasswordEncoder passwordEncoder() {return new BCryptPasswordEncoder();}// 此處去調用數據庫的或者采用靜態數據@Overrideprotected void configure(AuthenticationManagerBuilder auth) throws Exception {auth.userDetailsService(userService);}@Overrideprotected void configure(HttpSecurity http) throws Exception {//對于不同的路徑要不同的角色 靜態配置http.authorizeRequests().antMatchers("/dba/**").hasRole("dba").antMatchers("/admin/**").hasRole("admin").antMatchers("/user/**").hasRole("user").anyRequest().authenticated().and().formLogin().permitAll().and().csrf().disable();}// 角色繼承的bean@BeanRoleHierarchy roleHierarchy() {RoleHierarchyImpl roleHierarchy = new RoleHierarchyImpl();// 以前String hierarchy = "dba > admin admin > user";// 現在String hierarchy = "dba > admin \n admin > user";roleHierarchy.setHierarchy(hierarchy);return roleHierarchy;}	

3.動態權限配置的Security寫法

1. 1.先定義MyFilter實現FilterInvocationSecurityMetadataSource

主要就是分析出需要哪些角色

@Configuration
public class SecurityConfig extends WebSecurityConfigurerAdapter {@AutowiredUserService userService;@AutowiredMyFilter myFilter;@AutowiredMyAccessDecisionManager myAccessDecisionManager;@BeanPasswordEncoder passwordEncoder() {return new BCryptPasswordEncoder();}@Overrideprotected void configure(AuthenticationManagerBuilder auth) throws Exception {auth.userDetailsService(userService);}//    @Bean
//    RoleHierarchy roleHierarchy() {
//        RoleHierarchyImpl roleHierarchy = new RoleHierarchyImpl();
//        String hierarchy = "dba > admin \n admin > user";
//        roleHierarchy.setHierarchy(hierarchy);
//        return roleHierarchy;
//    }
@Bean
@Override
protected UserDetailsService userDetailsService() {return super.userDetailsService();
}@Overrideprotected void configure(HttpSecurity http) throws Exception {http.authorizeRequests().withObjectPostProcessor(new ObjectPostProcessor<FilterSecurityInterceptor>() {@Overridepublic <O extends FilterSecurityInterceptor> O postProcess(O o) {o.setAccessDecisionManager(myAccessDecisionManager);o.setSecurityMetadataSource(myFilter);return o;}}).and().formLogin().permitAll().and().csrf().disable();}
}

2.編寫MyAccessDecisionManager繼承 AccessDecisionManager


@Component
public class MyAccessDecisionManager implements AccessDecisionManager {/**** @param authentication 當前用戶具備的角色* @param o* @param collection  當前路徑需要的角色,這里是在MyFiter處理后得到的* @throws AccessDeniedException* @throws InsufficientAuthenticationException*/@Overridepublic void decide(Authentication authentication, Object o, Collection<ConfigAttribute> collection) throws AccessDeniedException, InsufficientAuthenticationException {for (ConfigAttribute attribute : collection) {if ("ROLE_login".equals(attribute.getAttribute())) {// 如果是返回的ROLE_login說明你請求的路徑不存在,所有判斷你有沒有登錄 登錄的就直接放行if (authentication instanceof AnonymousAuthenticationToken) {throw new AccessDeniedException("非法請求!");} else {return;}}// 獲取我具備的角色Collection<? extends GrantedAuthority> authorities = authentication.getAuthorities();// 做匹配for (GrantedAuthority authority : authorities) {if (authority.getAuthority().equals(attribute.getAttribute())) {return;}}}// 例如,我具備某些角色,但是此角色沒有此路徑的權限,那就是非要請求throw new AccessDeniedException("非法請求!");}@Overridepublic boolean supports(ConfigAttribute configAttribute) {return true;}@Overridepublic boolean supports(Class<?> aClass) {return true;}
}
3.1SecurityConfig的寫法

@Configuration
public class SecurityConfig extends WebSecurityConfigurerAdapter {@AutowiredUserService userService;@AutowiredMyFilter myFilter;@AutowiredMyAccessDecisionManager myAccessDecisionManager;@BeanPasswordEncoder passwordEncoder() {return new BCryptPasswordEncoder();}@Overrideprotected void configure(AuthenticationManagerBuilder auth) throws Exception {auth.userDetailsService(userService);}/@Overrideprotected void configure(HttpSecurity http) throws Exception {http.authorizeRequests().withObjectPostProcessor(new ObjectPostProcessor<FilterSecurityInterceptor>() {//FilterSecurityInterceptor 攔截器@Overridepublic <O extends FilterSecurityInterceptor> O postProcess(O o) {o.setAccessDecisionManager(myAccessDecisionManager);o.setSecurityMetadataSource(myFilter);return o;}}).and().formLogin().permitAll().and().csrf().disable();}
}

2.7spring security整合oauth2—oauth2

2.7.1配置資源服務器 ResourceServerConfig

/*** 資源服務器*/
@Configuration
@EnableResourceServer
public class ResourceServerConfig extends ResourceServerConfigurerAdapter {@Overridepublic void configure(ResourceServerSecurityConfigurer resources) throws Exception {//指定資源id stateless配置基于令牌認證resources.resourceId("rid").stateless(true);}//此處角色路徑可以從數據庫加載//    @Override
//    public void configure(HttpSecurity http) throws Exception {
//        // 路徑的角色
//        http.authorizeRequests().antMatchers("/admin/**").hasRole("admin")
//                .antMatchers("/user/**").hasRole("user")
//                .anyRequest().authenticated();
//    }// 從數據庫加載如下@AutowiredMyFilter myFilter;@AutowiredMyAccessDecisionManager myAccessDecisionManager;/*** @param http* @throws Exception*/@Overridepublic void configure(HttpSecurity http) throws Exception {http.authorizeRequests().withObjectPostProcessor(new ObjectPostProcessor<FilterSecurityInterceptor>() {@Overridepublic <O extends FilterSecurityInterceptor> O postProcess(O o) {o.setAccessDecisionManager(myAccessDecisionManager);o.setSecurityMetadataSource(myFilter);return o;}}).and().formLogin().permitAll().and().csrf().disable();}}

2.7.2授權服務器 AuthorizationServerConfig


/*** 授權服務器*/
@Configuration
@EnableAuthorizationServer
public class AuthorizationServerConfig extends AuthorizationServerConfigurerAdapter {// 支持password的認證模式@AutowiredAuthenticationManager authenticationManager;// 配置redis就會有@AutowiredRedisConnectionFactory redisConnectionFactory;// 密碼加密方式@AutowiredUserDetailsService userDetailsService;@BeanPasswordEncoder passwordEncoder() {return new BCryptPasswordEncoder();}@Overridepublic void configure(ClientDetailsServiceConfigurer clients) throws Exception {//配置在內存中//配置認證模式//配置授權模式//資源id(名字)//配置的密碼123456clients.inMemory().withClient("password").authorizedGrantTypes("password", "refresh_token").accessTokenValiditySeconds(1800).resourceIds("rid").scopes("all").secret("$2a$10$LcM2.fVWzB50vitKLrPPDugS/owlp.qVVT5jA0EyJuFeez6S5hTkm");}// 配置令牌的存儲@Overridepublic void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {endpoints.tokenStore(new RedisTokenStore(redisConnectionFactory)) //.authenticationManager(authenticationManager).userDetailsService(userDetailsService);}@Overridepublic void configure(AuthorizationServerSecurityConfigurer security) throws Exception {security.allowFormAuthenticationForClients();}}

2.7.3security配置文件

@Override@Beanprotected AuthenticationManager authenticationManager() throws Exception {return super.authenticationManager();}@Bean@Overrideprotected UserDetailsService userDetailsService() {return super.userDetailsService();}//  靜態的加載用戶
//    @Override
//    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
//        auth.inMemoryAuthentication()
//                .withUser("javaboy").password("$2a$10$LcM2.fVWzB50vitKLrPPDugS/owlp.qVVT5jA0EyJuFeez6S5hTkm").roles("admin")
//                .and()
//                .withUser("finde")
//                .password("$2a$10$kwLIAqAupvY87OM.O25.Yu1QKEXV1imAv7jWbDaQRFUFWSnSiDEwG")
//                .roles("user");
//    }
// 從數據庫加載用戶@AutowiredUserService userService;@Overrideprotected void configure(AuthenticationManagerBuilder auth) throws Exception {auth.userDetailsService(userService);}//放開oauth相關的請求,不就行攔截@Overrideprotected void configure(HttpSecurity http) throws Exception {http.antMatcher("/oauth/**").authorizeRequests().antMatchers("/oauth/**").permitAll().and().csrf().disable();}

2.7.4 MyFilter

@Component
public class MyFilter implements FilterInvocationSecurityMetadataSource {// 做路徑匹配的 提供了路徑批評規則AntPathMatcher pathMatcher = new AntPathMatcher();@AutowiredMenuService menuService;/*** 分析請求地址 根據請求的地址,分析出需要哪些角色* @param o* @return* @throws IllegalArgumentException*/@Overridepublic Collection<ConfigAttribute> getAttributes(Object o) throws IllegalArgumentException {// 請求的地址String requestUrl = ((FilterInvocation) o).getRequestUrl();// 所有的菜單 ,這里可以給一個緩存List<Menu> allMenus = menuService.getAllMenus();for (Menu menu : allMenus) {// 如果請求地址批評上了if (pathMatcher.match(menu.getPattern(), requestUrl)) {List<Role> roles = menu.getRoles();String[] rolesStr = new String[roles.size()];//查看需要哪些角色 rolesStr,防止角色集合for (int i = 0; i < roles.size(); i++) {rolesStr[i] = roles.get(i).getName();}return SecurityConfig.createList(rolesStr);}}// 沒有匹配上路徑,這個就是標識符號,看在數據庫中沒有這個路徑,怎么處理return SecurityConfig.createList("ROLE_login");}@Overridepublic Collection<ConfigAttribute> getAllConfigAttributes() {return null;}@Overridepublic boolean supports(Class<?> aClass) {return true;}
}

2.7.5 MyAccessDecisionManager


@Component
public class MyAccessDecisionManager implements AccessDecisionManager {/**** @param authentication 當前用戶具備的角色* @param o* @param collection  當前路徑需要的角色,這里是在MyFiter處理后得到的* @throws AccessDeniedException* @throws InsufficientAuthenticationException*/@Overridepublic void decide(Authentication authentication, Object o, Collection<ConfigAttribute> collection) throws AccessDeniedException, InsufficientAuthenticationException {for (ConfigAttribute attribute : collection) {if ("ROLE_login".equals(attribute.getAttribute())) {// 如果是返回的ROLE_login說明你請求的路徑不存在,所有判斷你有沒有登錄 登錄的就直接放行if (authentication instanceof AnonymousAuthenticationToken) {throw new AccessDeniedException("非法請求!");} else {return;}}// 獲取我具備的角色Collection<? extends GrantedAuthority> authorities = authentication.getAuthorities();// 做匹配for (GrantedAuthority authority : authorities) {if (authority.getAuthority().equals(attribute.getAttribute())) {return;}}}// 例如,我具備某些角色,但是此角色沒有此路徑的權限,那就是非要請求throw new AccessDeniedException("非法請求!");}@Overridepublic boolean supports(ConfigAttribute configAttribute) {return true;}@Overridepublic boolean supports(Class<?> aClass) {return true;}
}

2.7.6 postman測試 -請求token

post http://127.0.0.1:8981/oauth/token
Body x-www-form-urlencoded
[{“key”:“username”,“value”:“admin”},
{“key”:“password”,“value”:“123”},
{“key”:“grant_type”,“value”:“password”},
{“key”:“client_id”,“value”:“password”},
{“key”:“scope”,“value”:“all”},
{“key”:“client_secret”,“value”:“123456”}]

{"username":"admin", "password":"123","grant_type":"password","client_id":"password","scope":"all","client_secret":"123456",
}

結果
{
“access_token”: “d1bdfd01-e06a-4b4e-a661-a49012da9afa”,
“token_type”: “bearer”,
“refresh_token”: “d31082b6-68a7-46b5-937a-62a24b186970”,
“expires_in”: 1325,
“scope”: “all”
}

換回新的token

{"grant_type":"refresh_token", "refresh_token":"d31082b6-68a7-46b5-937a-62a24b186970","grant_type":"password","client_secret":"123456",
}

2.8spring security支持json登錄—security-dy/security-db/oauth2

2.8.1重寫UsernamePasswordAuthenticationFilter方法

public class MyAuthenticationFilter extends UsernamePasswordAuthenticationFilter {@Overridepublic Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response) throwsAuthenticationException {if (!request.getMethod().equals("POST")) {throw new AuthenticationServiceException("Authentication method not supported: " + request.getMethod());}if (request.getContentType().equals(MediaType.APPLICATION_JSON_VALUE)) {//說明用戶以 JSON 的形式傳遞的參數String username = null;String password = null;try {Map<String, String> map = new ObjectMapper().readValue(request.getInputStream(), Map.class);username = map.get("username");password = map.get("password");} catch (IOException e) {e.printStackTrace();}if (username == null) {username = "";}if (password == null) {password = "";}username = username.trim();UsernamePasswordAuthenticationToken authRequest = new UsernamePasswordAuthenticationToken(username, password);// Allow subclasses to set the "details" propertysetDetails(request, authRequest);return this.getAuthenticationManager().authenticate(authRequest);}return super.attemptAuthentication(request, response);}

2.8.2注入重寫的方法

在securityconfig中寫入一下文件

 // 配置支持json登錄@BeanMyAuthenticationFilter myAuthenticationFilter() throws Exception {MyAuthenticationFilter filter = new MyAuthenticationFilter();filter.setAuthenticationManager(authenticationManagerBean());return filter;}/**** @param http* @throws Exception*/@Overrideprotected void configure(HttpSecurity http) throws Exception {http.addFilterAt(myAuthenticationFilter(), UsernamePasswordAuthenticationFilter.class);}

2.8.3配置登錄成功后的轉跳和失敗后轉跳

在myAuthenticationFilter中配置
此時成功和失敗的回調只能在fiter中配置,cnfigure中的配置是失效的

  // 配置支持json登錄@BeanMyAuthenticationFilter myAuthenticationFilter() throws Exception {MyAuthenticationFilter filter = new MyAuthenticationFilter();filter.setAuthenticationManager(authenticationManagerBean());filter.setAuthenticationSuccessHandler(new AuthenticationSuccessHandler() { //登錄成功的處理@Override// authentication保存了登錄成功后的信息public void onAuthenticationSuccess(HttpServletRequest req, HttpServletResponse resp,Authentication authentication) throws IOException, ServletException {resp.setContentType("application/json;charset=utf-8");PrintWriter out = resp.getWriter();Map<String, Object> map = new HashMap<>();map.put("status", 200);map.put("msg", authentication.getPrincipal());out.write(new ObjectMapper().writeValueAsString(map));out.flush();out.close();}});filter.setAuthenticationFailureHandler(new AuthenticationFailureHandler() {//登錄失敗的處理@Override // e登錄失敗的異常public void onAuthenticationFailure(HttpServletRequest req, HttpServletResponse resp,AuthenticationException e) throws IOException, ServletException {resp.setContentType("application/json;charset=utf-8");PrintWriter out = resp.getWriter();Map<String, Object> map = new HashMap<>();map.put("status", 401);if (e instanceof LockedException) {map.put("msg", "賬戶被鎖定,登錄失敗!");} else if (e instanceof BadCredentialsException) {map.put("msg", "用戶名或密碼輸入錯誤,登錄失敗!");} else if (e instanceof DisabledException) {map.put("msg", "賬戶被禁用,登錄失敗!");} else if (e instanceof AccountExpiredException) {map.put("msg", "賬戶過期,登錄失敗!");} else if (e instanceof CredentialsExpiredException) {map.put("msg", "密碼過期,登錄失敗!");} else {map.put("msg", "登錄失敗!");}out.write(new ObjectMapper().writeValueAsString(map));out.flush();out.close();}});return filter;}

2.9spring security整合jwt --jwt-demo

2.9.1 JwtLoginFilter 登錄的時候給用戶token

public class JwtLoginFilter extends AbstractAuthenticationProcessingFilter {// 實現構造方法/**** @param defaultFilterProcessesUrl* @param authenticationManager*/public JwtLoginFilter(String defaultFilterProcessesUrl, AuthenticationManager authenticationManager) {super(new AntPathRequestMatcher(defaultFilterProcessesUrl));setAuthenticationManager(authenticationManager);}/***  提取用戶名和密碼去做登錄** @param req* @param httpServletResponse* @return* @throws AuthenticationException* @throws IOException*/@Overridepublic Authentication attemptAuthentication(HttpServletRequest req, HttpServletResponse httpServletResponse)throws AuthenticationException, IOException {// 為了獲取登錄的數據轉換成userUser user = new ObjectMapper().readValue(req.getInputStream(), User.class);return getAuthenticationManager().authenticate(new UsernamePasswordAuthenticationToken(user.getUsername(), user.getPassword()));}// 登錄成功的回調 生成jwt@Overrideprotected void successfulAuthentication(HttpServletRequest request, HttpServletResponse resp,FilterChain chain, Authentication authResult) throws IOException, ServletException {Collection<? extends GrantedAuthority> authorities = authResult.getAuthorities();//獲取登錄用戶的角色StringBuffer sb = new StringBuffer();for (GrantedAuthority authority : authorities) {//獲取當前角色sb.append(authority.getAuthority()).append(",");}// 生成jwt的tokenString jwt = Jwts.builder().claim("authorities", sb)// 用戶的角色.setSubject(authResult.getName()) // 主題.setExpiration(new Date(System.currentTimeMillis() + 60 * 60 * 1000)) // 過期時間.signWith(SignatureAlgorithm.HS512, "findme") // 簽名的算法.compact();Map<String, String> map = new HashMap<>();map.put("token", jwt);map.put("msg", "登錄成功");resp.setContentType("application/json;charset=utf-8");PrintWriter out = resp.getWriter();out.write(new ObjectMapper().writeValueAsString(map));out.flush();out.close();}// 登錄失敗/***** @param req* @param resp* @param failed* @throws IOException* @throws ServletException 登錄失敗的異常,根據異常判斷失敗的原因*/@Overrideprotected void unsuccessfulAuthentication(HttpServletRequest req, HttpServletResponse resp,AuthenticationException failed) throws IOException, ServletException {Map<String, String> map = new HashMap<>();map.put("msg", "登錄失敗");resp.setContentType("application/json;charset=utf-8");PrintWriter out = resp.getWriter();out.write(new ObjectMapper().writeValueAsString(map));out.flush();out.close();}

2.9.2. 訪問系統的時候效驗token

public class JwtFilter extends GenericFilterBean {/*** 用戶每次登錄的時候校驗token** @param servletRequest* @param servletResponse* @param filterChain* @throws IOException* @throws ServletException*/@Overridepublic void doFilter(ServletRequest servletRequest, ServletResponse servletResponse,FilterChain filterChain) throws IOException, ServletException {HttpServletRequest req = (HttpServletRequest) servletRequest;// token 放在很多地方都可以,此處是默認把token放到請求頭中String jwtToken = req.getHeader("authorization");// 解析tokenJws<Claims> jws = Jwts.parser().setSigningKey("findme") // 生成token的簽名.parseClaimsJws(jwtToken.replace("Bearer", "")); // 前端的token會自動加一個Bearer,此處需要去掉Claims claims = jws.getBody(); // 登錄的信息String username = claims.getSubject();// 用戶名 剛才在生成的時候放入了// 拿到登錄的角色后要轉換成一個list集合解析  此處是當前用戶的角色List<GrantedAuthority> authorities = AuthorityUtils.commaSeparatedStringToAuthorityList((String) claims.get("authorities"));// new 一個新的tokenUsernamePasswordAuthenticationToken token = new UsernamePasswordAuthenticationToken(username, null, authorities);SecurityContextHolder.getContext().setAuthentication(token);// 對過濾器放行filterChain.doFilter(servletRequest,servletResponse);}

2.9.3增加security的相關配置 configure_(HttpSecurity http) _

 // jwt 相關配置http.authorizeRequests().antMatchers(HttpMethod.POST, "/login").permitAll().anyRequest().authenticated().and()// 登錄的過濾器.addFilterBefore(new JwtLoginFilter("/login", authenticationManager()), UsernamePasswordAuthenticationFilter.class)// 做校驗的過濾器.addFilterBefore(new JwtFilter(), UsernamePasswordAuthenticationFilter.class).csrf().disable();

2.10 oauth2 整合jwt+swagger —swcurity-swagger/ 松哥例子swagger-jwt

注意在引入依賴的時候引入cloud相關的

2.10.1.AccessTokenConfig

package com.find.securityswagger.auth;import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.oauth2.provider.token.TokenStore;
import org.springframework.security.oauth2.provider.token.store.JwtAccessTokenConverter;
import org.springframework.security.oauth2.provider.token.store.JwtTokenStore;/*** @ClassName AccessTokenConfig* @Description token* @Author find me* @Date 2020/6/25 0025 20:37* @Version 1.0*/
@Configuration
public class AccessTokenConfig {// TokenStore 我們使用 JwtTokenStore 這個實例。// 使用了 JWT,access_token 實際上就不用存儲了(無狀態登錄,服務端不需要保存信息),// 因為用戶的所有信息都在 jwt 里邊,所以這里配置的 JwtTokenStore 本質上并不是做存儲。@BeanTokenStore tokenStore() {return new JwtTokenStore(jwtAccessTokenConverter());}// 另外我們還提供了一個 JwtAccessTokenConverter,// 這個 JwtAccessTokenConverter 可以實現將用戶信息和 JWT 進行轉換(將用戶信息轉為 jwt 字符串,或者從 jwt 字符串提取出用戶信息)。// 另外,在 JWT 字符串生成的時候,我們需要一個簽名,這個簽名需要自己保存好。@BeanJwtAccessTokenConverter jwtAccessTokenConverter() {JwtAccessTokenConverter converter = new JwtAccessTokenConverter();converter.setSigningKey("findme");return converter;}
}

2.10.2AuthorizationServer

package com.find.securityswagger.auth;import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.authentication.AuthenticationManager;
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.AuthorizationServerEndpointsConfigurer;
import org.springframework.security.oauth2.config.annotation.web.configurers.AuthorizationServerSecurityConfigurer;
import org.springframework.security.oauth2.provider.ClientDetailsService;
import org.springframework.security.oauth2.provider.token.AuthorizationServerTokenServices;
import org.springframework.security.oauth2.provider.token.DefaultTokenServices;
import org.springframework.security.oauth2.provider.token.TokenEnhancerChain;
import org.springframework.security.oauth2.provider.token.TokenStore;
import org.springframework.security.oauth2.provider.token.store.JwtAccessTokenConverter;import java.util.Arrays;/*** @ClassName JwtAccessTokenConverter* @Description 將用戶信息和 JWT 進行轉換* @Author find me* @Date 2020/6/25 0025 20:39* @Version 1.0*/
@EnableAuthorizationServer
@Configuration
public class AuthorizationServer extends AuthorizationServerConfigurerAdapter {@AutowiredTokenStore tokenStore;@AutowiredClientDetailsService clientDetailsService;@AutowiredAuthenticationManager authenticationManager;@AutowiredPasswordEncoder passwordEncoder;@AutowiredJwtAccessTokenConverter jwtAccessTokenConverter;//主要用來配置 Token 的一些基本信息,// 例如 Token 是否支持刷新、Token 的存儲位置、Token 的有效期以及刷新 Token 的有效期等等。// Token 有效期這個好理解,刷新 Token 的有效期我說一下,// 當 Token 快要過期的時候,我們需要獲取一個新的 Token,在獲取新的 Token 時候,// 需要有一個憑證信息,這個憑證信息不是舊的 Token,而是另外一個 refresh_token,這個 refresh_token 也是有有效期的。@BeanAuthorizationServerTokenServices tokenServices() {DefaultTokenServices services = new DefaultTokenServices();services.setClientDetailsService(clientDetailsService);services.setSupportRefreshToken(true);services.setTokenStore(tokenStore);services.setAccessTokenValiditySeconds(60 * 60 * 24 * 2);services.setRefreshTokenValiditySeconds(60 * 60 * 24 * 7);TokenEnhancerChain tokenEnhancerChain = new TokenEnhancerChain();tokenEnhancerChain.setTokenEnhancers(Arrays.asList(jwtAccessTokenConverter));services.setTokenEnhancer(tokenEnhancerChain);return services;}//用來配置令牌端點的安全約束,也就是這個端點誰能訪問,誰不能訪問。@Overridepublic void configure(AuthorizationServerSecurityConfigurer security) throws Exception {security.allowFormAuthenticationForClients();}//用來配置客戶端的詳細信息@Overridepublic void configure(ClientDetailsServiceConfigurer clients) throws Exception {clients.inMemory().withClient("findme").secret(passwordEncoder.encode("123")) //.resourceIds("rid")//資源id.authorizedGrantTypes("password", "refresh_token")//授權類型.scopes("all").redirectUris("http://localhost:6004/index.html");//重定向 uri}//  這里用來配置令牌的訪問端點和令牌服務。@Overridepublic void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {endpoints.authenticationManager(authenticationManager).tokenServices(tokenServices());}
}

2.10.3ResourceServerConfig

package com.find.securityswagger.auth;import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.ObjectPostProcessor;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
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.TokenStore;
import org.springframework.security.web.access.intercept.FilterSecurityInterceptor;/*** @ClassName ResourceServerConfig* @Description* @Author find me* @Date 2020/6/25 0025 20:41* @Version 1.0*/
@Configuration
@EnableResourceServer
public class ResourceServerConfig extends ResourceServerConfigurerAdapter {@AutowiredTokenStore tokenStore;//首先在 configure 方法中配置資源 ID 和 TokenStore,這里配置好之后,// 會自動調用 JwtAccessTokenConverter 將 jwt 解析出來,jwt 里邊就// 包含了用戶的基本信息,所以就不用遠程校驗 access_token 了。@Overridepublic void configure(ResourceServerSecurityConfigurer resources) throws Exception {//指定資源id stateless配置基于令牌認證
//        resources.resourceId("rid").stateless(true);resources.resourceId("rid").tokenStore(tokenStore);}@AutowiredMyFilter myFilter;@AutowiredMyAccessDecisionManager myAccessDecisionManager;/*** @param http* @throws Exception*/@Overridepublic void configure(HttpSecurity http) throws Exception {http.authorizeRequests().withObjectPostProcessor(new ObjectPostProcessor<FilterSecurityInterceptor>() {@Overridepublic <O extends FilterSecurityInterceptor> O postProcess(O o) {o.setAccessDecisionManager(myAccessDecisionManager);o.setSecurityMetadataSource(myFilter);return o;}}).and().formLogin().permitAll().and().csrf().disable();}
}

2.10.4 GlobalCorsConfiguration —支持跨域

package com.find.securityswagger.swaggerconfig;import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
import org.springframework.web.filter.CorsFilter;/*** @ClassName GlobalCorsConfiguration* @Description 支持跨域* @Author find me* @Date 2020/6/25 0025 21:36* @Version 1.0*/
@Configuration
public class GlobalCorsConfiguration {@Beanpublic CorsFilter corsFilter() {CorsConfiguration corsConfiguration = new CorsConfiguration();corsConfiguration.setAllowCredentials(true);corsConfiguration.addAllowedOrigin("*");corsConfiguration.addAllowedHeader("*");corsConfiguration.addAllowedMethod("*");UrlBasedCorsConfigurationSource urlBasedCorsConfigurationSource = new UrlBasedCorsConfigurationSource();urlBasedCorsConfigurationSource.registerCorsConfiguration("/**", corsConfiguration);return new CorsFilter(urlBasedCorsConfigurationSource);}
}
package com.find.securityswagger.swaggerconfig;import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import springfox.documentation.builders.ApiInfoBuilder;
import springfox.documentation.builders.OAuthBuilder;
import springfox.documentation.builders.PathSelectors;
import springfox.documentation.builders.RequestHandlerSelectors;
import springfox.documentation.service.*;
import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spi.service.contexts.SecurityContext;
import springfox.documentation.spring.web.plugins.Docket;
import springfox.documentation.swagger2.annotations.EnableSwagger2;import java.util.Arrays;
import java.util.List;/*** @ClassName Swagger2Config* @Description swagger* @Author find me* @Date 2020/6/25 0025 21:19* @Version 1.0*/
@Configuration
@EnableSwagger2
public class Swagger2Config {
//    // 手動添加token的方式
//    @Bean
//    Docket docket() {
//        return new Docket(DocumentationType.SWAGGER_2)
//                .select()
//                .apis(RequestHandlerSelectors.basePackage("com.find.securityswagger.controller"))
//                .paths(PathSelectors.any())
//                .build()
//                .securityContexts(Arrays.asList(securityContexts()))
//                .securitySchemes(Arrays.asList(securitySchemes()))
//                .apiInfo(new ApiInfoBuilder()
//                        .description("接口文檔的描述信息")
//                        .title("微人事項目接口文檔")
//                        .contact(new Contact("javaboy","https://www.yuque.com/findme","2354827879@qq.com"))
//                        .version("v1.0")
//                        .license("Apache2.0")
//                        .build());
//    }
//    //通過 securitySchemes 來配置全局參數,這里的配置是一個名為 Authorization 的請求頭(OAuth2 中需要攜帶的請求頭)。
//    private SecurityScheme securitySchemes() {
//        return new ApiKey("Authorization", "Authorization", "header");
//    }
//
//    // 則用來配置有哪些請求需要攜帶 Token,這里我們配置了所有請求。
//    private SecurityContext securityContexts() {
//        return SecurityContext.builder()
//                .securityReferences(defaultAuth())
//                .forPaths(PathSelectors.any())
//                .build();
//    }
//
//    // 參數
//    private List<SecurityReference> defaultAuth() {
//        AuthorizationScope authorizationScope = new AuthorizationScope("xxx", "描述信息");
//        AuthorizationScope[] authorizationScopes = new AuthorizationScope[1];
//        authorizationScopes[0] = authorizationScope;
//        return Arrays.asList(new SecurityReference("Authorization", authorizationScopes));
//    }// 可以在頁面去配置整個登錄信息@BeanDocket docket() {return new Docket(DocumentationType.SWAGGER_2).select().apis(RequestHandlerSelectors.basePackage("com.find.securityswagger.controller")).paths(PathSelectors.any()).build().securityContexts(Arrays.asList(securityContext())).securitySchemes(Arrays.asList(securityScheme())).apiInfo(new ApiInfoBuilder().description("接口文檔的描述信息").title("find me demo    ").contact(new Contact("findme","https://www.yuque.com/findme","2354827879@qq.com")).version("v1.0").license("Apache2.0").build());}private AuthorizationScope[] scopes() {return new AuthorizationScope[]{new AuthorizationScope("all", "all scope")};}// 構建時即得配置 token 的獲取地址。private SecurityScheme securityScheme() {GrantType grant = new ResourceOwnerPasswordCredentialsGrant("http://127.0.0.1:6004/oauth/token");return new OAuthBuilder().name("OAuth2").grantTypes(Arrays.asList(grant)).scopes(Arrays.asList(scopes())).build();}private SecurityContext securityContext() {return SecurityContext.builder().securityReferences(Arrays.asList(new SecurityReference("OAuth2", scopes()))).forPaths(PathSelectors.any()).build();}
}

swagger的兩種配置的效果如下

輸入 Bearer ${token}

postman測試參數如下 先獲取token,在傳遞token

2.11configure其他配置

@Overrideprotected void configure(HttpSecurity http) throws Exception {http.authorizeRequests()//開啟配置.antMatchers("/admin/**").hasRole("admin")//路徑符合這個需要admin角色
//                .antMatchers("user/**").hasAnyRole("admin", "user")//路徑符合這個,需要這兩個的任意一個.antMatchers("/user/**").access("hasAnyRole('user','admin')").anyRequest().authenticated()//其他請求,登錄后就可以訪問.and().formLogin()//表單登錄.loginProcessingUrl("/doLogin")//處理登錄請求的地址.loginPage("/login")//配置登錄頁面(實際上還是一個請求地址) 前后端分類不存在這種頁面 這里還是訪問的應該請求,會根據這請求去返回登錄頁面.usernameParameter("uname")//修改登錄的key.passwordParameter("passwd")//修改登錄的key.successHandler(new AuthenticationSuccessHandler() { //登錄成功的處理@Override// authentication保存了登錄成功后的信息public void onAuthenticationSuccess(HttpServletRequest req, HttpServletResponse resp,Authentication authentication) throws IOException, ServletException {resp.setContentType("application/json;charset=utf-8");PrintWriter out = resp.getWriter();Map<String, Object> map = new HashMap<>();map.put("status", 200);map.put("msg", authentication.getPrincipal());out.write(new ObjectMapper().writeValueAsString(map));out.flush();out.close();}}).failureHandler(new AuthenticationFailureHandler() {//登錄失敗的處理@Override // e登錄失敗的異常public void onAuthenticationFailure(HttpServletRequest req, HttpServletResponse resp,AuthenticationException e) throws IOException, ServletException {resp.setContentType("application/json;charset=utf-8");PrintWriter out = resp.getWriter();Map<String, Object> map = new HashMap<>();map.put("status", 401);if (e instanceof LockedException) {map.put("msg", "賬戶被鎖定,登錄失敗!");} else if (e instanceof BadCredentialsException) {map.put("msg", "用戶名或密碼輸入錯誤,登錄失敗!");} else if (e instanceof DisabledException) {map.put("msg", "賬戶被禁用,登錄失敗!");} else if (e instanceof AccountExpiredException) {map.put("msg", "賬戶過期,登錄失敗!");} else if (e instanceof CredentialsExpiredException) {map.put("msg", "密碼過期,登錄失敗!");} else {map.put("msg", "登錄失敗!");}out.write(new ObjectMapper().writeValueAsString(map));out.flush();out.close();}}).permitAll().and().logout().logoutUrl("/logout") //配置注銷請求的地址.logoutSuccessHandler(new LogoutSuccessHandler() {//注銷成功后的回調@Overridepublic void onLogoutSuccess(HttpServletRequest req, HttpServletResponse resp,Authentication authentication) throws IOException, ServletException {resp.setContentType("application/json;charset=utf-8");PrintWriter out = resp.getWriter();Map<String, Object> map = new HashMap<>();map.put("status", 200);map.put("msg", "注銷登錄成功!");out.write(new ObjectMapper().writeValueAsString(map));out.flush();out.close();}}).and().csrf().disable();/*** 權限不足處理*/http.exceptionHandling().accessDeniedHandler(new AccessDeniedHandler() {@Overridepublic void handle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, AccessDeniedException e) throws IOException {httpServletResponse.setContentType(MediaType.APPLICATION_JSON_UTF8_VALUE);Map<String, Object> failureMap = new HashMap<>();failureMap.put("code", 403);failureMap.put("msg", "權限不足!");httpServletResponse.getWriter().println(objectMapper.writeValueAsString(failureMap));}});
//        /**
//         * 未登陸處理
//         */
//        http.exceptionHandling().authenticationEntryPoint(new AuthenticationEntryPoint() {
//            @Override
//            public void commence(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, AuthenticationException e) throws IOException {
//
//
//                httpServletResponse.setContentType(MediaType.APPLICATION_JSON_UTF8_VALUE);
//
//                Map<String, Object> failureMap = new HashMap<>();
//                failureMap.put("code", 401);
//                failureMap.put("msg", "請先登錄!");
//
//                httpServletResponse.getWriter().println(objectMapper.writeValueAsString(failureMap));
//
//            }
//        });
//

總結

以上是生活随笔為你收集整理的1.spring security简单的demo-适合萌新的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。

欧美成年人在线观看 | 色小说av | 美女视频a美女大全免费下载蜜臀 | 亚洲一级免费观看 | 免费在线观看av片 | 日韩av福利在线 | 日日骑 | 久精品视频 | 91精品国产91久久久久福利 | 国内精品久久久久久久97牛牛 | 精品一区 精品二区 | 日韩久久久久久 | 欧美99精品| 美女视频永久黄网站免费观看国产 | 97av影院| 日韩免费在线视频 | 日韩网站视频 | 中文国产在线观看 | 亚洲精品激情 | 国产高清在线视频 | 成人小视频免费在线观看 | 国产一区二区三区 在线 | 欧美亚洲另类在线视频 | 婷婷伊人综合 | 国产精品毛片久久蜜 | 五月天电影免费在线观看一区 | 精品久久久久一区二区国产 | 91综合久久一区二区 | 日韩黄色免费电影 | 欧美一级电影免费观看 | 日韩精品一区二区三区中文字幕 | 9免费视频 | 亚洲电影久久 | 在线免费观看不卡av | 欧美人交a欧美精品 | 综合久久婷婷 | 久久精品99久久久久久2456 | 天天综合网久久 | 伊人天天干 | 中文一区在线观看 | 亚洲视频一区二区三区在线观看 | 中文字幕观看在线 | 91精品在线免费视频 | 香蕉在线视频播放网站 | 久久久国产影院 | 91久草视频 | av再线观看 | 欧美尹人| 亚洲精品免费观看 | 一区在线电影 | 国产一级特黄毛片在线毛片 | 一本到在线 | 国产精品欧美久久久久无广告 | 色香蕉在线视频 | 国产乱对白刺激视频不卡 | 911精品美国片911久久久 | 婷婷国产在线 | 美女视频黄免费网站 | 成人观看 | 成人精品一区二区三区中文字幕 | 欧美91av | 日韩免费在线一区 | 丁香在线观看完整电影视频 | 久久久不卡影院 | 久久艹在线 | 日日夜夜精品网站 | 婷婷视频在线播放 | 欧美资源在线观看 | 成人精品在线 | 一本一本久久a久久精品综合 | 国产视频一区在线 | 五月天六月婷婷 | 激情深爱五月 | 视频在线观看一区 | 亚洲免费在线播放视频 | 成人免费看视频 | 国产一区二区在线精品 | 天天插综合 | 97在线观看免费高清完整版在线观看 | 国产一级电影 | www黄色av | 国产只有精品 | 国产麻豆剧传媒免费观看 | 69成人在线 | 亚洲综合在线视频 | 亚洲黄色成人 | 全黄网站 | 99精品在线免费 | 国产福利免费看 | a天堂最新版中文在线地址 久久99久久精品国产 | 日本中文字幕在线免费观看 | 久久99久久99久久 | 99久久精品免费看 | 久草| 久久国产福利 | 98涩涩国产露脸精品国产网 | 久久免费黄色大片 | 九九热久久免费视频 | 在线观看免费高清视频大全追剧 | 99久久er热在这里只有精品15 | 91人人在线 | 超碰在线1 | 在线免费视频一区 | 成人免费毛片aaaaaa片 | 国产三级在线播放 | 99热精品免费观看 | 91香蕉视频色版 | 精品在线二区 | 夜夜躁日日躁狠狠久久88av | 米奇狠狠狠888 | 久久国产精品99久久久久久老狼 | 日韩欧美国产成人 | 9ⅰ精品久久久久久久久中文字幕 | 制服丝袜在线91 | 91麻豆网 | 国产中文字幕网 | 国产视频一 | 韩国av免费观看 | 97超碰人人澡人人爱学生 | 日韩av电影中文字幕 | 黄色免费网站 | 日韩在线第一区 | 一色屋精品视频在线观看 | 在线看av的网址 | 福利网址在线观看 | 手机成人av在线 | 超碰人人在线观看 | 天天综合视频在线观看 | 免费a v视频| 国产99久久久国产精品免费二区 | 91精品国产一区二区三区 | 国产色黄网站 | 国产色拍 | 精品1区2区 | 国产精品久久久久久久久久免费看 | 天天色天天爱天天射综合 | www看片网站 | 日韩欧美黄色网址 | 久久精久久精 | 九九九热精品免费视频观看网站 | 在线观看午夜 | 国产在线精品二区 | 菠萝菠萝在线精品视频 | 国产综合精品一区二区三区 | 99看视频在线观看 | 国产精品国产自产拍高清av | 美女亚洲精品 | 成人av网址大全 | 国产精品麻豆果冻传媒在线播放 | 99色免费视频 | 四虎在线免费 | 美女视频黄,久久 | 国产精品免费大片视频 | 五月天激情视频在线观看 | 黄色一级网 | 蜜臀av免费一区二区三区 | 欧美网址在线观看 | 最近中文字幕国语免费av | 成人免费观看电影 | 激情欧美网 | 国产精品一区二区在线播放 | 亚洲精品男女 | 日韩精品观看 | 亚洲热久久| www黄色软件 | 久久国语露脸国产精品电影 | 久久人人爽人人爽 | 成人在线观看你懂的 | 人人澡人 | 美女视频免费精品 | 美女天天操 | 国内外激情视频 | 在线观看一二三区 | www成人精品| 国产精品日韩精品 | 日产乱码一二三区别免费 | 国产视频不卡一区 | 999ZYZ玖玖资源站永久 | 色婷婷啪啪免费在线电影观看 | 欧美日韩免费视频 | 黄色精品视频 | 国产偷在线 | 伊人激情网 | 蜜桃视频日本 | 天天操天天射天天 | 国产精品久久久久久久免费观看 | 欧美色图p| 91精品电影 | 91久久国产精品 | 国产精品久久久久久久久久免费 | 亚洲欧美视频一区二区三区 | 久久精品在线视频 | 美女av免费看 | 久久婷婷一区二区三区 | 国内精品久久久久影院男同志 | 在线观看免费福利 | 探花视频在线观看+在线播放 | 国产丝袜一区二区三区 | 亚洲欧美在线综合 | 亚洲免费婷婷 | 亚洲国产高清在线观看视频 | 免费看三级 | 中文字幕一区二区三区四区久久 | 国产看片免费 | 亚洲一区二区三区毛片 | 97国产在线观看 | 91热视频在线观看 | 丁香激情综合 | 亚洲成人资源在线观看 | 99精品在线免费 | 肉色欧美久久久久久久免费看 | 中文字幕 在线 一 二 | 国产免费人成xvideos视频 | www.com久久 | 欧美一区二区三区不卡 | 成人中心免费视频 | 日日夜夜精品免费观看 | 国产高清av在线播放 | 国产精品中文 | 久草视频在线免费播放 | 日韩欧美国产激情在线播放 | 人人揉人人揉人人揉人人揉97 | 最近高清中文在线字幕在线观看 | 免费中文字幕在线观看 | 天天操天天色综合 | 天天射色综合 | 欧美精品网站 | 亚洲国产操 | 激情视频在线高清看 | 美女国产免费 | 99久久精品免费看国产麻豆 | 国产97在线看 | 欧美激情在线看 | 国产精品久久在线观看 | 五月婷婷激情综合 | 免费视频xnxx com | 久久国内精品视频 | 国产色婷婷精品综合在线手机播放 | 色视频在线免费观看 | 日韩视频一区二区 | 国产va饥渴难耐女保洁员在线观看 | 欧美日韩成人 | 天天操天天操天天操天天操 | 91看国产 | 96精品高清视频在线观看软件特色 | 日韩精品网址 | 最新av免费在线 | 国产精品免费视频一区二区 | 狠狠网| 三三级黄色片之日韩 | 国产免费观看av | 国产香蕉97碰碰碰视频在线观看 | 婷婷丁香五 | 久久久久久久久影院 | 日韩一区二区三免费高清在线观看 | 中文字幕高清视频 | 天天艹天天操 | av网站播放| 97人人模人人爽人人喊网 | 黄色免费大全 | 在线观看av不卡 | 丁香视频免费观看 | 亚洲 欧美日韩 国产 中文 | 久久久影院一区二区三区 | 久草在线视频资源 | 在线国产日本 | 高清精品视频 | 精品久久久久免费极品大片 | 97精品国产97久久久久久免费 | 国产在线永久 | 天无日天天操天天干 | 91精品毛片 | 中文字幕在线观看免费高清完整版 | 又粗又长又大又爽又黄少妇毛片 | 最近中文字幕久久 | 欧美日韩免费观看一区=区三区 | 国产精品一区二区电影 | 亚洲欧美怡红院 | av在线网站观看 | 成人91在线| 四虎www | 中文字幕亚洲欧美日韩2019 | 中文字幕精品在线 | 国产成人精品一区一区一区 | 一区久久久 | 天天色综合三 | 欧美91精品久久久久国产性生爱 | 欧美男同视频网站 | 亚洲电影在线看 | 久久久久国产一区二区三区 | 中文字幕在线观看av | 在线播放91| 中文字幕观看av | 婷婷草 | 亚洲综合在线播放 | 97精品国产97久久久久久春色 | aaa日本高清在线播放免费观看 | 日本久久99| 欧美精品一区二区性色 | 免费久久网站 | 国产精品人成电影在线观看 | 中文字幕日韩高清 | 久久国产精品小视频 | 亚洲成人精品久久 | 亚洲日本国产精品 | 国产精品igao视频网入口 | 亚洲黄在线观看 | 色五月色开心色婷婷色丁香 | 激情狠狠干 | 天天干视频在线 | 成人精品电影 | 日韩精品免费在线观看视频 | 久久中文字幕在线视频 | 亚洲综合在线视频 | www.五月激情.com | 欧美日韩在线播放一区 | 超碰97人人爱 | 成年人免费看的视频 | 91av蜜桃| 激情婷婷综合 | 久草在线中文888 | 日本久久不卡视频 | 人人插人人射 | 久久国产香蕉视频 | 日韩中文字幕第一页 | 亚洲精品午夜久久久久久久 | 一区二区三区不卡在线 | 91人人插 | 狠狠色综合欧美激情 | 狠狠狠干 | 久久少妇免费视频 | 91精品久久久久久综合乱菊 | 久久精品视频在线免费观看 | av免费看av | 九色自拍视频 | 91男人影院| 成人影视免费看 | 在线视频a | 国产一级免费观看视频 | 国产一线二线三线在线观看 | 一区二区精品在线 | 亚洲免费高清视频 | 午夜精品久久久久99热app | 99国产一区二区三精品乱码 | 久久视频在线免费观看 | 久草视频资源 | 99精品视频播放 | 国产色妞影院wwwxxx | 久久成人免费视频 | 91在线观看视频网站 | 久久久官网 | 色夜影院 | 岛国精品一区二区 | 婷婷亚洲综合 | 亚洲精品久久久久久中文传媒 | 日韩精品91偷拍在线观看 | 最近字幕在线观看第一季 | www久久久久 | 国产精品久久精品 | 天天操天天能 | 久久久黄色av | 人人躁| 亚洲影视资源 | 91大神电影 | av三级在线播放 | 在线亚洲精品 | 337p西西人体大胆瓣开下部 | 在线观看91网站 | 亚洲精品视频网站在线观看 | 欧美日本日韩aⅴ在线视频 插插插色综合 | 亚洲欧美视频在线 | 日韩手机在线观看 | 久久久久女教师免费一区 | 伊人永久| 激情五月婷婷丁香 | 一区二区三区中文字幕在线观看 | 激情久久久久久久久久久久久久久久 | 色窝资源 | 欧美激情第一区 | 国产视频一区在线 | 欧美 日韩 国产 成人 在线 | 伊人影院99| 五月导航| 在线观看免费一级片 | 国产精品一区二区三区视频免费 | 婷婷精品进入 | 综合网在线视频 | 亚洲高清视频在线播放 | av成人在线播放 | 国产在线播放一区二区三区 | 国产成人精品在线观看 | 波多野结衣视频在线 | 最新国产精品拍自在线播放 | 国产精品大片免费观看 | 91桃色国产在线播放 | 日韩在线免费小视频 | 综合色站导航 | 69国产精品成人在线播放 | 韩国av永久免费 | 国产96在线 | 国产亚洲精品精品精品 | 国产精品刺激对白麻豆99 | 国产精品国产三级国产专区53 | 国产精品地址 | 日韩字幕| 婷婷福利影院 | 伊人色播| 欧洲一区二区三区精品 | 黄色国产在线 | 在线观看的av | av黄在线播放| 美女久久 | 国产精品久久久久久电影 | 91视频xxxx| 国产自在线 | 亚洲人在线视频 | 玖玖玖精品 | 久热免费在线观看 | 日韩欧美国产免费播放 | 天天天天天干 | 日日夜夜精品免费观看 | 97视频在线免费观看 | 欧美9999 | 欧美性色黄大片在线观看 | 三级a视频| 免费91在线观看 | 日本女人在线观看 | 国产一级免费观看 | 国产精品专区在线观看 | 在线免费av网 | 天天干亚洲 | 在线观看日本高清mv视频 | 黄色电影在线免费观看 | 午夜免费视频网站 | 色综合久久久久久久久五月 | 91精品少妇偷拍99 | 97在线观| 九九爱免费视频在线观看 | 五月的婷婷 | 国产精品视频地址 | 国产精品露脸在线 | 久久精品观看 | 免费日韩 | 337p西西人体大胆瓣开下部 | 四月婷婷在线观看 | 超碰在线97观看 | 欧美国产在线看 | 综合国产在线观看 | 国内精自线一二区永久 | 蜜臀av性久久久久蜜臀aⅴ流畅 | 免费黄色一区 | 久热色超碰 | 亚洲国产日韩欧美在线 | 久草精品网| 超碰在线91 | 99免费在线| 久久99久久99精品免观看粉嫩 | 九九精品在线观看 | 色综合久久久久久中文网 | 天天射天天射天天 | 一区二区三区在线观看免费视频 | 欧美性极品xxxx娇小 | 国产精品99在线播放 | 黄色av一区二区 | 毛片99| 毛片在线网 | 五月天综合色 | av在线播放国产 | 免费一级特黄录像 | 亚洲免费av电影 | 97成人免费 | 日韩视频一区二区在线观看 | 91色偷偷 | 91中文字幕在线播放 | 国产小视频你懂的 | 色网站免费在线观看 | 日韩av电影中文字幕在线观看 | 国精产品999国精产品视频 | 国产一区二区精品91 | 国产精品粉嫩 | 中文字幕永久 | 免费在线成人av电影 | 国产精品99久久久久久久久 | www.黄色小说.com | 国产日韩精品一区二区三区 | 中文字幕日韩一区二区三区不卡 | 国产h片在线观看 | 久草在线91 | 国精产品一二三线999 | 中文字幕在线看视频国产中文版 | 免费看黄在线网站 | 日日草视频 | 中日韩欧美精彩视频 | 日韩资源视频 | 在线国产不卡 | 成人超碰在线 | 狠狠干电影 | 国产精品美乳一区二区免费 | 午夜精品福利一区二区三区蜜桃 | 天天爱天天射天天干天天 | 成av在线 | 国产精品精品久久久久久 | 国产午夜剧场 | 国产福利一区二区三区在线观看 | 国内精品一区二区 | 国产专区一| 日韩精品91偷拍在线观看 | 四虎影视成人永久免费观看视频 | 欧美污在线观看 | 国产又粗又猛又色又黄网站 | 国产不卡在线观看 | 免费99精品国产自在在线 | 欧美性黄网官网 | 亚洲免费国产视频 | 国产一区欧美在线 | 亚洲精品国精品久久99热 | 国产精品va在线播放 | 久久久久国产精品免费免费搜索 | 日韩免费观看高清 | 成人av网站在线 | 99精品免费观看 | 国内外激情视频 | 激情在线网址 | 在线亚洲激情 | 人人添人人澡人人澡人人人爽 | 麻豆视频在线观看免费 | 日韩在线观看中文 | 色视频网站在线观看一=区 a视频免费在线观看 | 久久综合色一综合色88 | 国产高清在线a视频大全 | 成人午夜免费剧场 | 日韩电影精品 | 日韩免费视频观看 | 久久免费国产视频 | 久久r精品 | 综合久久综合久久 | www.色婷婷.com | 一区二区三区在线免费观看视频 | 国产日韩欧美在线影视 | 天天插视频 | 久久精品在线视频 | 91在线91拍拍在线91 | av东方在线 | 天天干天天做 | 精品久久久久久久久久 | 久久国产精品网站 | 久久久性 | 国产亚洲精品久久久久久移动网络 | 久久久久久高清 | 久草在线99 | 天天操天天爽天天干 | 国产一区二区三区网站 | 久久精品这里都是精品 | 午夜av在线播放 | 91丨九色丨蝌蚪丨对白 | 在线观看黄网站 | 国产视频在线观看免费 | 国产在线不卡精品 | 黄色特级一级片 | 九九热在线播放 | 中文字幕 91| 国产精品国产亚洲精品看不卡15 | 美女精品久久久 | 亚洲一区二区精品在线 | 黄p网站在线观看 | 在线免费av网站 | 九九热免费在线视频 | 亚洲综合在线五月 | 久久亚洲影视 | 人人爽人人av| 青青五月天 | 天天综合网在线观看 | 中文字幕影片免费在线观看 | 摸bbb搡bbb搡bbbb | 狠狠躁夜夜躁人人爽超碰97香蕉 | 久久爱导航 | 天天爱天天操天天干 | 91亚洲综合 | 久久综合色播五月 | 国产五月婷| 亚洲成人av免费 | 黄色在线观看污 | 欧美贵妇性狂欢 | 亚洲电影成人 | 免费福利片2019潦草影视午夜 | 精品国产_亚洲人成在线 | 国产欧美精品一区二区三区四区 | 91在线小视频 | 免费亚洲电影 | 日本黄色免费在线 | a色网站| 狠狠干成人综合网 | 三级在线视频观看 | 99av国产精品欲麻豆 | 久久国产精品区 | 欧美精品久久 | 欧美日韩3p| 天天操天天添天天吹 | 综合久久久久 | 色视频在线免费观看 | 在线观看中文字幕dvd播放 | 成年人在线免费看片 | a色视频 | 精品一区在线看 | 日韩在线色视频 | 99热这里只有精品免费 | 亚洲免费黄色 | 久久99精品久久久久久久久久久久 | 在线亚洲播放 | 黄色在线观看网站 | 日韩av一区二区在线 | 午夜婷婷在线观看 | 91精品欧美 | 亚洲经典视频在线观看 | 亚洲精品美女久久 | 国产五月天婷婷 | 少妇bbw撒尿| 国产精品自拍在线 | av中文字幕在线免费观看 | 丁香在线观看完整电影视频 | 日韩色区 | 欧美资源 | 人人舔人人爽 | 日韩精品视频久久 | 久久 在线 | 国产成人精品aaa | 免费看片色 | 久久歪歪 | 中文字幕乱码在线播放 | 亚洲四虎| 午夜精品一区二区三区可下载 | 成片人卡1卡2卡3手机免费看 | 亚洲精品视频在线观看网站 | 国产黄色片在线免费观看 | 久久久精品欧美一区二区免费 | 日日夜夜狠狠操 | 精品欧美在线视频 | 九九久久精品视频 | 久久视频免费在线观看 | 91av视频| 免费精品国产va自在自线 | 久久婷婷五月综合色丁香 | 成 人 黄 色 视频免费播放 | 日韩中文字幕亚洲一区二区va在线 | 500部大龄熟乱视频使用方法 | 亚洲综合网站在线观看 | 国产亚洲视频在线免费观看 | 大型av综合网站 | 日韩专区中文字幕 | 在线影院av | 天天综合网~永久入口 | 亚洲国产欧美一区二区三区丁香婷 | 超碰人人乐 | 天天干天天干天天干 | 午夜视频免费播放 | 91免费观看视频网站 | 亚洲另类在线视频 | 久久国产日韩 | 91成人免费在线 | 337p日本大胆噜噜噜噜 | 久久久久久久久亚洲精品 | 天天插夜夜操 | 亚洲 成人 一区 | 精品国产一区二区久久 | 超碰免费97 | 天天干天天操 | 色av婷婷 | 美女网站色在线观看 | 久久免费久久 | 国产在线播放一区二区 | 日韩在线观看电影 | 黄色av一区二区三区 | 亚洲欧美精品一区二区 | 高清在线一区二区 | 91视频免费网站 | 亚洲欧洲视频 | 天天干夜夜爽 | 成人影音在线 | 91麻豆高清视频 | 国产馆在线播放 | 欧美日韩高清在线一区 | 亚洲干视频在线观看 | 欧美日韩aaaa | 国产无吗一区二区三区在线欢 | 日韩久久久久久 | 亚洲午夜av电影 | 天天射天天爽 | 日韩精品视频在线免费观看 | 在线免费黄色av | 不卡视频一区二区三区 | 在线观看黄色 | 国产精品videossex国产高清 | 亚洲成a人片在线观看中文 中文字幕在线视频第一页 狠狠色丁香婷婷综合 | 91精品国产91久久久久 | 中文字幕久久亚洲 | 黄色av电影一级片 | 天天干天天拍天天操天天拍 | 日韩亚洲欧美中文字幕 | 欧美精品国产综合久久 | 国产高清视频免费观看 | 久久99精品久久久久久秒播蜜臀 | 天天干中文字幕 | 免费中文字幕视频 | 成年人免费在线观看网站 | 久久电影色 | 一区二区三区精品在线 | 中文字幕在线观看视频一区 | 亚洲精品一区二区三区高潮 | 777xxx欧美 | 亚洲精品毛片一级91精品 | 午夜精品久久久久久中宇69 | av软件在线观看 | 手机av看片| 热久久在线视频 | 9992tv成人免费看片 | 日日夜夜精品视频天天综合网 | 亚洲精品国产自产拍在线观看 | 日本最大色倩网站www | 69精品视频 | 日本久久中文 | 久香蕉| 久精品视频在线观看 | 欧美在线视频不卡 | 国产大陆亚洲精品国产 | 国产涩涩在线观看 | 日韩在线播放av | 黄网站app在线观看免费视频 | 欧美另类高清 videos | 黄毛片在线观看 | 人人射网站 | 久99精品 | 热久久免费国产视频 | 人人看人人爱 | 久久久国产精品一区二区三区 | 日韩一区正在播放 | 在线观看韩日电影免费 | 欧美怡红院视频 | 日本在线观看黄色 | 97成人在线视频 | 亚洲五月综合 | 久草在线手机视频 | 日韩精品在线看 | 国产一级性生活视频 | 色99在线| 麻豆国产精品一区二区三区 | 999视频网站 | 99久久99久久精品国产片果冰 | 久操视频在线免费看 | 精品久久影院 | 精品久久一 | 操操日日| 国产三级久久久 | av久久在线| 天天干 天天摸 天天操 | 99热这里有 | 激情狠狠干 | 日韩精品免费 | 国产精品免费成人 | 亚洲最新av在线网站 | 一区二区三区免费 | 99精品热视频 | 婷婷av资源| 国产 视频 高清 免费 | 丁香婷婷色综合亚洲电影 | 国产 精品 资源 | 黄色成人影院 | 777久久久| 日韩色综合 | 亚洲精选久久 | 精品在线不卡 | 激情五月婷婷丁香 | 999视频在线播放 | 日韩黄在线观看 | 在线电影中文字幕 | 91日韩在线播放 | 中文字幕久久久精品 | 热久久国产 | 99免在线观看免费视频高清 | 最近乱久中文字幕 | 草久视频在线 | 日日夜夜天天射 | 国产精品久久久久久久婷婷 | 国产精品18久久久久久首页狼 | 99久久er热在这里只有精品15 | 欧美日韩国产二区 | 99久视频| 最近中文字幕 | 国产人成免费视频 | 亚洲综合国产精品 | 国产五十路毛片 | 欧美一级乱黄 | 久久免费大片 | 国产不卡一二三区 | 黄网在线免费观看 | 久久这里有精品 | 日本久久中文字幕 | 国产成人在线播放 | 国产无区一区二区三麻豆 | 中文字幕在线播放日韩 | 欧美国产不卡 | 波多野结依在线观看 | 99久久er热在这里只有精品15 | 粉嫩aⅴ一区二区三区 | 丁香激情视频 | 日韩中文免费视频 | 成人黄色影片在线 | 在线观看亚洲免费视频 | 久久婷婷国产色一区二区三区 | 欧美日韩性视频在线 | 最近中文字幕高清字幕免费mv | 天天摸天天干天天操天天射 | 亚洲国产精品电影 | 69精品人人人人 | 在线草| 久久a视频 | 五月天丁香亚洲 | 人人草在线视频 | 天天干天天摸 | 亚州av网站大全 | 99久视频| 激情自拍av | 在线观看免费观看在线91 | 婷婷久久亚洲 | 国产成人精品一二三区 | 美女视频黄是免费的 | 国产 日韩 欧美 中文 在线播放 | 欧美黑人xxxx猛性大交 | 成年人在线观看网站 | 欧美日韩高清在线一区 | 国产黄色播放 | 9草在线| 国产精美视频 | 黄网站色视频免费观看 | 国内免费的中文字幕 | 亚洲精品一区二区三区在线观看 | 高潮久久久久久久久 | 久操视频在线观看 | 天天色天天上天天操 | 欧美日韩xxx | 日韩另类在线 | 91色在线观看 | 国产日韩欧美在线 | 亚洲作爱视频 | 亚洲婷婷综合色高清在线 | 97色资源 | 久草视频在线免费 | 日韩激情久久 | 精品国产伦一区二区三区观看方式 | 婷婷丁香视频 | 亚洲在线视频免费 | 这里只有精品视频在线观看 | 国产成人精品一区二区在线 | 日韩精品一区二区三区免费视频观看 | 四虎最新入口 | 日日操日日操 | 色视频一区| 最新超碰在线 | 国产香蕉av | 国产婷婷vvvv激情久 | 日韩在线不卡视频 | 亚洲欧美国产精品va在线观看 | 操天天操 | 欧美日韩激情视频8区 | 国产精品video爽爽爽爽 | 日韩精品一区在线播放 | 99婷婷| 午夜12点 | 日韩欧美国产视频 | 日韩视频区 | 亚洲精品女 | 午夜精品久久一牛影视 | 免费看国产曰批40分钟 | 色网站免费在线观看 | 亚洲一区二区视频在线 | 激情网站网址 | 国产精品一区二区麻豆 | 激情喷水 | 精品在线观看国产 | 日本久久久影视 | 亚州精品天堂中文字幕 | 五月天丁香视频 | 狠狠久久婷婷 | 国产一级免费av | 亚洲美女在线一区 | 中文字幕乱偷在线 | 久久久午夜视频 | 久久爱资源网 | 日本中文字幕免费观看 | 亚洲欧美视频在线 | 国产黄色大片免费看 | 成人国产精品久久久 | 久久免费视频在线 | 国产成人一二三 | 国产一级黄色电影 | 亚洲精品国偷拍自产在线观看 | 亚州精品成人 | 四虎在线视频免费观看 | 玖玖视频国产 | 精品久久久久久久久久久院品网 | 婷婷丁香在线 | av中文天堂 | 99精品久久久久久久久久综合 | 天天干天天干天天干天天干天天干天天干 | 成人资源站 | 日韩av快播电影网 | 精品一区二区三区在线播放 | 在线国产片 | 久久在线精品 | 色婷婷综合五月 | 精品国产一区二区三区在线 | 在线视频日韩一区 | 91亚洲精品国偷拍自产在线观看 | 亚洲精品乱码久久久久久蜜桃欧美 | 麻豆精品在线视频 | 国产精品入口久久 | 国内精品二区 | 中文字幕精品www乱入免费视频 | 久草香蕉在线 | 91激情视频在线 | 欧美色婷婷 | 99热超碰 | 美女视频永久黄网站免费观看国产 | 国产情侣一区 | 国内精品久久天天躁人人爽 | 超碰午夜 | 精品美女在线视频 | 国产亚洲一区 | 日日夜夜天天人人 | 国产精品美女久久久 | 2019精品手机国产品在线 | 欧美午夜精品久久久久久浪潮 | 韩国精品一区二区三区六区色诱 | 99精品视频在线观看播放 | 国产中文字幕视频在线观看 | www.夜夜操 | 成人动态视频 | 97成人在线免费视频 | 国产区第一页 | 免费视频一级片 | 日韩在线观看你懂得 | 日韩视频区 | 日韩视频一区二区三区 | 在线免费三级 | 久久免费视频7 | 永久免费毛片 | 成年人电影毛片 | 国产亚洲精品成人av久久ww | 午夜精品一区二区三区在线 | 亚洲综合涩 | 国产 视频 高清 免费 | 在线欧美最极品的av | 人人舔人人舔 | 人人澡人摸人人添学生av | 欧美肥妇free | 国产精彩视频一区二区 | 国产精品国产三级国产 | 亚洲精品免费在线播放 | 亚洲一区精品二人人爽久久 | 日韩精品视频一二三 | 97香蕉超级碰碰久久免费软件 | 青青看片 | 激情电影在线观看 | 永久免费观看视频 | 日本不卡一区二区三区在线观看 | 欧美激情精品一区 | 97天天干| 国产又粗又猛又黄又爽的视频 | 91在线小视频 | 精品一区二区三区四区在线 | 色夜视频 | 国产精品久久久久久久久软件 | 久久久96 | 久久字幕网 | 天天射天天操天天干 | 综合色影院| 香蕉视频国产在线 | av在线播放亚洲 | 久久艹艹| 日韩理论影院 | 美女性爽视频国产免费app | 国产精品69av | 国产成人精品一区二区三区在线观看 | 亚洲天天在线 | 久久综合亚洲鲁鲁五月久久 | 天天干天天操av | 婷婷免费视频 | 精品视频一区在线 | 日韩色区 | 一区二区视频在线观看免费 | 黄色毛片网站在线观看 | 999久久国精品免费观看网站 | 欧美午夜久久 | 免费a视频在线 | av在线精品 | 久久新视频| 色视频在线观看免费 | 成人午夜在线电影 | 国产视频一区在线免费观看 |