【问题标题】:Spring Security authentication/authorization via REST endpoint通过 REST 端点进行 Spring Security 身份验证/授权
【发布时间】: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 在同一个应用程序中可以有不同的令牌吗?

【问题讨论】:

    标签: spring spring-mvc authentication spring-security spring-social


    【解决方案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/…
    猜你喜欢
    • 2017-05-10
    • 2021-03-19
    • 2012-03-06
    • 2013-02-23
    • 1970-01-01
    • 2017-05-08
    • 2014-03-06
    • 2021-11-25
    • 2013-06-12
    相关资源
    最近更新 更多