Grails Spring Security插件:获取302 for Ajax Request for timedout Session

dub*_*ech 8 grails spring-security grails-plugin

我们使用带有Grails 2.2.1的Spring Security插件版本1.2.7.3.在我的Config.groovy手中:

grails.plugins.springsecurity.auth.ajaxLoginFormUrl = "/mylogin/authAjax"
Run Code Online (Sandbox Code Playgroud)

认为,当存在Ajax请求时,如果用户的HttpSession超时,Spring Security将调用authAjax()()MyloginController.

根据doc,我确保X-Requested-With带有值的头部XMLHttpRequest位于Ajax请求中,因此插件知道它是一个Ajax请求.

我的期望是authAjax()将被调用,我可以返回401,所以UI知道它需要弹出另一个登录屏幕.

但是,相反,在authAjax()调用get中,将302返回到UI,并将location字段设置为http://localhost:8080/MyApplication/mycontroller/authAjax

这意味着我必须在我的UI上输入非常hackey的东西.检查302并检查位置字段,然后让用户重新登录.我更愿意回归401.

我有什么想法我做错了吗?

太感谢了

小智 0

如果其他人也遇到这个问题,我发现这只是 chainMap 规则的问题。我的 REST api 位于“/api/”url 下,所以我的 chainMap 如下所示:

grails.plugin.springsecurity.filterChain.chainMap = [
    [pattern: '/assets/**',      filters: 'none'],
    [pattern: '/**/js/**',       filters: 'none'],
    [pattern: '/**/css/**',      filters: 'none'],
    [pattern: '/**/images/**',   filters: 'none'],
    [pattern: '/**/favicon.ico', filters: 'none'],
    [pattern: '/api/**',         filters: 'JOINED_FILTERS,-anonymousAuthenticationFilter,-exceptionTranslationFilter,-authenticationProcessingFilter,-securityContextPersistenceFilter,-rememberMeAuthenticationFilter'], // Stateless API
    [pattern: '/**',             filters: 'JOINED_FILTERS,-restTokenValidationFilter,-restExceptionTranslationFilter'] // Traditional, session based accesses.
]
Run Code Online (Sandbox Code Playgroud)

最后两行是重要的一点;“/api/**”由 Spring Security REST 插件保护,该插件是无状态连接(即每个请求都携带身份验证令牌)。“/**”规则涵盖了需要有状态会话(非 REST 活动)的所有其他内容。如果令牌已过期或以任何方式无效,无状态 REST 请求将返回 402,有状态非 REST 将返回 302 并使浏览器循环。

按照正确的顺序排列这些规则,你应该没问题。