Announcement Announcement Module
Collapse
No announcement yet.
Prevent concurrent session with HttpInvoker remoting? Page Title Module
Move Remove Collapse
This topic is closed
X
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • Prevent concurrent session with HttpInvoker remoting?

    Hi all!

    I'm working on a rich client project using the HttpInvoker remoting mechanism. I'm using a BasicProcessingFilter and it seems to work fine. Now I'd like to prevent concurrent session with a session controller, that's why I tried to add an HttpSessionContextIntegrationFilter. But it doesn't seem to work. I'm missing something but I can't see what...

    Here's my configuration:

    Jar version

    The acegi jar snapshot (0.9.0) used in the Spring RCP framework project

    web.xml
    Code:
      <filter>
          <filter-name>Acegi Filter Chain Proxy</filter-name>
          <filter-class>net.sf.acegisecurity.util.FilterToBeanProxy</filter-class>
          <init-param>
              <param-name>targetClass</param-name>
              <param-value>net.sf.acegisecurity.util.FilterChainProxy</param-value>
          </init-param>
      </filter>
    
      <filter-mapping>
        <filter-name>Acegi Filter Chain Proxy</filter-name>
        <url-pattern>/*</url-pattern>
      </filter-mapping>
    
      <listener>
        <listener-class>net.sf.acegisecurity.ui.session.HttpSessionEventPublisher</listener-class>
      </listener>
    security-context.xml
    Code:
      <bean id="authenticationManager" class="net.sf.acegisecurity.providers.ProviderManager">
        <property name="providers">
          <list>
            <ref bean="daoAuthenticationProvider"/>
          </list>
        </property>
        <property name="sessionController"><ref bean="concurrentSessionController"/></property>
      </bean>
    
      <bean id="daoAuthenticationProvider" class="net.sf.acegisecurity.providers.dao.DaoAuthenticationProvider">
        <property name="authenticationDao"><ref bean="authenticationDao"/></property>
      </bean>
    
      <bean id="concurrentSessionController" class="net.sf.acegisecurity.providers.ConcurrentSessionControllerImpl">
        <property name="maxSessions"><value>1</value></property>
      </bean>
      
      <!-- Filters -->
      <bean id="filterChainProxy" class="net.sf.acegisecurity.util.FilterChainProxy">
        <property name="filterInvocationDefinitionSource">
          <value>
            CONVERT_URL_TO_LOWERCASE_BEFORE_COMPARISON
            PATTERN_TYPE_APACHE_ANT
            /**=httpSessionContextIntegrationFilter,basicProcessingFilter
          </value>
        </property>
      </bean>
      
      <bean id="httpSessionContextIntegrationFilter" class="net.sf.acegisecurity.context.HttpSessionContextIntegrationFilter">
        <property name="context"><value>net.sf.acegisecurity.context.SecurityContextImpl</value></property>
      </bean>
        
      <bean id="basicProcessingFilter" class="net.sf.acegisecurity.ui.basicauth.BasicProcessingFilter">
        <property name="authenticationManager"><ref bean="authenticationManager"/></property>
        <property name="authenticationEntryPoint"><ref bean="basicProcessingFilterEntryPoint"/></property>
      </bean>
    
      <bean id="basicProcessingFilterEntryPoint" class="net.sf.acegisecurity.ui.basicauth.BasicProcessingFilterEntryPoint">
        <property name="realmName"><value>Care manager realm</value></property>
      </bean>
    Log

    [DEBUG,PathBasedFilterInvocationDefinitionMap,http-8080-Processor25] Converted URL to lowercase, from: '/care-manager/remoteauthenticationmanager-hessian'; to:
    '/care-manager/remoteauthenticationmanager-hessian'
    [DEBUG,PathBasedFilterInvocationDefinitionMap,http-8080-Processor25] Candidate is: '/care-manager/remoteauthenticationmanager-hessian'; pattern is /**; matched=true
    [DEBUG,FilterChainProxy,http-8080-Processor25] /care-manager/RemoteAuthenticationManager-hessian at position 1 of 2 in additional filter chain; firing Filter: '
    net.sf.acegisecurity.context.HttpSessionContextInt egrationFilter@19fc25'
    [DEBUG,HttpSessionContextIntegrationFilter,http-8080-Processor25] No HttpSession currently exists - new SecurityContext instance associated with SecurityContextHolder
    [DEBUG,FilterChainProxy,http-8080-Processor25] /care-manager/RemoteAuthenticationManager-hessian at position 2 of 2 in additional filter chain; firing Filter: '
    net.sf.acegisecurity.ui.basicauth.BasicProcessingF ilter@952905'
    [DEBUG,BasicProcessingFilter,http-8080-Processor25] Authorization header: null
    [DEBUG,FilterChainProxy,http-8080-Processor25] /care-manager/RemoteAuthenticationManager-hessian reached end of additional filter chain; proceeding with original chain
    [DEBUG,ProviderManager,http-8080-Processor25] Authentication attempt using net.sf.acegisecurity.providers.dao.DaoAuthenticati onProvider
    [INFO,LoggerListener,http-8080-Processor25] Authentication success for user: root; details: null
    [DEBUG,HttpSessionContextIntegrationFilter,http-8080-Processor25] HttpSession is null, but SecurityContextHolder has not changed from default: ' net.sf.acegisecurity.context.SecurityContextImpl@1 248979: Null authentication'; not creating HttpSession or storing SecurityContextHolder contents
    [DEBUG,HttpSessionContextIntegrationFilter,http-8080-Processor25] SecurityContextHolder set to new context, as request processing completed
    [DEBUG,PathBasedFilterInvocationDefinitionMap,http-8080-Processor25] Converted URL to lowercase, from: '/care-manager/businessrepositorymanager'; to: '/care-man
    ager/businessrepositorymanager'
    [DEBUG,PathBasedFilterInvocationDefinitionMap,http-8080-Processor25] Candidate is: '/care-manager/businessrepositorymanager'; pattern is /**; matched=true
    [DEBUG,FilterChainProxy,http-8080-Processor25] /care-manager/businessRepositoryManager at position 1 of 2 in additional filter chain; firing Filter: 'net.sf.acegisecurity.context.HttpSessionContextIn tegrationFilter@19fc25'
    [DEBUG,HttpSessionContextIntegrationFilter,http-8080-Processor25] No HttpSession currently exists - new SecurityContext instance associated with SecurityContextHolder
    [DEBUG,FilterChainProxy,http-8080-Processor25] /care-manager/businessRepositoryManager at position 2 of 2 in additional filter chain; firing Filter: 'net.sf.acegisecurity.ui.basicauth.BasicProcessing Filter@952905'
    [DEBUG,BasicProcessingFilter,http-8080-Processor25] Authorization header: Basiccm9vdDpyb290
    [DEBUG,HttpSessionEventPublisher,http-8080-Processor25] Publishing event: net.sf.acegisecurity.ui.session.HttpSessionCreated Event[source=org.apache.catalina.ses
    sion.StandardSessionFacade@177ff35]
    [DEBUG,ProviderManager,http-8080-Processor25] Authentication attempt using net.sf.acegisecurity.providers.dao.DaoAuthenticati onProvider
    [INFO,LoggerListener,http-8080-Processor25] Authentication success for user: root; details: net.sf.acegisecurity.ui.WebAuthenticationDetails@8 2e4f3: RemoteIpAddress: 127.0.0.1; SessionId: 4689907DA04E6B7B3F9E546F994944F7
    [DEBUG,BasicProcessingFilter,http-8080-Processor25] Authentication success: net.sf.acegisecurity.providers.UsernamePasswordAut henticationToken@1852a81: Username: net.sf.acegisecurity.providers.dao.User@1a9883d: Username: root; Password: [PROTECTED]; Enabled: true; AccountNonExpired: true; credentialsNonExpired: true; A
    ccountNonLocked: true; Granted Authorities: ROLE_ADMIN, ROLE_USER; Password: [PROTECTED]; Authenticated: true; Details: net.sf.acegisecurity.ui.WebAuthenticationDetails@8 2e4f3: RemoteIpAddress: 127.0.0.1; SessionId: 4689907DA04E6B7B3F9E546F
    994944F7; Granted Authorities: ROLE_ADMIN, ROLE_USER
    [DEBUG,FilterChainProxy,http-8080-Processor25] /care-manager/businessRepositoryManager reached end of additional filter chain; proceeding with original chain
    [DEBUG,AbstractSecurityInterceptor,http-8080-Processor25] Secure object: invocation: method 'getBusinessRepositories', arguments []; target is of class [com.sv.cm.service.impl.BusinessRepositoryManagerIm pl]; ConfigAttributes: [ROLE_ADMIN]
    [DEBUG,AbstractSecurityInterceptor,http-8080-Processor25] Previously Authenticated: net.sf.acegisecurity.providers.UsernamePasswordAut henticationToken@1852a81:
    Username: net.sf.acegisecurity.providers.dao.User@1a9883d: Username: root; Password: [PROTECTED]; Enabled: true; AccountNonExpired: true; credentialsNonExpired:
    true; AccountNonLocked: true; Granted Authorities: ROLE_ADMIN, ROLE_USER; Password: [PROTECTED]; Authenticated: true; Details: net.sf.acegisecurity.ui.WebAuthenticationDetails@8 2e4f3: RemoteIpAddress: 127.0.0.1; SessionId: 4689907DA04E6B7B
    3F9E546F994944F7; Granted Authorities: ROLE_ADMIN, ROLE_USER
    [DEBUG,AbstractSecurityInterceptor,http-8080-Processor25] Authorization successful
    [DEBUG,AbstractSecurityInterceptor,http-8080-Processor25] RunAsManager did not change Authentication object
    [DEBUG,PathBasedFilterInvocationDefinitionMap,http-8080-Processor24] Converted URL to lowercase, from: '/care-manager/businessrepositorymanager'; to: '/care-man
    ager/businessrepositorymanager'
    [DEBUG,PathBasedFilterInvocationDefinitionMap,http-8080-Processor24] Candidate is: '/care-manager/businessrepositorymanager'; pattern is /**; matched=true
    [DEBUG,FilterChainProxy,http-8080-Processor24] /care-manager/businessRepositoryManager at position 1 of 2 in additional filter chain; firing Filter: 'net.sf.acegisecurity.context.HttpSessionContextIn tegrationFilter@19fc25'
    [DEBUG,HttpSessionContextIntegrationFilter,http-8080-Processor24] No HttpSession currently exists - new SecurityContext instance associated with SecurityContextHolder
    [DEBUG,FilterChainProxy,http-8080-Processor24] /care-manager/businessRepositoryManager at position 2 of 2 in additional filter chain; firing Filter: 'net.sf.acegisecurity.ui.basicauth.BasicProcessing Filter@952905'
    [DEBUG,BasicProcessingFilter,http-8080-Processor24] Authorization header: Basic cm9vdDpyb290
    [DEBUG,HttpSessionEventPublisher,http-8080-Processor24] Publishing event: net.sf.acegisecurity.ui.session.HttpSessionCreated Event[source=org.apache.catalina.ses
    sion.StandardSessionFacade@171120a]
    [DEBUG,BasicProcessingFilter,http-8080-Processor24] Authentication request for user: root failed: net.sf.acegisecurity.providers.ConcurrentLoginExce ption: root
    has reached the maximum concurrent logins

    [DEBUG,HttpSessionContextIntegrationFilter,http-8080-Processor24] SecurityContext stored to HttpSession: 'net.sf.acegisecurity.context.SecurityContextImpl@ 13c29
    6b: Null authentication'
    [DEBUG,HttpSessionContextIntegrationFilter,http-8080-Processor25] SecurityContext stored to HttpSession: 'net.sf.acegisecurity.context.SecurityContextImpl@ c360a
    5: Authentication: net.sf.acegisecurity.providers.UsernamePasswordAut hentication
    Token@1852a81: Username: net.sf.acegisecurity.providers.dao.User@1a9883d: Userna
    me: root; Password: [PROTECTED]; Enabled: true; AccountNonExpired: true; credentialsNonExpired: true; AccountNonLocked: true; Granted Authorities: ROLE_ADMIN, R
    OLE_USER; Password: [PROTECTED]; Authenticated: true; Details: net.sf.acegisecurity.ui.WebAuthenticationDetails@8 2e4f3: RemoteIpAddress: 127.0.0.1; SessionId: 4689907DA04E6B7B3F9E546F994944F7; Granted Authorities: ROLE_ADMIN, ROLE_USER'
    [DEBUG,HttpSessionContextIntegrationFilter,http-8080-Processor25] SecurityContextHolder set to new context, as request processing completed
    [DEBUG,HttpSessionContextIntegrationFilter,http-8080-Processor24] SecurityContextHolder set to new context, as request processing completed

  • #2
    I don't see how this would work, as HTTP Invoker has no way of presenting a jsessionid (at least I'm aware of) on subsequent requests. You could probably roll-your-own extension of HTTP Invoker to use HTTP Headers to reflect the jsessionid.

    Alternatively, if you understand how the net.sf.acegisecurity.providers.rcp package works (and it's not hard - I just don't want to repeat what's already in the reference guide and it's only four small class files) you could write a similar service to perform authentication. However, the returned GrantedAuthority[] would include a ticket object. The ticket object would be registered in a server-side Map along with the username. You'd then have your RemoteAuthenticationProvider use the ticket as the password on subsequent requests. The server-side AuthenticationDao would then retrieve the user from the backend, but change the password to match what the Map said the ticket should be. As such, you'll have in effect achieved concurrent login support by moving session handling to the authentication subsystem. There are hybrids of this approach too, and this approach should return a more suitable exception, but it might give you some ideas on the approach to use.

    Comment


    • #3
      Thanks a lot for your answer Ben, I'll have a look at what you described.

      Dominique

      Comment

      Working...
      X