spring-security完善登录失败信息反馈

security用户名不存在和密码错误等反馈信息是通过捕获异常传递的,所以我们在登录失败处理器中判断一下异常属于哪一个,就可以直到是用户名错了还密码错误了等等情况,再根据需求定制返回信息就行了。
用户名不存在:UsernameNotFoundException;
密码错误:BadCredentialException;
帐户被锁:LockedException;
帐户未启动:DisabledException;
密码过期:CredentialExpiredException;等等!

    public AuthenticationFailureHandler failureHandler(){
        return new AuthenticationFailureHandler() {
            @Override
            public void onAuthenticationFailure(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, AuthenticationException e) throws IOException, ServletException {
                httpServletResponse.setCharacterEncoding("utf-8");
                httpServletResponse.setContentType("application/json;charset=utf-8");
                PrintWriter writer = httpServletResponse.getWriter();
                if(e.getClass().equals(UsernameNotFoundException.class)){
                    //此时异常属于用户名不存在
                    writer.println(JSONUtil.toJsonStr(JsonResult.failure("用户名不存在!")));
                }else {
                    //此时异常属于密码错误
                    writer.println(JSONUtil.toJsonStr(JsonResult.failure("密码错误!")));
                }
                writer.flush();
                writer.close();
            }
        };
    }

这里有个小问题security默认的AbstractUserDetailsAuthenticationProvider的authenticate方法,设置了hideUserNotFoundExceptions = true,这里直接就覆盖了UsernameNotFoundException异常并抛出BadCredentialsException异常所以捕获不到UsernameNotFoundException异常,所以我们要重写一下这里

  @Bean
    public AuthenticationProvider daoAuthenticationProvider() {
        DaoAuthenticationProvider daoAuthenticationProvider = new DaoAuthenticationProvider();
        daoAuthenticationProvider.setUserDetailsService(userDetailsService);
        daoAuthenticationProvider.setPasswordEncoder(passwordEncoder());
        daoAuthenticationProvider.setHideUserNotFoundExceptions(false);
        return daoAuthenticationProvider;
    }


        @Override
    public void configure(AuthenticationManagerBuilder auth) throws Exception {
        //springsecurity通过userDetailsService的loadUserByUsername方法
        //去数据库里查询用户并认证
//        auth.userDetailsService(userDetailsService)
//                //设置密码加密方式,默认为BCryptPasswordEncoder,也是springsecurity默认的密码加密方式
//                //这个必须要
//                .passwordEncoder(passwordEncoder());
            auth.authenticationProvider(daoAuthenticationProvider());
    }

还要记得在UserDetailsService里抛出一下异常

public class UserDetailsServiceImpl implements UserDetailsService {

    @Autowired
    private UserInfoService userInfoService;


    @Override
    public UserDetails loadUserByUsername(String userName){
       //通过用户名查找用户
        UserInfo user = userInfoService.findByUserName(userName);
        LoginUser loginUser = new LoginUser();
        if (user==null){
            //用户为为空直接抛出异常
            throw new UsernameNotFoundException("用户名未找到");

        }else {
            //将查找的用户封装到LoginUser类中
            loginUser.setUserInfo(user);
        }
        return loginUser;
    }
}
  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值