在我使用 RESTful Web 服务的 Spring Boot 应用程序中,我已经将 Spring Security 与 Spring Social 和 SpringSocialConfigurer
一起配置了。
现在我有两种身份验证/授权方式 - 通过用户名/密码和社交网络,例如Twitter。
为了在我的Spring MVC REST控制器中通过我自己的RESTful端点实现身份验证/授权,我添加了以下方法:
@RequestMapping(value = "/login", method = RequestMethod.POST)
public Authentication login(@RequestBody LoginUserRequest userRequest) {
Authentication authentication = authenticationManager.authenticate(new UsernamePasswordAuthenticationToken(userRequest.getUsername(), userRequest.getPassword()));
boolean isAuthenticated = isAuthenticated(authentication);
if (isAuthenticated) {
SecurityContextHolder.getContext().setAuthentication(authentication);
}
return authentication;
}
private boolean isAuthenticated(Authentication authentication) {
return authentication != null && !(authentication instanceof AnonymousAuthenticationToken) && authentication.isAuthenticated();
}
但我不确定在成功调用端点后/login
必须将什么返回给客户端。我认为返回完整的身份验证对象是多余的。
如果身份验证成功,应该向客户端返回什么?
你能告诉我如何正确实现这个登录方法吗?
另外,在 RESTfull 登录的情况下,我会有UsernamePasswordAuthenticationToken
,如果通过 Twitter 登录,我会有SocialAuthenticationToken
可以在同一应用程序中使用不同的令牌吗?
您可以通过覆盖 SimpleUrlAuthenticationSuccessHandler
中的方法来配置成功身份验证后返回的内容
public class CustomAuthenticationSuccessHandler extends SimpleUrlAuthenticationSuccessHandler {
public CustomAuthenticationSuccessHandler() {
super();
setRedirectStrategy(new NoRedirectStrategy());
}
@Override
public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response,
Authentication authentication) throws IOException, ServletException {
super.onAuthenticationSuccess(request, response, authentication);
ObjectMapper mapper = new ObjectMapper();
response.setContentType("application/json;charset=UTF-8");
response.getWriter().print(mapper.writeValueAsString(objectToBereturned);
response.getWriter().flush();
}
protected class NoRedirectStrategy implements RedirectStrategy {
@Override
public void sendRedirect(HttpServletRequest request, HttpServletResponse response, String url)
throws IOException {
// any redirect if required. leave the implementation black if not needed
}
}
}
此外,您还可以处理故障响应:
public class CustomAuthenticationFailureHandler extends SimpleUrlAuthenticationFailureHandler {
@Override
public void onAuthenticationFailure(HttpServletRequest request, HttpServletResponse response,
AuthenticationException exception) throws IOException, ServletException {
response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
}
}
Restful 调用应始终返回响应代码。在您的情况下,它应该只是 200 OK。失败时 401 未经授权。拥有不同的令牌绝对没问题,无论如何您都不能使用相同的令牌。
我个人更愿意通过 Spring 安全性过滤器而不是控制器来处理登录端点,因为您可以更好地控制流程。