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