通过 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

在 Spring 安全性中使用 rest 服务进行身份验证和授权 [关闭]

使用 Spring Security 保护 REST 端点

没有 REST 端点在 Spring Boot 应用程序中工作