Spring Security ACL抛出AccessDeniedException后,如何请求凭据?

时间:2014-01-10 18:35:15

标签: grails spring-security spring-security-acl

我正在使用Grails 2.2.3和Spring Security ACL插件1.1.1,我希望有一个向公众开放的URL,使用@PostAuthorize注释的服务层可以保证资源。我们这样做是因为要确定用户是否可以访问特定对象,我们需要首先查看该对象。

我希望能够做的是在控制器层中捕获AccessDeniedException,然后让浏览器请求凭据并再试一次。我尝试了将响应状态设置为401并重定向回自身再次尝试的天真方法。我遇到的问题是浏览器从未要求提供凭据。

要将其放入代码中,我想要做的是在控制器层中:

@Secured(['IS_AUTHENTICATED_ANONYMOUSLY'])
def controllerAction() {
   try {
      someService.action()
   } catch (AccessDeniedException ade) {
      // if logged in show FORBIDDEN, if not ask for credentials and try again
   }
}

服务层只有:

@PostAuthorize("""returnObject.availability == 'ALL'""")
def action() {
   PersistedObject.findById(1)
}

感谢您的帮助!

1 个答案:

答案 0 :(得分:0)

我最终解决了这个问题,但事实证明我错过了一个我需要与401状态代码一起发送的标题。

要纠正我上面的想法,请执行以下操作:

@Secured(['IS_AUTHENTICATED_ANONYMOUSLY'])
def controllerAction() {
   try {
      someService.action()
   } catch (AccessDeniedException ade) {
      if (!springSecurityService.isLoggedIn()) {
         response.setHeader 'WWW-Authenticate', 'Basic realm="Grails Realm"' // the missing line
         response.sendError HttpServletResponse.SC_UNAUTHORIZED 
   }
}

"重定向"在提交凭据后,我一直在浏览器中自动查找。我错误地认为需要特定的重定向功能。