Uploaded image for project: 'Geode'
  1. Geode
  2. GEODE-3951

ClassCastException in PULSE Logout - Default Configurations

Agile BoardRank to TopRank to BottomAttach filesAttach ScreenshotBulk Copy AttachmentsBulk Move AttachmentsVotersStop watchingWatchersCreate sub-taskConvert to sub-taskLinkCloneLabelsUpdate Comment AuthorReplace String in CommentUpdate Comment VisibilityDelete Comments
    XMLWordPrintableJSON

Details

    • Bug
    • Status: Closed
    • Trivial
    • Resolution: Fixed
    • None
    • 1.4.0
    • pulse
    • None

    Description

      The issue is 100% reproducible (latest develop branch) when using PULSE in embedded mode and the default configurations, the integrated security feature must not be enabled.

      Steps to reproduce:

      1. Start locator: gfsh start locator --name=locator1.
      2. Open Pulse: gfsh start pulse.
      3. Login into pulse application.
      4. Click on the logout button.
      

      At this stage, the following exception will be shown:

      HTTP ERROR 500
      Problem accessing /pulse/clusterLogout. Reason:
          Server Error
      
      Caused by:
      java.lang.ClassCastException: org.springframework.security.authentication.UsernamePasswordAuthenticationToken cannot be cast to org.apache.geode.tools.pulse.internal.security.GemFireAuthentication
      	at org.apache.geode.tools.pulse.internal.security.LogoutHandler.onLogoutSuccess(LogoutHandler.java:43)
      	at org.springframework.security.web.authentication.logout.LogoutFilter.doFilter(LogoutFilter.java:111)
      	at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:331)
      	at org.springframework.security.web.header.HeaderWriterFilter.doFilterInternal(HeaderWriterFilter.java:64)
      	at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
      	at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:331)
      	at org.springframework.security.web.context.request.async.WebAsyncManagerIntegrationFilter.doFilterInternal(WebAsyncManagerIntegrationFilter.java:56)
      	at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
      	at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:331)
      	at org.springframework.security.web.context.SecurityContextPersistenceFilter.doFilter(SecurityContextPersistenceFilter.java:105)
      	at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:331)
      	at org.springframework.security.web.FilterChainProxy.doFilterInternal(FilterChainProxy.java:214)
      	at org.springframework.security.web.FilterChainProxy.doFilter(FilterChainProxy.java:177)
      	at org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:346)
      	at org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:262)
      	at org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1668)
      	at org.eclipse.jetty.servlet.ServletHandler.doHandle(ServletHandler.java:581)
      	at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:143)
      	at org.eclipse.jetty.security.SecurityHandler.handle(SecurityHandler.java:548)
      	at org.eclipse.jetty.server.session.SessionHandler.doHandle(SessionHandler.java:226)
      	at org.eclipse.jetty.server.handler.ContextHandler.doHandle(ContextHandler.java:1180)
      	at org.eclipse.jetty.servlet.ServletHandler.doScope(ServletHandler.java:511)
      	at org.eclipse.jetty.server.session.SessionHandler.doScope(SessionHandler.java:185)
      	at org.eclipse.jetty.server.handler.ContextHandler.doScope(ContextHandler.java:1112)
      	at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:141)
      	at org.eclipse.jetty.server.handler.HandlerCollection.handle(HandlerCollection.java:119)
      	at org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:134)
      	at org.eclipse.jetty.server.Server.handle(Server.java:524)
      	at org.eclipse.jetty.server.HttpChannel.handle(HttpChannel.java:319)
      	at org.eclipse.jetty.server.HttpConnection.onFillable(HttpConnection.java:253)
      	at org.eclipse.jetty.io.AbstractConnection$ReadCallback.succeeded(AbstractConnection.java:273)
      	at org.eclipse.jetty.io.FillInterest.fillable(FillInterest.java:95)
      	at org.eclipse.jetty.io.SelectChannelEndPoint$2.run(SelectChannelEndPoint.java:93)
      	at org.eclipse.jetty.util.thread.strategy.ExecuteProduceConsume.executeProduceConsume(ExecuteProduceConsume.java:303)
      	at org.eclipse.jetty.util.thread.strategy.ExecuteProduceConsume.produceConsume(ExecuteProduceConsume.java:148)
      	at org.eclipse.jetty.util.thread.strategy.ExecuteProduceConsume.run(ExecuteProduceConsume.java:136)
      	at org.eclipse.jetty.util.thread.QueuedThreadPool.runJob(QueuedThreadPool.java:671)
      	at org.eclipse.jetty.util.thread.QueuedThreadPool$2.run(QueuedThreadPool.java:589)
      	at java.lang.Thread.run(Thread.java:745)
      

      The problem is within the LogoutHandler class, it's always trying to get an instance of GemFireAuthentication through downcasting, but the Authentication object is an instance of GemFireAuthentication only when the Integrated Security feature is used. This means that the LogoutHandler will only be successful when the profile pulse.authentication.gemfire is active and the GemFireAuthenticationProvider is in charge. In the default case scenario, on the other hand, the Authentication object is populated by the default classes from spring-security and, thus, the exception is thrown.
      The fix should be quick and without major impact, anyway: the filter actually doesn't need to downcast to GemFireAuthentication since there's nothing extra on that object that needs to be used by the handler, it just needs to use the instance of Authentication as follows:

      public void onLogoutSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication) throws IOException, ServletException {
      	logger.debug("Invoked #LogoutHandler ...");
      
          if (authentication != null) {
          	Repository.get().logoutUser(authentication.getName());
          	logger.info("#LogoutHandler : Closing GemFireAuthentication JMX Connection...");
      	}
      
      	super.onLogoutSuccess(request, response, authentication);
      }
      

      Attachments

        Activity

          This comment will be Viewable by All Users Viewable by All Users
          Cancel

          People

            jjramos Juan Ramos
            jjramos Juan Ramos
            Votes:
            0 Vote for this issue
            Watchers:
            2 Stop watching this issue

            Dates

              Created:
              Updated:
              Resolved:

              Slack

                Issue deployment