问:Grails2.4,CAS和臭名昭着的重定向循环

时间:2015-04-01 14:20:15

标签: grails spring-security cas

我有几个Grails应用程序在生产中运行,并通过spring-security和“Grails CAS插件”与CAS服务器(CAS 3.3.5)连接。这些应用程序由版本1.3.7到2.2.4的各种版本的Grails支持

我正在将其中一个移至2.4.4,我从未结束身份验证问题。在练习结束时,我有臭名昭着的说法:“这个网页有一个重定向循环”(在Chrome中)。在服务器端,我有通常的(!)错误:

ERROR [org.jasig.cas.web.ServiceValidateController] - <TicketException
generating ticket for: [callbackUrl:
https://casclient.mydomain.com:9043/testCas/secure/receptor]>
org.jasig.cas.ticket.InvalidTicketException
    at org.jasig.cas.CentralAuthenticationServiceImpl.delegateTicketGrantingTicket(CentralAuthenticationServiceImpl.java:268)

以下是我为重现问题所采取的所有步骤:

  1. grails create-app testCas
  2. grails create-controller showSecure 在控制器中添加动作showSecurePage
  3. grails generate-views
  4. 在view / showSecure
  5. 下创建showSecurePage页面
  6. 将此添加到UrlMappings

    class UrlMappings {
        static mappings = {
            "/showSecure" {
                controller = "showSecure"
                action = [ GET: "showSecurePage" ]
            }
            "/"(view:"/index")
            "500"(view:'/error')
        }
    }
    
  7. 此时如果我启动应用程序,我可以毫无问题地访问“showSecurePage”页面。让我们继续并安装“CAS插件”。

    1. 在BuildConfig.groovy的“插件”片段中添加字符串:

      compile ":spring-security-core:2.0-RC4"
      compile ":spring-security-cas:2.0-RC1"
      
    2. 和“dependencies”片段:

          mavenRepo 'http://repo.spring.io/milestone'
      
      1. 执行grails cleangrails compile

      2. 运行:grails s2-quickstart testCas User Role

      3. Config.groovy已修改,必须“调整”。

        1. 由于我们不使用注释,因此我将s2-quickstart(staticRules)添加的条目替换为:

          grails.plugin.springsecurity.rejectIfNoRule = true
          grails.plugin.springsecurity.securityConfigType = "InterceptUrlMap"
          grails.plugin.springsecurity.interceptUrlMap = [
              '/':                  ['permitAll'],
              '/index':             ['permitAll'],
              '/index.gsp':         ['permitAll'],
              '/**/js/**':          ['permitAll'],
              '/**/css/**':         ['permitAll'],
              '/**/images/**':      ['permitAll'],
              '/**/favicon.ico':    ['permitAll'],
              '/login/**':          ['permitAll'],
              '/logout/**':         ['permitAll'],
              '/secure/receptor':   ['permitAll'],
              '/showSecure/**':     ['isFullyAuthenticated()'],
              '/finance/**':        ['ROLE_FINANCE', 'isFullyAuthenticated()']
          ]
          
        2. 注意:我按照19710841

          中的说明将“permitAll”添加到“/ secure / receptor”
          1. 最后我们添加了CAS配置。如文档中所述,必须定义所有列出的参数:

            grails.serverURL = "http://casclient.mydomain.com:9080/testCas"
            grails.serverSecureURL = "https://casclient.mydomain.com:9043/testCas"
            grails.plugin.springsecurity.useCAS = true
            grails.plugin.springsecurity.cas.active = true
            grails.plugin.springsecurity.cas.serverUrlPrefix = 'https://casserver.mydomain.com:10443/sso'
            grails.plugin.springsecurity.cas.serverUrlEncoding = 'UTF-8'
            grails.plugin.springsecurity.cas.loginUri = '/login'
            grails.plugin.springsecurity.cas.sendRenew = false
            grails.plugin.springsecurity.cas.serviceUrl = "${grails.serverURL}/secure/security_check"
            grails.plugin.springsecurity.cas.key ='authentication_provider'
            grails.plugin.springsecurity.cas.artifactParameter = 'ticket'
            grails.plugin.springsecurity.cas.serviceParameter = 'service'
            grails.plugin.springsecurity.cas.filterProcessesUrl = '/secure/security_check'
            grails.plugin.springsecurity.cas.proxyCallbackUrl = "${grails.serverSecureURL}/secure/receptor"
            grails.plugin.springsecurity.cas.proxyReceptorUrl = '/secure/receptor'
            grails.plugin.springsecurity.cas.useSingleSignOut = true
            
            grails.plugin.springsecurity.logoutURL = "${grails.plugin.springsecurity.cas.serverUrlPrefix}/logout"
            grails.plugin.springsecurity.logout.afterLogoutUrl = "${grails.plugin.springsecurity.cas.serverUrlPrefix}/logout?url=${grails.serverURL}"
            
          2. 注意:如果在grails.plugin.springsecurity.cas.proxyCallbackUrl中我将链接定义为“http”而不是“https”,我将在CAS服务器端有一个循环,其中包含“错误凭据”消息。添加安全链接时,此错误消失。

            现在访问安全页面,我看到了常用的CAS登录信息。如果我正确登录,我会在CAS日志中看到“重定向循环”错误:

            -------------------------2015-03-31 13:33:33,736 ERROR
            [org.jasig.cas.web.ServiceValidateController] - <TicketException
            generating ticket for: [callbackUrl:
            https://casclient.mydomain.com:9043/testCas/secure/receptor]>
            org.jasig.cas.ticket.InvalidTicketException
                at org.jasig.cas.CentralAuthenticationServiceImpl.delegateTicketGrantingTicket(CentralAuthenticationServiceImpl.java:268)
                at org.jasig.cas.web.ServiceValidateController.handleRequestInternal(ServiceValidateController.java:126)
            

            编辑:更多信息。 在启用各种调试的详细输出中,我意识到存在对ROLE_ANONYMOUS的连续引用。嫌疑人认为问题不是认证,而是授权。确实这是问题所在。如果我修改Config.groovy:

            '/showSecure/**':     ['ROLE_USER', 'isFullyAuthenticated()'],
            

            我实现了在resources.groovy中定义的(现在)服务:

            // Place your Spring DSL code here
            beans = {
            
                userDetailsService(EsoUserDetailsService)
            }
            

            问题消失了。 我有另外一个。 如果在EsoUserDetailsS​​ervice中,我尝试以这种方式从数据库中检索角色:

            User.withTransaction { status ->
                        User user = User.findByUsername(username)
                        if (!user) throw new UsernameNotFoundException('User not found', username)
            
                        def authorities = user.authorities.collect { new GrantedAuthorityImpl(it.authority)
                        }
            
                        return new EsoUserDetails(user.username, user.password, user.enabled,
                        !user.accountExpired, !user.passwordExpired, !user.accountLocked, authorities,
                        user.id, user.getUserRealName())
                    }
            

            我有错误:

            类[eso.phase3.rm.User]上的方法在Grails应用程序之外使用。如果使用模拟API或正确引导Grails在测试环境中运行。

0 个答案:

没有答案