Аутентификация/авторизация Spring Security через конечную точку REST

в моем приложении Spring Boot с веб-сервисами RESTful я настроил Spring Security вместе с Spring Social и SpringSocialConfigurer.

сейчас у меня есть два способа аутентификации/авторизации через логин/пароль и через социальные сети, например, как Twitter.

для реализации аутентификации / авторизации через мою собственную конечную точку RESTful в моем контроллере Spring MVC REST я добавил следующий метод:

@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 login у меня будет UsernamePasswordAuthenticationToken и в случае входа через Twitter у меня будет SocialAuthenticationToken нормально ли иметь разные токены в одном и том же заявление ?

2 ответов


вы можете настроить, что вернуть при успешной аутентификации путем переопределения методов в 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, а не контроллеры, поскольку вы можете лучше контролировать поток.