众所周知,在Spring secrity中,密码验证由框架进行,但在实际项目开发中,交给secrity原生处理就显得有点局限了。而我们要做的自定义登录,就要去重写一些内容了。
首先,继承UsernamePasswordAuthenticationFilter 去重写下方方法,获取自定义登录接口的相关信息,再对用户名和密码处理。
@Override
public Authentication attemptAuthentication(HttpServletRequest request,
HttpServletResponse response) throws AuthenticationException {
// 从输入流中获取到登录的信息
// UserVerify loginUser = new ObjectMapper().readValue(request.getInputStream(), UserVerify.class);
String username = request.getParameter("usercode");
String password = request.getParameter("password");
return authenticationManager.authenticate(
new UsernamePasswordAuthenticationToken(username, password)
);
之后,spring会通过你设置的密码加密方式以及loadUserByUsername方法中的逻辑进行验证,再之后的验证成功与否会有不同的处理。
//登陆成功处理
@Override
protected void successfulAuthentication(HttpServletRequest request,
HttpServletResponse response,
FilterChain chain,
Authentication authResult) {
UserVerify jwtUser = (UserVerify) authResult.getPrincipal();
Integer id = jwtUser.getId();
String usercode = jwtUser.getUsercode();
String username = jwtUser.getUsername();
String password = jwtUser.getPassword();
String faculty = jwtUser.getFaculty();
List<GrantedAuthority> authorities = jwtUser.getAuthorities();
log.info("jwtUser:" + jwtUser.toString());
String token = jwtUtils.createToken(id,usercode,password,username,faculty,authorities);
// 返回创建成功的token
// 但是这里创建的token只是单纯的token
// 按照jwt的规定,最后请求的时候应该是 `Bearer token`
response.setCharacterEncoding("UTF-8");
response.setContentType("application/json; charset=utf-8");
response.setHeader("token", token);
Map map = new HashMap();
map.put("response", response);
map.put("token", token);
ReturnUtil.success("登陆成功!", map);
}
//登录失败处理
@Override
protected void unsuccessfulAuthentication(HttpServletRequest request, HttpServletResponse response, AuthenticationException failed) throws IOException, ServletException {
response.getWriter().write("authentication failed, reason: " + failed.getMessage());
}
最后对token的生成,验证也需要专门去写。