我们正在使用带有Grails 2.2.1的Spring Security插件版本1.2.7.3。
在我的Config.groovy
中,我这样做:
grails.plugins.springsecurity.auth.ajaxLoginFormUrl = "/mylogin/authAjax"
认为,当存在Ajax请求时,如果用户的HttpSession已超时,Spring Security将在authAjax()
中调用MyloginController
。
根据doc,我确保带有值X-Requested-With
的标头XMLHttpRequest
在Ajax请求中,因此插件知道它是一个Ajax请求。
我的期望是authAjax()
将被调用,我可以返回401,因此UI知道它需要弹出另一个登录屏幕。
但是,不是调用authAjax()
,而是将302返回到UI,其中位置字段设置为http://localhost:8080/MyApplication/mycontroller/authAjax
这意味着我必须在我的UI上输入非常hackey的东西,检查302并检查位置字段然后让用户重新登录。我宁愿让401回来。
任何想法我做错了什么?
万分感谢。
答案 0 :(得分: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.
]
最后两行是重要位; ``/ api / **''由Spring Security REST插件保护,该插件是无状态连接(即每个请求都带有身份验证令牌)。 “ / **”规则涵盖需要状态会话(非REST活动)的所有其他内容。 如果令牌已过期或以任何方式无效,则无状态REST请求将返回402,有状态的非休息状态将返回302并循环发送您的浏览器。
以正确的顺序获取这些规则,您应该会很好。