通过 REST 端点进行 Spring Security 身份验证/授权
Posted
技术标签:
【中文标题】通过 REST 端点进行 Spring Security 身份验证/授权【英文标题】:Spring Security authentication/authorization via REST endpoint 【发布时间】:2015-06-29 21:44:57 【问题描述】:在我的带有 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
在同一个应用程序中可以有不同的令牌吗?
【问题讨论】:
【参考方案1】:您可以通过覆盖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);
【讨论】:
感谢您的回答。这正是我在当前应用程序中已经使用的。 好像NoRedirectStrategy
在Spring Boot 2.x中不可用,我可以从哪里获取?
@LeonidDashko NoRedirectStrategy 不是 spring 提供的。这是我实现的 RedirectStrategy 接口。您可以在上面的代码中找到相同的内容。有一个受保护的 NoRedirectStrategy 类实现了 RedirectStrategy 接口。但是,如果您不想使用它,可以使用 spring 提供的 DefaultRedirectStrategy。【参考方案2】:
Restful 调用应始终返回响应代码。在您的情况下,它应该只是 200 OK。失败时 401 未经授权。拥有不同的令牌绝对没问题,无论如何你不能使用相同的。
我个人更喜欢通过 Spring Security 过滤器而不是控制器来处理登录端点,因为您可以更好地控制流程。
【讨论】:
是否有关于如何通过 Spring Security 过滤器处理登录端点的文档或指南? 肯定有。您可以搜索 Spring Security Java 配置示例并查找自定义身份验证入口点实现或登录过滤器。这是一个例子:blog.jdriven.com/2014/10/…以上是关于通过 REST 端点进行 Spring Security 身份验证/授权的主要内容,如果未能解决你的问题,请参考以下文章
DispatcherServlet 的 Spring MVC 中来自 REST 端点的 404 错误
为啥 spring-boot-starter-jdbc 会破坏我的 REST 端点?
Spring Boot REST 端点忽略 Content-Type