记录使用springsecurity整合jwt时静态资源访问及过滤器顺序异常

1 篇文章 0 订阅
1 篇文章 0 订阅

记录使用springsecurity整合jwt时静态资源访问及过滤器顺序异常

首先晒出我的security错误配置

 http.addFilterBefore(new JwtLoginFilter(authenticationManager()), UsernamePasswordAuthenticationFilter.class)
                // 访问控制时登录状态检查过滤器
                .addFilterBefore(new JwtAuthenticationFilter(authenticationManager()), UsernamePasswordAuthenticationFilter.class);
                //此处需要注意 自定义资源权限认证过滤器需要在异常处理过滤器之后  因为资源权限认证过滤器一般位于登录认证的最后 如果异常过滤器在资源认证过滤器后 将不会生效
                .addFilterAfter(getMyFilterSecurityInterceptor(), ExceptionTranslationFilter.class)
                .exceptionHandling().accessDeniedHandler(new MyAccessDeineHandler()).authenticationEntryPoint(new MyAuthenticationEntryPoint())
                .and()
                // 禁用 csrf, 由于使用的是JWT,我们这里不需要csrf
                .cors().and().csrf().disable()
                .headers().frameOptions().disable();
        // 退出登录处理器
        http.logout().logoutUrl("/loginout").logoutSuccessHandler(new MyLoginOutSuccessHandler());
        //禁用session
        http.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.NEVER);
               .authorizeRequests()
               // 跨域预检请求
                .antMatchers(HttpMethod.OPTIONS, "/**").permitAll()
                // 登录URL
               .antMatchers("/login").permitAll()
               .antMatchers("/index.html").permitAll()
                .antMatchers("/static/**").permitAll()
                .antMatchers("/favicon.ico").permitAll()
                // swagger
                .antMatchers("/swagger**/**").permitAll()
                .antMatchers("/webjars/**").permitAll()
                .antMatchers("/v2/**").permitAll()
                // 其他所有请求需要身份认证
               .anyRequest().authenticated();
        

首先 乍一看我这配置没什么问题,登录及权限测试都没啥问题。
但是

问题一:退出登录传递到指定处理类时,authentication值为空,无法退出登录对redis中token做退出处理

在这里插入图片描述

原因:

因为使用jwt的原因 我自定义jwt token验证过滤器JwtAuthenticationFilter(看我上面的配置),并将此过滤器置于UsernamePasswordAuthenticationFilter之前。JwtAuthenticationFilter中我用于验证token,并且组装authentication放入SecurityContextHolder中。经过我断点得知,logoutFilter过滤器位于我自定义过滤器之前,所以不论退出登录多少次,首先经过的就是logoutFilter,而不会到达JwtAuthenticationFilter 无法组装authentication信息。

问题二:当我把前端vue项目打包到我的项目中时,无法访问到页面

在这里插入图片描述

原因:

上文中配置了静态资源过滤,但是并没有起到作用
在这里插入图片描述
因为我的自定义过滤器中有token验证过滤器,会对所有请求进行token验证,无论是访问静态资源还是访问接口。但我明明配置静态资源过滤,可还是会被我的过滤器拦截。
无论如何调换过滤器位置,都无法躲过我的过滤器,所以不能使用这种放行,所以配置

public void configure(WebSecurity web) {
        //解决静态资源被拦截的问题
        web.ignoring().antMatchers("/static/**","/favicon.ico","/error","/index.html");
    }

来解决这个问题,这种配置会直接跳过过滤器,不经过过滤器过滤,打断点可以看到
在这里插入图片描述我在请求一进来的applicationFilterConfig过滤中, 我们可以看到spring security的过滤器点进去:
在这里插入图片描述
配置静态资源不会经过springsecurity的过滤器。
正确配置:

@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {

    //自定义用户认证
    @Bean
    public UserDetailsService userDetailsService(){
        return new UserDetailsServiceImpl();
    }
    //加密算法生成bean
    @Bean
    public BCryptPasswordEncoder bCryptPasswordEncoder(){
        return new BCryptPasswordEncoder();
    }

    @Override
    public void configure(AuthenticationManagerBuilder auth) throws Exception {
        // 使用自定义登录身份认证组件
        JwtAuthenticationProvider jwtAuthenticationProvider = new JwtAuthenticationProvider(userDetailsService());
        jwtAuthenticationProvider.setPasswordEncoder(new MyPasswordEncoder());
        auth.authenticationProvider(jwtAuthenticationProvider);
    }

    @Override
    public void configure(WebSecurity web) {
        //解决静态资源被拦截的问题
        web.ignoring().antMatchers("/static/**","/favicon.ico","/error","/index.html");
    }


    @Override
    protected void configure(HttpSecurity http) throws Exception {


        // 开启登录认证流程过滤器
        http.addFilterBefore(new JwtLoginFilter(authenticationManager()), LogoutFilter.class)
                // 访问控制时登录状态检查过滤器
                .addFilterBefore(new JwtAuthenticationFilter(authenticationManager()), LogoutFilter.class)
                //此处需要注意 自定义资源权限认证过滤器需要在异常处理过滤器之后  因为资源权限认证过滤器一般位于登录认证的最后 如果异常过滤器在资源认证过滤器后 将不会生效
                .addFilterAfter(getMyFilterSecurityInterceptor(), ExceptionTranslationFilter.class)
                .exceptionHandling().accessDeniedHandler(new MyAccessDeineHandler()).authenticationEntryPoint(new MyAuthenticationEntryPoint())
                .and()
                // 禁用 csrf, 由于使用的是JWT,我们这里不需要csrf
                .cors().and().csrf().disable()
                .headers().frameOptions().disable();
        // 退出登录处理器
        http.logout().logoutUrl("/loginout").logoutSuccessHandler(new MyLoginOutSuccessHandler());
        //禁用session
        http.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.NEVER);
    }

    @Bean
    @Override
    public AuthenticationManager authenticationManager() throws Exception {
        return super.authenticationManager();
    }

    public MyFilterSecurityInterceptor getMyFilterSecurityInterceptor() throws Exception {
        MyFilterSecurityInterceptor myFilterSecurityInterceptor = new MyFilterSecurityInterceptor();
        myFilterSecurityInterceptor.setAuthenticationManager(authenticationManager());
        myFilterSecurityInterceptor.setAccessDecisionManager(new MyAccessDecisionManager());
        myFilterSecurityInterceptor.setSecurityMetadataSource(new MyInvocationSecurityMetadataSource());
        return myFilterSecurityInterceptor;
    }

}

记得双击么么哒,评论区留言问题我会一一解答

  • 4
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值