Spring Security多个注销URL?

3

我正在使用Spring安全Java配置,并希望知道一种实现多个URL注销的方法,即:

logout().logoutRequestMatcher(new 
AntPathRequestMatcher("/invalidate")).logoutUrl("/logout");

在这段代码中,正常的注销URL "/logout" 可以正常工作并且是POST请求,但我也想让用户通过"/invalidate"注销,但似乎不起作用。

我正在尝试理解您需求的业务用例。 - Jayesh
1
应用程序中存在一个遗留的URL,用于注销用户(GET请求),正常的POST注销也应该继续工作。 - Tarun Sapra
有人了解这个吗? - Tarun Sapra
1
也想知道。 - Juzer Ali
有一点需要注意,你对.logoutUrl("/logout")的调用会覆盖之前设置的/invalidate路径。 - Juzer Ali
3个回答

2
根据Spring Security教程,似乎下面的方法更为优雅:

enter image description here

在安全表单登录标记中添加类似以下内容:
<security:logout logout-url="/logout" success-handler-ref="logoutHandler"/>

每当您访问/logout URL时,将调用logoutHandler,并且您可以在其中决定在成功注销后如何行事。
来自Spring文档:

enter image description here

你所需要做的就是创建一个新类,实现图像中标记的接口,并实现其单个方法。
在该方法中,决定在成功注销后如何操作。例如:
@Component("logoutHandler")
public class MyLogoutSuccessHandler implements LogoutSuccessHandler {

    @Override
    public void onLogoutSuccess(HttpServletRequest request,HttpServletResponse response, Authentication authentication) throws IOException, ServletException {

        if(request.getParameter("msgShow") != null && request.getParameter("msgShow").equals("false")){
            redirectResponse(request, response, "http://" + request.getServerName() + ":" + request.getServerPort() + "/my_web_app/home?logout=false");
        }
        else{
            redirectResponse(request, response,"http://" + request.getServerName() + ":" + request.getServerPort() + "/my_web_app/home?logout=true");
        }
    }

    private void redirectResponse(HttpServletRequest request, HttpServletResponse response, String destination) {
        response.setStatus(HttpServletResponse.SC_MOVED_PERMANENTLY);
        response.setHeader("Location", destination);
    }
}

现在不要忘记为上面的注销处理程序添加一个@Component注释+在安全配置文件中添加下面的2个语句:
<context:annotation-config />
<context:component-scan base-package="package.to.logout.handler" />

这并没有回答问题。 - aradil

1
这可能不是最优雅的方法,但您可以指定一个@Controller,将其映射到您想要注销的所有URL,例如:
@Controller
public class LogoutController {

  final String logoutRedirectUrl = "redirect:http://yourredirect.xy";

  @RequestMapping("/logout")
  public String logout1(HttpServletRequest request) throws ServletException {
    request.logout();
    return logoutRedirectUrl;
  }    

  @RequestMapping("/second/logout/")
  public String logout2(HttpServletRequest request) throws ServletException {
    request.logout();
    return logoutRedirectUrl;
  }
}

1
我认为在安全配置文件中应该指定额外的注销URL。 - Moshe Arad
1
Tarun Sapra 想知道如何指定两个注销 URL,而不是一个注销 URL 做两件事。据我所知,在安全配置文件中只能指定一个 URL。我提出的解决方案提供了一种解决方法,而 @Moshe Arad 提出的解决方案则做了不同的事情(尽管肯定更优雅)。 - C Brand

0

一个小提示,实际匹配应该得到改进。

List logoutUrls = Arrays.asList(
    "/rest/logout1",
    "/rest/logout2"
);
RequestMatcher rm = new RequestMatcher() {
  @Override
  public boolean matches(HttpServletRequest request) {
    String uriStr = request.getRequestURI().toString();
    return logoutUrls.stream()
        .filter(lu -> uriStr.contains(lu))
        .findFirst()
        .isPresent();
  }
};

然后注册请求匹配器:

http.logout(logout -> logout.logoutRequestMatcher(rm));

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接