GRAILS: как узнать количество вошедших в систему пользователей с помощью плагина ядра безопасности Spring? - PullRequest
3 голосов
/ 11 июля 2011

Моя проблема в том, что я хочу ограничить количество пользователей, которые могут одновременно регистрироваться в моем приложении (это значение хранится в базе данных).Сначала я попытался сделать это с некоторой конфигурацией в tomcat или других веб-контейнерах - но есть проблема, что сеанс используется также, если пользователь не вошел в систему (отображение страницы входа в систему также требует сеанса в tomcat) ..Поэтому мне нужно проверить, сколько пользователей «действительно» вошли в систему. Я нашел довольно много примеров кода для плагина acegi, но ничего особенно полезного в плагине Springsecurity Core.

мои фрагменты пока что:

в resources.groovy я определил мои bean-компоненты:

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

    concurrentSessionController(org.springframework.security.concurrent.ConcurrentSessionControllerImpl) { 
        sessionRegistry = ref('sessionRegistry') 
        maximumSessions = -1 
   }
}

в BootStrap.groovy, начало инициализации:

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

Ответы [ 2 ]

4 голосов
/ 13 июля 2011

Спасибо за ваш ответ!Теперь я понял ...

Шаги, которые я предпринял:

Определение бобов:

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
    }

дополнительные шаги, которые необходимо сделать:

  1. установка шаблонов из grails (grails install-templates)
  2. добавить слушателя в web.xml:

    <listener>
        <listener-class>org.springframework.security.web.session.HttpSessionEventPublisher</listener-class>
    </listener>
    

и теперь это работает!

здорово!:)

(теперь следующие шаги - определение обработчика событий (когда пользователь входит в систему) проверяет количество лицензий (сеансов) и разрешает или запрещает доступ к нему. Но я думаю, что это не так сложно... посмотрим ...)

1 голос
/ 13 июля 2011

Сначала я думал о подсчете пользователей, которые вошли в данный период, но это может быть неточным.

Я думаю, вы могли бы кэшировать идентификатор пользователя и время его последнего действия. Затем вы можете написать фильтр, который при каждом действии обновляет этот кеш, если пользователь вошел в систему. Затем вы можете просто посчитать элементы, которые находятся в кеше. Если ваш кэш будет маленьким, вы также можете перебирать его и удалять пользователей, которые неактивны, например, для. пять минут (или любые другие, например, истечение сеанса - btw: sessionId также может храниться там, чтобы вы могли проверить, является ли этот сеанс все еще действительным). Если кеш большой, запланированная работа может позаботиться об этом.

...