记录一个坑

在做spring security JWT登录验证的时候写了一个filter

public class JwtAuthenticationTokenFilter extends BasicAuthenticationFilter {

    @Value("${token.header}")
    private String token_header;

    @Autowired
    private UserDetailsServiceImpl userDetailsService;

    @Autowired
    private TokenUtils jwtUtils;

    public JwtAuthenticationTokenFilter(AuthenticationManager authenticationManager) {
        super(authenticationManager);
    }

    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain) throws ServletException, IOException {

       /* if (request.getMethod().equals(String.valueOf(RequestMethod.GET))) {
            chain.doFilter(request, response);
            return;
        }*/

        String auth_token = request.getHeader(this.token_header);
        final String auth_token_start = "Bearer ";
        if (!StringUtils.isEmpty(auth_token) && auth_token.startsWith(auth_token_start)) {
            auth_token = auth_token.substring(auth_token_start.length());
        } else {
            // 不按规范,不允许通过验证
            auth_token = null;

        }

        String username = jwtUtils.getUsernameFromToken(auth_token);

        logger.info(String.format("Checking authentication for user %s.", username));

        // 如果上面解析 token 成功并且拿到了 username 并且本次会话的权限还未被写入
        if (username != null && SecurityContextHolder.getContext().getAuthentication() == null) {
           // User user = jwtUtils.getUserFromToken(auth_token);
            // 用 UserDetailsService 从数据库中拿到用户的 UserDetails 类
            // UserDetails 类是 Spring Security 用于保存用户权限的实体类
            UserDetails userDetails = userDetailsService.loadUserByUsername(username);
            // 检查用户带来的 token 是否有效
            // 包括 token 和 userDetails 中用户名是否一样, token 是否过期, token 生成时间是否在最后一次密码修改时间之前
            // 若是检查通过
            if (jwtUtils.validateToken(auth_token, userDetails)) {
                // 生成通过认证
                UsernamePasswordAuthenticationToken authentication = new UsernamePasswordAuthenticationToken(userDetails, null, userDetails.getAuthorities());
                authentication.setDetails(new WebAuthenticationDetailsSource().buildDetails(request));
                logger.info(String.format("Authenticated user %s, setting security context", username));
                // 将权限写入本次会话
                SecurityContextHolder.getContext().setAuthentication(authentication);
            }
        }
        chain.doFilter(request, response);
    }
}

当时的tokenUtils与userDetailServiceImp注入不进来,一直为空

@Configuration
@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {

    @Autowired
    private UserDetailsServiceImpl userDetailsService;

    @Autowired
    private JwtLoginFilter jwtLoginFilter;

    @Bean
    @Override
    public AuthenticationManager authenticationManagerBean() throws Exception {
        return super.authenticationManagerBean();
    }
    @Bean
    public BCryptPasswordEncoder bCryptPasswordEncoder(){
        return new BCryptPasswordEncoder();
    }

    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.userDetailsService(userDetailsService).passwordEncoder(bCryptPasswordEncoder());
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
                .authorizeRequests()
                .antMatchers("/task/**").authenticated()       // 需携带有效 token
              /*  .antMatchers("/admin").hasAuthority("admin")   // 需拥有 admin 这个权限
                .antMatchers("/ADMIN").hasRole("ADMIN")     // 需拥有 ADMIN 这个身份*/
                .anyRequest().permitAll()
                .and()
                .csrf()
                .disable()                      // 禁用 Spring Security 自带的跨域处理
                .sessionManagement()                        // 定制我们自己的 session 策略
                .sessionCreationPolicy(SessionCreationPolicy.STATELESS)// 调整为让 Spring Security 不创建和使用 session                 .and()                 .addFilter(new JwtLoginFilter(authenticationManagerBean()))                 .addFilter(new JwtAuthenticationTokenFilter(authenticationManagerBean())); 


}

在websecurityconfig这里addfFilter当时直接new了一个对象放进去的,原来就是因为是new的对象并不在spring容器里,所以注入不进去。

@Autowired注入Spring Bean,则当前类必须也是Spring Bean才能调用它,不能用new xxx()来获得对象,这种方式获得的对象无法调用@Autowired注入的Bean。

后来直接改用@bean的或者直接加@component注解的方式将自定义filter加入到spring容器中就可以啦!

原文地址:https://www.cnblogs.com/yyZNL/p/11576058.html

时间: 2024-11-05 12:24:36

记录一个坑的相关文章

RecycleView设置顶部分割线(记录一个坑)

大家都知道,想给RecycleView设置分割线可以重写RecyclerView.ItemDecoration 项目过程中,遇到一个需求:RecycleView顶部有一条灰色的间隔,我想到了给RecycleView设置分割线的方法,当然只给第一个Item设置,而且在上方. public class MyDividerItemDecoration extends RecyclerView.ItemDecoration { private Drawable mDivider; /** * Custo

H5+ app 记录一个坑 希望有缘人可以解决这个问题

最新少主在开发一款公益的web APP  用的是h5 +  然后打包的 少主两部手机 拿来测试 发现有一部手机出了问题 应用没有缓存 一离开应用就注销了 之后才知道 原来是自己设置了一个东西 在开发者模式 应用 [不保留活动 ] 这个不要开~~~ 开了 应用就没有缓存了 然后再进入就重新开发了 然后假如有授权登陆的话 直接授权不了~~~ (OK 已经解决 部分手机设置了 不保留活动 在开发者选项 应用 用户离开后即撤销每个活动 这个不能开~~!!) 原文地址:https://www.cnblog

【Java记录】try-with-resources的一个坑

[Java记录]try-with-resources的一个坑 今天处理 AsynchronousFileChannel 时候的一个问题,代码如下: public static void main(String[] args) throws Exception { String filePath = "/home/xe/git/osc/JavaNote/Lang/data/Test.java"; ExecutorService executorService = Executors.ne

记录我开发工作中遇到HTTP跨域和OPTION请求的一个坑

我通过这篇文章把今天工作中遇到的HTTP跨域和OPTION请求的一个坑记录下来. 场景是我需要在部署在域名a的Web应用里用JavaScript去消费一个部署在域名b的服务器上的服务.域名b上的服务也是我开发的,因此我将域名a加到了该服务的HTTP响应结构的头文件里,这样就允许了域名a上的JavaScript代码用AJAX访问域名b的服务. 域名b上的服务是一个Servlet,允许域名a跨域访问的代码就一行: protected void doGet(HttpServletRequest req

再次记录 Visual Studio 2015 CTP 5 的一个坑

升级到 VS2015 CTP 之后,今天要改项目中的一个东西,然后就不得不把 C# 6.0 改变的语法代码中改了下(之前没改,大约200多个),首先,比如下面示例代码: var fullName = "\{customer.FirstName} \{customer.LastName}"; 项目中有很多这样的类似代码,这些都得改掉,怎么办?手动改???算了,还是批量修改吧,但是怎么批量替换呢,难道直接把"\ {"替换成"{",但是"$&

移动端开发碰到一个坑

移动端开发真是不断踩坑,今天在做一个移动端的组件,又发现了一个坑,记录到日志里面,做个记录,以便以后再遇到这个问题有个记录可以参考. 在ios中的chrome浏览器中,手指从屏幕上方移动出屏幕(一定要经过屏幕边缘划出屏幕)时,不能触发touchend的事件,但是这个touchend事件并不是消失了,而是等到下次触摸屏幕的时候才会触发. 这个问题搞得我想到无奈,我的需求是一个容器内做一个动画,当手指离开屏幕时,也就是touchend时启动这个动画,有了这个问题,当手指是经过屏幕上边缘而离开屏幕是,

MySQL多表更新的一个坑

简述 MySQL支持update t1,t2 set t1.a=2;这种语法,别的关系数据库例如oracle和sql server都不支持.这种语法有时候写起来挺方便,但他有一个坑. 测试脚本 drop database fander; create database fander; use fander; create table t1(a int); create table t2(a int); insert into t1 value(1); select * from t1; upda

踩到Framework7 Photo Browser 的一个坑

最近在做的项目用了Framework7前端框架,功能确实比较强大!但这两天遇到一个坑,希望我的这点收获能给遇到这个问题的朋友一点帮助. 在使用Photo Browser 的时候,图片下方想放一个“点赞”的按钮,耐何就死活无法响应鼠标的点击事件(click tap都不行).怀疑被父级元素拦截了,反复各种折腾就是没效果! 最后都要放弃的时候,都准备移除“点赞”功能了,无意中发现.photo-browser-captions这个层有个样式是 pointer-events: none; 翻了一下CSS手

PHP中逻辑运算符and/or与||/&&的一个坑

我原来以为PHP中的and和&&是一样的, 只是写法上为了可读性和美观, 事实上我错了. 这里面深藏了一个坑! 看以下代码: $bA = true; $bB = false; $b1 = $bA and $bB; $b2 = $bA && $bB; var_dump($b1); // $b1 = true var_dump($b2); // $b2 = false $bA = false; $bB = true; $b3 = $bA or $bB; $b4 = $bA ||