通过 REST 端点进行 Spring 安全性身份验证/授权



在我使用 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 安全性过滤器而不是控制器来处理登录端点,因为您可以更好地控制流程。

最新更新