Session GRAILS:如何通过springsecuritycoreplugin获取当前登录用户的数量?

Session GRAILS:如何通过springsecuritycoreplugin获取当前登录用户的数量?,session,grails,spring-security,grails-plugin,Session,Grails,Spring Security,Grails Plugin,我的问题是,我想限制可以同时登录到我的应用程序中的用户数量(该值存储在数据库中)。首先,我尝试在tomcat或其他web容器中进行一些配置,但问题是,如果用户未登录,也会使用会话(显示登录页面也需要在tomcat中使用会话)。。。所以我需要检查有多少用户“真正”登录。 我已经找到了很多acegi插件的代码示例,但是springsecurity核心插件没有什么真正的帮助 到目前为止,我的片段: 在resources.groovy中,我定义了我的bean: beans = { session

我的问题是,我想限制可以同时登录到我的应用程序中的用户数量(该值存储在数据库中)。首先,我尝试在tomcat或其他web容器中进行一些配置,但问题是,如果用户未登录,也会使用会话(显示登录页面也需要在tomcat中使用会话)。。。所以我需要检查有多少用户“真正”登录。 我已经找到了很多acegi插件的代码示例,但是springsecurity核心插件没有什么真正的帮助

到目前为止,我的片段:

在resources.groovy中,我定义了我的bean:

beans = {
    sessionRegistry(org.springframework.security.concurrent.SessionRegistryImpl)

    concurrentSessionController(org.springframework.security.concurrent.ConcurrentSessionControllerImpl) { 
        sessionRegistry = ref('sessionRegistry') 
        maximumSessions = -1 
   }
}
在BootStrap.groovy中,init的请求是:

class BootStrap {

    def springSecurityService

    def authenticationManager
    def concurrentSessionController
    def securityContextPersistenceFilter

    def init = { servletContext ->
        authenticationManager.sessionController = concurrentSessionController
        ...
在Config.groovy中,我添加了:

grails.plugins.springsecurity.providerNames = ['concurrentSessionController', 'daoAuthenticationProvider', 'anonymousAuthenticationProvider', 'rememberMeAuthenticationProvider'] 
但一旦应用程序启动(grails run app),当它试图配置SpringSecury时就会崩溃:

...
Running Grails application..

Configuring Spring Security ...
Application context shutting down...
Application context shutdown.
limepix@turbo:~/develop/testproject$
我已经为我的应用程序配置了日志记录-日志文件中的内容/最后一项是:

2011-07-11 11:19:43,071 [main] ERROR context.GrailsContextLoader  - Error executing bootstraps: No bean named 'concurrentSessionController' is defined
org.springframework.beans.factory.NoSuchBeanDefinitionException: No bean named 'concurrentSessionController' is defined
        at SpringSecurityCoreGrailsPlugin$_createBeanList_closure22.doCall(SpringSecurityCoreGrailsPlugin.groovy:648)
        at SpringSecurityCoreGrailsPlugin.createBeanList(SpringSecurityCoreGrailsPlugin.groovy:648)
        at SpringSecurityCoreGrailsPlugin.this$2$createBeanList(SpringSecurityCoreGrailsPlugin.groovy)
        at SpringSecurityCoreGrailsPlugin$_closure4.doCall(SpringSecurityCoreGrailsPlugin.groovy:581)
        at org.grails.tomcat.TomcatServer.start(TomcatServer.groovy:212)
            at grails.web.container.EmbeddableServer$start.call(Unknown Source)
        at _GrailsRun_groovy$_run_closure5_closure12.doCall(_GrailsRun_groovy:158)
        at _GrailsRun_groovy$_run_closure5_closure12.doCall(_GrailsRun_groovy)
        at _GrailsSettings_groovy$_run_closure10.doCall(_GrailsSettings_groovy:280)
        at _GrailsSettings_groovy$_run_closure10.call(_GrailsSettings_groovy)
        at _GrailsRun_groovy$_run_closure5.doCall(_GrailsRun_groovy:149)
        at _GrailsRun_groovy$_run_closure5.call(_GrailsRun_groovy)
        at _GrailsRun_groovy.runInline(_GrailsRun_groovy:116)
        at _GrailsRun_groovy.this$4$runInline(_GrailsRun_groovy)
        at _GrailsRun_groovy$_run_closure1.doCall(_GrailsRun_groovy:59)
        at RunApp$_run_closure1.doCall(RunApp.groovy:33)
        at gant.Gant$_dispatch_closure5.doCall(Gant.groovy:381)
        at gant.Gant$_dispatch_closure7.doCall(Gant.groovy:415)
        at gant.Gant$_dispatch_closure7.doCall(Gant.groovy)
        at gant.Gant.withBuildListeners(Gant.groovy:427)
        at gant.Gant.this$2$withBuildListeners(Gant.groovy)
        at gant.Gant$this$2$withBuildListeners.callCurrent(Unknown Source)
        at gant.Gant.dispatch(Gant.groovy:415)
        at gant.Gant.this$2$dispatch(Gant.groovy)
        at gant.Gant.invokeMethod(Gant.groovy)
        at gant.Gant.executeTargets(Gant.groovy:590)
        at gant.Gant.executeTargets(Gant.groovy:589)
也许有人可以给我指一些文档、示例,或者直接告诉我如何获取当前已登录用户的数量

来自德国纽伦堡的问候


limepix首先我想计算在给定时间段内登录的用户数,但这可能不准确


我认为您可以缓存用户id和他最后一次操作的时间。然后,您可以编写过滤器,在用户登录时,在每个操作上更新此缓存。然后,您可以只计算缓存中的项目。如果您的缓存很小,您还可以对其进行迭代,并删除五分钟内处于非活动状态的用户(或者任何其他用户,如会话过期-顺便说一句:
sessionId
,因此您可以检查该会话是否仍然有效)。如果缓存很大,计划的作业可以处理它

谢谢你的回答!现在我明白了

我采取的步骤是:

定义bean:

import org.springframework.security.web.authentication.session.ConcurrentSessionControlStrategy 
import org.springframework.security.web.session.ConcurrentSessionFilter 
import org.springframework.security.core.session.SessionRegistryImpl 
import org.springframework.security.web.authentication.session.SessionAuthenticationStrategy

beans = { 

        sessionRegistry(SessionRegistryImpl) 

        sessionAuthenticationStrategy(ConcurrentSessionControlStrategy, sessionRegistry) { 
                maximumSessions = -1 
        } 

        concurrentSessionFilter(ConcurrentSessionFilter){ 
                sessionRegistry = sessionRegistry 
                expiredUrl = '/login/concurrentSession' 
        } 
} 
然后我在控制器中注入:

class SystemController {    

    def sessionRegistry
检查当前正在使用的会话数:

    def sessioncount = {
        def cnt = 0

        sessionRegistry.getAllPrincipals().each{
            cnt += sessionRegistry.getAllSessions(it, false).size()
        }    

        render cnt
    }
必须采取的其他步骤:

  • 从grails安装模板(grails安装模板)
  • 将侦听器添加到web.xml:

    <listener>
        <listener-class>org.springframework.security.web.session.HttpSessionEventPublisher</listener-class>
    </listener>
    
    
    org.springframework.security.web.session.HttpSessionEventPublisher
    
  • 现在它工作了

    太好了!:)


    (现在接下来的步骤是-定义eventlistener(当用户登录时)检查许可证(会话)的数量并允许或拒绝访问他。但我认为这并没有那么棘手…我们将看到…

    嘿。谢谢你的回答!我的第一种方法几乎是朝着同一个方向发展的,但后来我问自己——既然已经完成了,为什么还要实施某种“会话控制策略”?!使用spring安全插件(以及spring中的一些附加库)为您提供了完成此类任务的所有可能性。(我已经用一点方法回答了我自己的问题;)为什么选择spring-security-core-2.0.6.RELEASE.jar?该插件使用SpringSecurity3.0;您不应该混入不兼容的jar文件。另外,即使有必要,在BuildConfig中添加依赖项也比在lib dir中添加依赖项要好得多。谢谢burt,你说得对!我在nabble上找到了一个使用类的例子,我想我只能在旧版本的SpringSecurity中找到它(顺便说一句,它起作用了…),但我看得不够深入。我从我的库目录中删除了lib,它仍然有效;)顺便说一句,为什么不可能直接从“springSecurityService”获取此类信息?我认为这样的信息可以在任何地方使用,比如“浮动许可证”等出现问题的地方。。。(ala springSecurityService.GetSessionUsed()或springSecurityService.GetNumuserLoggeDid())出现错误,因为注入的SessionRegistry始终包含0个会话。我们通过“grails安装模板”解决了这个问题。但是要小心!它将删除web.xml中的所有自定义配置