Spring Security JWT登录新增账号校验及自定义异常状态码咨询
Spring Security 新增账号激活状态校验方案
1. 改造用户查询逻辑(ApplicationUserDetailsService)
Spring Security 内置的 UserDetails 接口原生提供 isEnabled() 方法用于标识账号是否可用,我们直接将数据库中存储的 isActive 字段映射到该属性即可,框架会自动完成基础校验:
@Override public UserDetails loadUserByUsername(String nickname) throws UsernameNotFoundException { Optional<ApplicationUser> applicationUser = applicationUserRepository.findByNickname(nickname); if (!applicationUser.isPresent()) { throw new UsernameNotFoundException(nickname); } ApplicationUser currentUser = applicationUser.get(); // 使用全参数构造User,参数依次为:用户名、密码、是否启用、账户未过期、凭证未过期、账户未锁定、权限列表 return new User( currentUser.getNickname(), currentUser.getPassword(), currentUser.isActive(), true, true, true, emptyList()); }
如果你希望使用自定义的 UserIsNotActiveException,也可以在查询到用户后直接判断激活状态,主动抛出异常即可。
2. 重写认证失败处理逻辑(AuthenticationFilter)
默认的 UsernamePasswordAuthenticationFilter 所有认证失败场景都会返回401状态码,我们需要重写失败处理方法,根据异常类型返回不同状态码:
@Override protected void unsuccessfulAuthentication(HttpServletRequest request, HttpServletResponse response, AuthenticationException failed) throws IOException, ServletException { response.setContentType("application/json;charset=UTF-8"); // 账号未激活场景,返回403 if (failed instanceof DisabledException) { response.setStatus(HttpServletResponse.SC_FORBIDDEN); response.getWriter().print("账号未激活,请先完成激活后再登录"); } // 用户名不存在/密码错误场景,返回401 else if (failed instanceof UsernameNotFoundException || failed instanceof BadCredentialsException) { response.setStatus(HttpServletResponse.SC_UNAUTHORIZED); response.getWriter().print("用户名或密码错误"); } // 其他认证错误默认返回401 else { response.setStatus(HttpServletResponse.SC_UNAUTHORIZED); response.getWriter().print("认证失败"); } }
如果上一步你使用了自定义的 UserIsNotActiveException,只需要把异常判断条件替换为对应的自定义异常类型即可。
3. 可选:JWT请求阶段的激活状态校验
如果需要实现账号被禁用后,已颁发的JWT也立即失效的效果,可以在 AuthorizationFilter 中拿到JWT对应的用户名后,再次查询数据库校验激活状态,不符合要求直接返回空的认证信息即可。
内容的提问来源于stack exchange,提问作者Juan Ignacio López
相关产品推荐
相关产品推荐

