山有木兮丶丶 2021-10-27 18:09 采纳率: 80%
浏览 734
已结题

spring security重写UsernamePasswordAuthenticationFilter后记住我失效

因为security不支持JSON数据登录,就重写了UsernamePasswordAuthenticationFilter里面的attemptAuthentication方法,代码如下

public class CustomAuthenticationFilter extends UsernamePasswordAuthenticationFilter {

    private AuthenticationBean authenticationBean = null;

    @Override
    public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response) throws AuthenticationException {
        //use jackson to deserialize json
        ObjectMapper mapper = new ObjectMapper();
        UsernamePasswordAuthenticationToken authRequest = null;
        try (InputStream is = request.getInputStream()){
            AuthenticationBean authenticationBean = mapper.readValue(is,AuthenticationBean.class);
            authRequest = new UsernamePasswordAuthenticationToken(authenticationBean.getUsername(), authenticationBean.getPassword());
        }catch (IOException e) {
            e.printStackTrace();
            authRequest = new UsernamePasswordAuthenticationToken("", "");
        }finally {
            setDetails(request, authRequest);
            return this.getAuthenticationManager().authenticate(authRequest);
        }
    }
}

然后在WebSecurityConfig中加入了这个过滤器。

http.addFilterAt(customAuthenticationFilter(), UsernamePasswordAuthenticationFilter.class);

@Bean
    CustomAuthenticationFilter customAuthenticationFilter() throws Exception {
        CustomAuthenticationFilter filter = new CustomAuthenticationFilter();
        filter.setAuthenticationSuccessHandler(authenticationSuccessHandler);
        filter.setAuthenticationFailureHandler(authenticationFailureHandler);
        filter.setFilterProcessesUrl("/login");

        //这句很关键,重用WebSecurityConfigurerAdapter配置的AuthenticationManager,不然要自己组装AuthenticationManager
        filter.setAuthenticationManager(authenticationManagerBean());
        return filter;
    }

此时可以用JSON传账号密码登录了,然后我又增加了记住我的相关配置。

.and().rememberMe()
                .rememberMeParameter("remember_me")
                .tokenRepository(persistentTokenRepository())
                .tokenValiditySeconds(60).userDetailsService(userDetailsService())

@Bean
    public PersistentTokenRepository persistentTokenRepository(){
        JdbcTokenRepositoryImpl tokenRepository = new JdbcTokenRepositoryImpl();
        tokenRepository.setDataSource(dataSource);
        System.out.println("启动了记住我。。。");
        //在第一次运行时会创建一个记住我token数据库,只能运行一次
//        tokenRepository.setCreateTableOnStartup(true);
        return tokenRepository;
    }

发现登录成功后没有返回cookie,数据库中也没存有相应的cookie。
但是我把

http.addFilterAt(customAuthenticationFilter(), UsernamePasswordAuthenticationFilter.class);

注释掉,用原始表单的方式登录,记住我又能正常用,前端能接收到cookie,数据库也存了cookie

  • 写回答

1条回答 默认 最新

  • Forrest Gump plus 2021-10-27 18:50
    关注

    自定义的过滤器应该放在之前

    img


    所以你把代码改成下面的就可以了,在UsernamePasswordAuthenticationFilter之前过滤

    http.addFilterBefore(customAuthenticationFilter(), UsernamePasswordAuthenticationFilter.class);
    
    
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

问题事件

  • 系统已结题 11月5日
  • 已采纳回答 10月28日
  • 创建了问题 10月27日

悬赏问题

  • ¥15 【提问】基于Invest的水源涵养
  • ¥20 微信网友居然可以通过vx号找到我绑的手机号
  • ¥15 spring后端vue前端
  • ¥15 寻一个支付宝扫码远程授权登录的软件助手app
  • ¥15 解riccati方程组
  • ¥15 display:none;样式在嵌套结构中的已设置了display样式的元素上不起作用?
  • ¥15 使用rabbitMQ 消息队列作为url源进行多线程爬取时,总有几个url没有处理的问题。
  • ¥15 Ubuntu在安装序列比对软件STAR时出现报错如何解决
  • ¥50 树莓派安卓APK系统签名
  • ¥65 汇编语言除法溢出问题