session - auth - spring security grails 3.3 1
GRAILS: ¿cómo obtener el número de usuarios actualmente conectados mediante el plugin principal de Spring Spring? (2)
Primero estaba pensando en contar usuarios que iniciaron sesión en un período determinado, pero esto puede ser impreciso.
Creo que podrías guardar el ID de usuario y la hora de su última acción. Luego puede escribir el filtro, que en cada acción actualiza esta memoria caché si el usuario está conectado. Luego, puede contar los elementos que están en la memoria caché. Si su caché sería pequeña, también podría iterar sobre ella y eliminar usuarios que están inactivos, por ejemplo. cinco minutos (o cualquier otro, como la caducidad de la sesión - por cierto, sessionId
también podría almacenarse allí, por lo que podría verificar si esa sesión todavía es válida). Si la caché es grande, el trabajo programado podría encargarse de eso.
mi problema es que quiero limitar el número de usuarios que pueden registrarse simultáneamente en mi aplicación (este valor se almacena en la base de datos). primero intenté hacer eso con alguna configuración en tomcat u otros contenedores web, pero existe el problema de que una sesión también se usa si un usuario no está conectado (mostrar la página de inicio de sesión también necesita una sesión en tomcat). Así que necesito comprobar cuántos usuarios están "realmente" conectados. He encontrado bastantes ejemplos de código para el plugin de Acegi, pero nada realmente útil sobre el plugin de Springsecurity.
mis fragmentos hasta ahora:
en resources.groovy he definido mis beans:
beans = {
sessionRegistry(org.springframework.security.concurrent.SessionRegistryImpl)
concurrentSessionController(org.springframework.security.concurrent.ConcurrentSessionControllerImpl) {
sessionRegistry = ref(''sessionRegistry'')
maximumSessions = -1
}
}
en BootStrap.groovy la mendicidad del init es:
class BootStrap {
def springSecurityService
def authenticationManager
def concurrentSessionController
def securityContextPersistenceFilter
def init = { servletContext ->
authenticationManager.sessionController = concurrentSessionController
...
y en Config.groovy he agregado:
grails.plugins.springsecurity.providerNames = [''concurrentSessionController'', ''daoAuthenticationProvider'', ''anonymousAuthenticationProvider'', ''rememberMeAuthenticationProvider'']
pero tan pronto como la aplicación comienza (aplicación-ejecución de griales), se bloquea, cuando intenta configurar SpringSecury:
...
Running Grails application..
Configuring Spring Security ...
Application context shutting down...
Application context shutdown.
limepix@turbo:~/develop/testproject$
He configurado el registro para mi aplicación: el contenido / la última entrada en mi archivo de registro es:
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)
tal vez alguien me puede señalar algunos documentos, ejemplos o directamente puede decirme cómo obtener el número de usuarios actualmente conectados.
saludo de nuremberg, alemania
limepix
¡Gracias por tu respuesta! Ahora lo tengo...
Los pasos que tomé son:
Definiendo los frijoles:
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''
}
}
luego en mi controlador inyecté:
class SystemController {
def sessionRegistry
y el cheque, cuántas sesiones están actualmente en uso:
def sessioncount = {
def cnt = 0
sessionRegistry.getAllPrincipals().each{
cnt += sessionRegistry.getAllSessions(it, false).size()
}
render cnt
}
pasos adicionales que deben hacerse:
- instalar plantillas de griales (grails install-templates)
agregar oyente a web.xml:
<listener> <listener-class>org.springframework.security.web.session.HttpSessionEventPublisher</listener-class> </listener>
y ahora funciona!
¡estupendo! :)
(ahora los siguientes pasos son: definir un eventlistener (cuando el usuario inicia sesión) verificar el número de licencias (sesiones) y permitir o denegar el acceso a él, pero creo que no es tan complicado ... ya veremos. ..)