問題背景:新項目使用Springboot框架,鑒權使用了Jwt
處理cors:
@Configuration public class WebMvcConfig implements WebMvcConfigurer { @Override public void addCorsMappings(CorsRegistry registry) { registry.addMapping("/**") .allowedHeaders("*") .allowedMethods("*") .allowedOrigins("*") .allowCredentials(true); } }
使用自定義Jwt鑒權:
@Configuration @EnableWebSecurity @EnableGlobalMethodSecurity(prePostEnabled = true) public class WebSecurityConfig extends WebSecurityConfigurerAdapter { @Autowired JwtAuthenticationEntryPoint unauthorizedHandler; @Autowired RestAuthenticationAccessDeniedHandler accessDeniedHandler; @Autowired CustomUserDetailsServiceImpl CustomUserDetailsService; @Autowired JwtAuthenticationTokenFilter authenticationTokenFilter; @Autowired private MyPermissionEvaluator myPermissionEvaluator; @Autowired public void configureAuthentication(AuthenticationManagerBuilder authenticationManagerBuilder) throws Exception { authenticationManagerBuilder // 設置UserDetailsService .userDetailsService(CustomUserDetailsService) // 使用BCrypt進行密碼的hash .passwordEncoder(passwordEncoder()); } /** * 裝載BCrypt密碼編碼器 * @return */ @Bean public PasswordEncoder passwordEncoder() { return new BCryptPasswordEncoder(); } @Override protected void configure(HttpSecurity httpSecurity) throws Exception { httpSecurity .exceptionHandling().accessDeniedHandler(accessDeniedHandler).and() .cors().and()//烏龍在這行,一開始沒有配置這個//如果您使用的是Spring Security,請確保在Spring Security級別啟用CORS,以允許它利用Spring MVC級別定義的配置。
//烏龍在這行,一開始沒有配置這個 //烏龍在這行,一開始沒有配置這個 // 由於使用的是JWT,我們這里不需要csrf .csrf().disable() .exceptionHandling().authenticationEntryPoint(unauthorizedHandler).and() // 基於token,所以不需要session .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS).and() .authorizeRequests() // 對於獲取token的rest api要允許匿名訪問 .antMatchers("/admin/login", "/admin/register","/error/**").permitAll() // 除上面外的所有請求全部需要鑒權認證 .anyRequest().authenticated(); // 禁用緩存 httpSecurity.headers().cacheControl(); // 添加JWT filter httpSecurity .addFilterBefore(authenticationTokenFilter, UsernamePasswordAuthenticationFilter.class); } @Override public void configure(WebSecurity web) { web .ignoring().antMatchers(HttpMethod.OPTIONS, "/**").and() .ignoring() .antMatchers( "/favicon.ico", "/**/*.css", "/**/*.js", "/**/*.png", "/**/*.gif", "/**/*.ttf" ); } @Bean @Override public AuthenticationManager authenticationManagerBean() throws Exception { return super.authenticationManagerBean(); } /** * 注入自定義PermissionEvaluator */ @Bean public DefaultWebSecurityExpressionHandler webSecurityExpressionHandler(){ DefaultWebSecurityExpressionHandler handler = new DefaultWebSecurityExpressionHandler(); handler.setPermissionEvaluator(myPermissionEvaluator); return handler; } }
然后就出問題了:登錄后使用token Jwt鑒權正常,前端跨域正常,但是當token失效后接口200 但是拿不到數據
這個樣子 This request has no response data available
用postman請求正常:報token失效
由於之前解決了跨域問題就沒考慮跨域,懷疑的方向是Jwt攔截后沒有處理返回或者dochain斷掉了
后來看了下瀏覽器的console發現token失效后出現了跨域問題,
搜索發現security配置里少了一個配置:.cors().and()
如果使用的是Spring Security,請確保在Spring Security級別啟用CORS,以允許它利用Spring MVC級別定義的配置。
好吧,security沒有啟用cors
fixed 一切正常