我正在使用Spring Security Core Plugin运行Grails应用程序。
当已登录的用户尝试访问某个页面而无法访问该页面时,始终会调用在UrlMappings.groovy中配置为403
的相同操作。
我一直在努力让我的应用程序呈现不同的页面,具体取决于访问拒绝的原因。例如:如果需要IS_AUTHENTICATED_FULLY
,我想将用户重定向到可以重新进行身份验证的表单。如果需要特定角色但不存在,我想将用户重定向到可以请求此角色的页面。等等...
有谁知道如何存档?
==============================更新================ ==================
我尝试通过docs中描述的onAuthorizationEvent
回调来解决问题。不幸的是,无论触发它的规则如何,事件参数总是相同的。
至少我可以访问那些被拒绝访问的URI。有没有办法从URI获取安全规则,以便我可以比较当前用户的角色和状态,并找出缺少的内容?这可能会解决问题。
答案 0 :(得分:1)
经过长时间的互联网研究后,终于得到了@yariash的回复和this post的一些想法:
import org.springframework.context.ApplicationListener;
import org.springframework.security.access.event.AuthorizationFailureEvent
import org.springframework.security.authentication.RememberMeAuthenticationToken;
class AuthorizationFailureEventListener
implements ApplicationListener<AuthorizationFailureEvent> {
@Override
public void onApplicationEvent(AuthorizationFailureEvent e) {
def attributes = e.getConfigAttributes()
if(!attributes) {
return
}
def authentication = e.getAuthentication()
def requiredAuthorities = attributes?.collect { it.getAttribute() }
def userAuthorities = authentication.getAuthorities().collect { it.getAuthority() }
def missingAuthorities = requiredAuthorities - userAuthorities
if(requiredAuthorities.contains('IS_AUTHENTICATED_FULLY') &&
!(authentication instanceof RememberMeAuthenticationToken)) {
requiredAuthorities.remove('IS_AUTHENTICATED_FULLY')
}
e.getSource().getRequest().setAttribute("MISSING_AUTHORITIES", missingAuthorities);
}
}
然后将此监听器包含为bean:
beans = {
//...
authorizationFailureEventListener(AuthorizationFailureEventListener) { bean ->
bean.autowire = "byName"
}
//...
}
最后在我的错误控制器中:
static mappings = {
//....
"403"(controller:'error', action:'error403')
//......
}
class ErrorController {
def error403() {
def missingAuthorities = request.getAttribute("MISSING_AUTHORITIES")
// Render the right view based on the missing authorities
}
}