我有几个AngularJS应用程序都使用Spring / Java和SAML 2.0 for SSO(利用Spring Security SAML扩展)。我的SSO ID提供程序是OpenAM,一切都运行良好。但是,当用户在一个应用程序中执行全局注销但打开了其他选项卡时,我遇到了这种情况。由于这些是单页面Web应用程序,因此在孤立选项卡UNTIL中仍可使用许多功能,用户可以执行某些操作来调用ajax请求。当然,这些AJAX请求会被Spring Security SAML过滤器拦截,并通过REDIRECT触发对OpenAM登录URL的身份验证尝试。当然,这会在浏览器中造成严重破坏,因为AJAX请求不允许重定向到另一个域。此外,我无法对Angular的$ http拦截器做任何事情,因为请求被“取消”并且$ http错误回调函数中没有可用的质量信息(例如方便的401/403状态代码)。我所知道的是请求失败了。
我不想假设所有错误的$ http请求都是由于身份验证问题(并且执行$ window.location.reload()),因为可能存在合理的失败原因。我倾向于禁止针对ajax请求的Spring Security重定向(到OpenAM登录页面),而是发送回401/403状态代码。这将允许我处理$ http拦截器中的错误并在验证失败时执行整页加载,从而优雅地重定向到登录页面,就好像他们第一次访问该站点一样。
有关如何实现这一目标的任何想法?
答案 0 :(得分:3)
负责初始化身份验证并决定返回HTTP错误,执行重定向,...的bean是AuthenticationEntryPoint
的实例。要改变其行为,您可以:
SAMLEntryPoint
(扩展commence
方法)并覆盖默认行为,以防请求是来自Angular的AJAX调用,因此它返回HTTP错误而不是执行重定向到IDP security:http
元素(在当前之前),它只涵盖您的AJAX请求(例如,使用属性pattern="/api/**"
)并使用一个行为符合您想要的行为点(见Http403ForbiddenEntryPoint
)答案 1 :(得分:0)
指的是弗拉基米尔(Vladimir)的第一个项目符号的可能实现方式-摘自https://www.jasha.eu/blogposts/2015/10/saml-authentication-angularjs-spring-security.html
public class XhrSamlEntryPoint extends SAMLEntryPoint {
@Override
public void commence(HttpServletRequest request, HttpServletResponse response,
AuthenticationException e) throws IOException, ServletException {
if (isXmlHttpRequest(request) && e instanceof InsufficientAuthenticationException) {
response.sendError(HttpServletResponse.SC_UNAUTHORIZED, e.getMessage());
return;
}
super.commence(request, response, e);
}
private boolean isXmlHttpRequest(HttpServletRequest request) {
return "XMLHttpRequest".equalsIgnoreCase(request.getHeader("X-Requested-With"));
}
}
请记住,X-Requested-With不是必需的标头,因此根据this answer,检测不是防弹的。就我而言,由于后端与SPA前端一起使用,因此我完全删除了对ajax调用的检查。