Grails Acegi 安全性:角色和访问问题

Posted

技术标签:

【中文标题】Grails Acegi 安全性:角色和访问问题【英文标题】:Grails Acegi security: Problem with roles and access 【发布时间】:2011-05-30 01:35:00 【问题描述】:

这个故事的悲惨结局

好吧,事实证明,我的 Role 类(Role 实现 GrantedAuthority)中的 compareTo 方法总是返回 0。所以每个用户只有一个角色(因为它们存储在一个 Set 中)。

问题

大家好,

我的应用程序出现了一些奇怪的行为。

我在 User 类(由 Acegi 创建)中添加了几个字段,所以我可以设置过期密码,记录最后 N 个密码,诸如此类。我们有 9 个角色,ROLE_ADMIN 是可以访问所有功能的“超级用户”。

部署应用后,用户开始抱怨他们无法使用它。他们可以登录,但无论何时他们想去某个地方,他们都会被拒绝访问,就好像他们没有角色一样。

这发生在每个用户身上,除了管理员(只有ROLE_ADMIN),包括那些拥有(ROLE_ADMIN + 其他角色)的用户。

我什至无法开始。

更新

我已检查,用户来自附加角色的数据库。

在 SecurityConfig.groovy 文件中检查角色。恐怕问题出在其他地方,因为我有一个实际有效的项目标记版本。

这是我的 SecurityConfig.groovy:

import com.mycompany.myapp.audit.Auditoria

security 

    // see DefaultSecurityConfig.groovy for all settable/overridable properties

    active = true

    loginUserDomainClass = "com.mycompany.myapp.user.User"
    authorityDomainClass = "com.mycompany.myapp.user.Role"
    requestMapClass = "com.mycompany.myapp.user.Requestmap"

    useRequestMapDomainClass = false

    /** authenticationEntryPoint */
    loginFormUrl = '/login/auth'
    forceHttps = 'false'
    ajaxLoginFormUrl = '/login/authAjax'
    authenticationFailureUrl = '/login/authfail'


    afterLogoutUrl = '/login/auth'

    requestMapString = """\
            CONVERT_URL_TO_LOWERCASE_BEFORE_COMPARISON
            PATTERN_TYPE_APACHE_ANT

            /=IS_AUTHENTICATED_REMEMBERED
            /login/auth=IS_AUTHENTICATED_ANONYMOUSLY
            /login/authajax=IS_AUTHENTICATED_ANONYMOUSLY
            /login/authfail=IS_AUTHENTICATED_ANONYMOUSLY
            /login/renew=IS_AUTHENTICATED_ANONYMOUSLY
            /js/**=IS_AUTHENTICATED_ANONYMOUSLY
            /css/**=IS_AUTHENTICATED_ANONYMOUSLY
            /images/**=IS_AUTHENTICATED_ANONYMOUSLY
            /plugins/**=IS_AUTHENTICATED_ANONYMOUSLY


            /scan/uploadfile=IS_AUTHENTICATED_ANONYMOUSLY
            /ticket/uploadfile=IS_AUTHENTICATED_ANONYMOUSLY
            /analisis/list =ROLE_SUP_TECNICO, ROLE_OP_TECNICO, ROLE_OP_FUNCIONAL, ROLE_ADMIN
            /analisis/hazzards/**=ROLE_SUP_TECNICO, ROLE_OP_TECNICO, ROLE_OP_FUNCIONAL, ROLE_ADMIN
            /analisis/show/**=ROLE_SUP_TECNICO, ROLE_OP_TECNICO, ROLE_ADMIN
            /analisis/create/**=ROLE_SUP_TECNICO, ROLE_ADMIN
            /analisis/edit/**=ROLE_SUP_TECNICO,ROLE_ADMIN
            /hazzardsreport/**=ROLE_SUP_TECNICO, ROLE_OP_TECNICO, ROLE_OP_FUNCIONAL, ROLE_REPORTE_VULNERABILIDAD, ROLE_ADMIN
            /mistaken/**=ROLE_SUP_TECNICO, ROLE_OP_TECNICO, ROLE_ADMIN
            /hazzardtype/**=ROLE_SUP_TECNICO, ROLE_ADMIN

            /** MODULO NORMAS */
            /report/**=ROLE_OP_FUNCIONAL, ROLE_ADMIN
            /norm/**=ROLE_OP_FUNCIONAL, ROLE_ADMIN

            /** TICKETS */
            /ticket/**=ROLE_SUP_TECNICO, ROLE_OP_TECNICO, ROLE_ADMIN
            /alert/**=ROLE_SUP_TECNICO, ROLE_OP_TECNICO, ROLE_ADMIN
            /ticket/uploadfile=IS_AUTHENTICATED_ANONYMOUSLY

            /** RISKS */
            /project/**=ROLE_AN_RIESGOS, ROLE_ADMIN
            /riskreport/**=ROLE_AN_RIESGOS, ROLE_ADMIN, ROLE_REPORTE_RIESGO

        /** BUSINESS CONTINUITY*/
            /projectpcn/**=ROLE_AN_PCN, ROLE_ADMIN
        /businessuniteval/** = ROLE_AN_PCN, ROLE_ADMIN
        /subprocesseval/** = ROLE_AN_PCN, ROLE_ADMIN
        /failscenario/**=ROLE_AN_PCN, ROLE_ADMIN
        /strategy/**=ROLE_AN_PCN, ROLE_ADMIN
        /test/**=ROLE_AN_PCN, ROLE_ADMIN
        /reportepcn/**=ROLE_AN_PCN, ROLE_ADMIN, ROLE_REPORTE_PCN
        /process/**=ROLE_AN_PCN, ROLE_ADMIN


        /** ADMIN */
            /user/changeent=IS_AUTHENTICATED_REMEMBERED
            /user/finduser=IS_AUTHENTICATED_REMEMBERED
            /user/**=ROLE_ADMIN
            /role/**=ROLE_ADMIN
            /requestmap/**=ROLE_ADMIN
        /empresa/**=ROLE_ADMIN
        /asset/**=ROLE_ADMIN, ROLE_SUP_TECNICO, ROLE_OP_TECNICO
        /responsable/**=ROLE_ADMIN
        /preference/**=ROLE_ADMIN
        /businessunit/**=ROLE_ADMIN, ROLE_AN_PCN


            /**=IS_AUTHENTICATED_REMEMBERED
        """


    useSecurityEventListener = true

    onInteractiveAuthenticationSuccessEvent =  e, appCtx ->
        Auditoria.log(e.getSource().getPrincipal().getDomainClass(), "Usuario autenticado - " + e.getSource().getDetails().getRemoteAddress())
    


更新 - 记录冗长且没有 cmets/newlines

您好,更新我的SecurityConfig.groovy 后,错误仍然存​​在。 但是,我已经恢复了这个日志行。我尝试使用分配了所有 9 个角色的用户访问 /norm/index

调试 2010 年 12 月 28 日 00:12:57,110 [http-8080-3] 安全对象:FilterInvocation:URL:/no​​rm/index;配置属性:[ROLE_OP_FUNCIONAL,ROLE_ADMIN]

org.springframework.security.intercept.AbstractSecurityInterceptor - 以前经过身份验证:org.springframework.security.providers.UsernamePasswordAuthenticationToken@a00c7ad6: 主要的: com.baufest.insside.security.UserLoginDetails@0:

用户名:someuser;密码保护];启用:真; AccountNonExpired:真;凭据非过期:真; AccountNonLocked:真;的确 权限:ROLE_OP_TECNICO; 密码保护]; 已认证:真实;

详细信息:org.springframework.security.ui.WebAuthenticationDetails@0:授予权限:ROLE_OP_TECNICO

调试 2010 年 12 月 28 日 00:12:57,110 [http-8080-3] org.springframework.security.ui.ExceptionTranslationFilter - 访问被拒绝(用户不是匿名的);委派给 AccessDeniedHandler

对于我在这里阅读的内容,似乎我的用户只获得了 1 个角色,即使在我调试它时,user.authorities 已分配给它所有 9 个角色。

任何想法将不胜感激 提前致谢。

【问题讨论】:

应用程序日志中有任何内容吗?您是否启用了正确的日志?你有 SecurityFilters.groovy,有什么? 尝试将 cmets 从 requestMapString 中取出。也去掉换行符。 我指的是额外的换行符,而不是所有的换行符。每行输入一个条目。此外,您在以普通用户身份登录时尝试访问什么 URL...最后,在您的 Config.groovy 中启用 org.springframework.security 包上的调试级别日志记录。 【参考方案1】:

编辑 --

来自documentation,requestMapString 的格式应该是

requestMapString = '''CONVERT_URL_TO_LOWERCASE_BEFORE_COMPARISON 
                      PATTERN_TYPE_APACHE_ANT 
                      /login/**=IS_AUTHENTICATED_ANONYMOUSLY 
                      /admin/**=ROLE_USER
                      /book/test/**=IS_AUTHENTICATED_FULLY
                      /book/**=ROLE_SUPERVISOR
                   '''

一些注意事项:

1) 请求映射字符串中有额外的换行符和 cmets。 requestMapString 是一个multiline String(查看'''一个长字符串''' 格式),因此 Acegi 机制将尝试解析/使用 cmets。

【讨论】:

“正确检查角色”是什么意思?我在 SecurityConfig.xml 中编写了映射 @tom 你在 SecurityConfig.xml 中“编写了映射”是什么意思。它应该是 SecurityConfig.groovy。此外,该映射中的 url 级别检查只是针对端点是否完全安全。您仍然可以以编程方式检查您的操作/服务方法中的角色。由于您没有提供太多信息,我不得不对您使用 acegi 的方式做出假设 @hvgotcodes 抱歉,我的意思是 SecurityConfig.groovy。我没有程序检查,我认为这就是我所需要的。 @hvgotcodes 我尝试删除不必要的换行符和 cmets,但仍然无法访问。有点奇怪,这个文件的先前版本有一个有效的副本(带有 cmets 和换行符)。 @tom,你删除了 cmets 吗?您是否出于安全考虑进行了日志记录。

以上是关于Grails Acegi 安全性:角色和访问问题的主要内容,如果未能解决你的问题,请参考以下文章

使用 Acegi 和 Grails 通过 LDAP 进行身份验证时出现 PartialResultException

安装Acegi安全插件-本地安装

使用 Grails 和 Acegi 自动登录

在 grails + acegi 中测试 securityConfig 映射

Grails - Acegi:自定义身份验证方法

登录页面使用 SSL,未加密页面看不到加密会话 cookie (Grails, Acegi)