簡體   English   中英

如何根據拒絕訪問的原因使Grails的Spring Security Core呈現不同的頁面

[英]How to make Grails's Spring Security Core render a different page depending on the reason why access was denied

我正在使用Spring Security Core插件運行Grails應用程序。

當已經登錄的用戶嘗試訪問頁面而不訪問該頁面時,將始終調用在UrlMappings.groovy中配置為403的相同操作。

我一直在努力使我的應用程序根據訪問拒絕的原因來呈現不同的頁面。 例如:如果需要IS_AUTHENTICATED_FULLY ,我想將用戶重定向到他可以重新認證的表單。 如果需要特定角色但不存在特定角色,我想將用戶重定向到他可以請求該角色的頁面。 等等...

有人知道如何存檔嗎?

=============================更新=================== ===============

我試圖通過文檔中描述的onAuthorizationEven‌​t回調解決問題。 不幸的是,無論觸發該事件的規則是什么,事件參數始終是相同的。

至少我可以訪問被拒絕從那里訪問的URI。 有沒有一種方法可以從URI中獲取安全規則,以便我可以與當前用戶的角色和狀態進行比較並找出缺少的內容? 那也許可以解決問題。

也許在那里創建控制器並訪問異常?

static mappings = {
    //....
   "403"(controller:'error', action:'error403')
   //......
}


class ErrorController {  
   def error403() {
       def message = request.exception?.cause?.message; //access message and render right view
   }
}

經過互聯網的長期研究,終於使它與@yariash的回復和這篇博文中的一些想法結合使用:

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
    }
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM