Аутентификация / авторизация 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 у меня будет UsernamePasswordAuthenticationToken а в случае входа через твиттер у меня будет 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);
    }
}

Успешные звонки всегда должны возвращать код ответа. В вашем случае это должно быть просто 200 ОК. При сбое 401 Несанкционированный. Наличие разных токенов абсолютно нормально, вы не можете использовать их в любом случае.

Лично я предпочел бы обрабатывать конечные точки входа в систему через фильтры Spring Security, а не контроллеры, поскольку вы можете лучше контролировать поток.

Другие вопросы по тегам