In my Spring Boot application with RESTful webservices I have configured Spring Security together with Spring Social and SpringSocialConfigurer
.
Right now I have two ways of authentication/authorization - via username/password and via social networks for example like Twitter.
In order to implement authentication/authorization via my own RESTful endpoint in my Spring MVC REST controller I have added following method:
@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();
}
but I'm not sure what exactly must be returned to client after successfull /login
endpoint call. I think returning of full authentication object is redundant.
What should be returned to client in case of successfull authentication ?
Could you please tell me how to correctly implement this login method ?
Also, in case of RESTfull login I'll have UsernamePasswordAuthenticationToken
and in case of login through Twitter I'll have SocialAuthenticationToken
Is it okay to have different tokens in a same application ?
You can configure what to return on successful authentication by overriding methods in 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
}
}
}
Additionally you can also handle the failure response:
public class CustomAuthenticationFailureHandler extends SimpleUrlAuthenticationFailureHandler {
@Override
public void onAuthenticationFailure(HttpServletRequest request, HttpServletResponse response,
AuthenticationException exception) throws IOException, ServletException {
response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
}
}