Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Plugin admin console pages show NPE when login expired #357

Closed
guusdk opened this issue Mar 15, 2023 · 3 comments
Closed

Plugin admin console pages show NPE when login expired #357

guusdk opened this issue Mar 15, 2023 · 3 comments

Comments

@guusdk
Copy link
Member

guusdk commented Mar 15, 2023

When a page of the admin console (provided by a plugin) is opened after the authenticated user session expires, a NullPointerException is shown on screen. Instead, the admin console should redirect to the login screen.

Exception:
java.lang.NullPointerException
	at org.jivesoftware.openfire.admin.decorators.main_jsp._jspService(main_jsp.java:222)
	at org.apache.jasper.runtime.HttpJspBase.service(HttpJspBase.java:71)
	at javax.servlet.http.HttpServlet.service(HttpServlet.java:790)
	at org.eclipse.jetty.servlet.ServletHolder$NotAsync.service(ServletHolder.java:1459)
	at org.eclipse.jetty.servlet.ServletHolder.handle(ServletHolder.java:799)
	at org.eclipse.jetty.servlet.ServletHandler$ChainEnd.doFilter(ServletHandler.java:1626)
	at org.eclipse.jetty.servlet.ServletHandler.doHandle(ServletHandler.java:548)
	at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:143)
	at org.eclipse.jetty.security.SecurityHandler.handle(SecurityHandler.java:620)
	at org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:127)
	at org.eclipse.jetty.server.handler.ScopedHandler.nextHandle(ScopedHandler.java:235)
	at org.eclipse.jetty.server.session.SessionHandler.doHandle(SessionHandler.java:1624)
	at org.eclipse.jetty.server.handler.ScopedHandler.nextHandle(ScopedHandler.java:233)
	at org.eclipse.jetty.server.handler.ContextHandler.doHandle(ContextHandler.java:1434)
	at org.eclipse.jetty.server.handler.ScopedHandler.nextScope(ScopedHandler.java:188)
	at org.eclipse.jetty.servlet.ServletHandler.doScope(ServletHandler.java:501)
	at org.eclipse.jetty.server.session.SessionHandler.doScope(SessionHandler.java:1594)
	at org.eclipse.jetty.server.handler.ScopedHandler.nextScope(ScopedHandler.java:186)
	at org.eclipse.jetty.server.handler.ContextHandler.doScope(ContextHandler.java:1349)
	at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:141)
	at org.eclipse.jetty.server.Dispatcher.include(Dispatcher.java:128)
	at com.opensymphony.sitemesh.compatability.OldDecorator2NewDecorator.render(OldDecorator2NewDecorator.java:46)
	at com.opensymphony.sitemesh.webapp.decorator.BaseWebAppDecorator.render(BaseWebAppDecorator.java:33)
	at com.opensymphony.sitemesh.webapp.SiteMeshFilter.doFilter(SiteMeshFilter.java:84)
	at org.eclipse.jetty.servlet.FilterHolder.doFilter(FilterHolder.java:193)
	at org.eclipse.jetty.servlet.ServletHandler$Chain.doFilter(ServletHandler.java:1601)
	at org.jivesoftware.util.LocaleFilter.doFilter(LocaleFilter.java:73)
	at org.eclipse.jetty.servlet.FilterHolder.doFilter(FilterHolder.java:193)
	at org.eclipse.jetty.servlet.ServletHandler$Chain.doFilter(ServletHandler.java:1601)
	at org.jivesoftware.util.SetCharacterEncodingFilter.doFilter(SetCharacterEncodingFilter.java:49)
	at org.eclipse.jetty.servlet.FilterHolder.doFilter(FilterHolder.java:193)
	at org.eclipse.jetty.servlet.ServletHandler$Chain.doFilter(ServletHandler.java:1601)
	at org.jivesoftware.admin.PluginFilter.doFilter(PluginFilter.java:226)
	at org.eclipse.jetty.servlet.FilterHolder.doFilter(FilterHolder.java:193)
	at org.eclipse.jetty.servlet.ServletHandler$Chain.doFilter(ServletHandler.java:1601)
	at org.jivesoftware.admin.AuthCheckFilter.doFilter(AuthCheckFilter.java:234)
	at org.eclipse.jetty.servlet.FilterHolder.doFilter(FilterHolder.java:201)
	at org.eclipse.jetty.servlet.ServletHandler$Chain.doFilter(ServletHandler.java:1601)
	at org.eclipse.jetty.servlet.ServletHandler.doHandle(ServletHandler.java:548)
	at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:143)
	at org.eclipse.jetty.security.SecurityHandler.handle(SecurityHandler.java:602)
	at org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:127)
	at org.eclipse.jetty.server.handler.ScopedHandler.nextHandle(ScopedHandler.java:235)
	at org.eclipse.jetty.server.session.SessionHandler.doHandle(SessionHandler.java:1624)
	at org.eclipse.jetty.server.handler.ScopedHandler.nextHandle(ScopedHandler.java:233)
	at org.eclipse.jetty.server.handler.ContextHandler.doHandle(ContextHandler.java:1434)
	at org.eclipse.jetty.server.handler.ScopedHandler.nextScope(ScopedHandler.java:188)
	at org.eclipse.jetty.servlet.ServletHandler.doScope(ServletHandler.java:501)
	at org.eclipse.jetty.server.session.SessionHandler.doScope(SessionHandler.java:1594)
	at org.eclipse.jetty.server.handler.ScopedHandler.nextScope(ScopedHandler.java:186)
	at org.eclipse.jetty.server.handler.ContextHandler.doScope(ContextHandler.java:1349)
	at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:141)
	at org.eclipse.jetty.server.handler.ContextHandlerCollection.handle(ContextHandlerCollection.java:191)
	at org.eclipse.jetty.server.handler.HandlerCollection.handle(HandlerCollection.java:146)
	at org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:127)
	at org.eclipse.jetty.server.Server.handle(Server.java:516)
	at org.eclipse.jetty.server.HttpChannel.lambda$handle$1(HttpChannel.java:388)
	at org.eclipse.jetty.server.HttpChannel.dispatch(HttpChannel.java:633)
	at org.eclipse.jetty.server.HttpChannel.handle(HttpChannel.java:380)
	at org.eclipse.jetty.server.HttpConnection.onFillable(HttpConnection.java:277)
	at org.eclipse.jetty.io.AbstractConnection$ReadCallback.succeeded(AbstractConnection.java:311)
	at org.eclipse.jetty.io.FillInterest.fillable(FillInterest.java:105)
	at org.eclipse.jetty.io.ssl.SslConnection$DecryptedEndPoint.onFillable(SslConnection.java:555)
	at org.eclipse.jetty.io.ssl.SslConnection.onFillable(SslConnection.java:410)
	at org.eclipse.jetty.io.ssl.SslConnection$2.succeeded(SslConnection.java:164)
	at org.eclipse.jetty.io.FillInterest.fillable(FillInterest.java:105)
	at org.eclipse.jetty.io.ChannelEndPoint$1.run(ChannelEndPoint.java:104)
	at org.eclipse.jetty.util.thread.strategy.EatWhatYouKill.runTask(EatWhatYouKill.java:338)
	at org.eclipse.jetty.util.thread.strategy.EatWhatYouKill.doProduce(EatWhatYouKill.java:315)
	at org.eclipse.jetty.util.thread.strategy.EatWhatYouKill.tryProduce(EatWhatYouKill.java:173)
	at org.eclipse.jetty.util.thread.strategy.EatWhatYouKill.run(EatWhatYouKill.java:131)
	at org.eclipse.jetty.util.thread.ReservedThreadExecutor$ReservedThread.run(ReservedThreadExecutor.java:386)
	at org.eclipse.jetty.util.thread.QueuedThreadPool.runJob(QueuedThreadPool.java:883)
	at org.eclipse.jetty.util.thread.QueuedThreadPool$Runner.run(QueuedThreadPool.java:1034)
	at java.lang.Thread.run(Thread.java:750)

Corresponding code from main_jsp.java:

    211     String path = request.getContextPath();
    212     // Decorated pages will typically must set a pageID and optionally set a subPageID
    213     // and extraParams. Store these values as request attributes so that the tab and sidebar
    214     // handling tags can get at the data.
    215     request.setAttribute("pageID", decoratedPage.getProperty("meta.pageID"));
    216     request.setAttribute("subPageID", decoratedPage.getProperty("meta.subPageID"));
    217     request.setAttribute("extraParams", decoratedPage.getProperty("meta.extraParams"));
    218 
    219     // Message HTML can be passed in:
    220     String message = decoratedPage.getProperty("page.message");
    221 
    222     pageContext.setAttribute( "usernameHtmlEscaped", StringUtils.escapeHTMLTags(JID.unescapeNode(webManager.getUser().getUsername())) );
    223 
    224       out.write("\n\n<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.0 Transitional//EN\">\n\n");
    225       if (_jspx_meth_fmt_005fsetBundle_005f0(_jspx_page_context))
    226         return;
    227       out.write("\n<html>\n    <head>\n        <meta charset=\"UTF-8\">\n        <meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge\">\n        <me>
    228       out.print( AdminConsole.getAppName() );
    229       out.write(' ');
    230       if (_jspx_meth_fmt_005fmessage_005f0(_jspx_page_context))
    231         return;
    232       out.write(':');
    233       out.write(' ');
    234       if (_jspx_meth_decorator_005ftitle_005f0(_jspx_page_context))
    235         return;

As the stacktrace shows, this code flows through org.jivesoftware.admin.AuthCheckFilter.doFilter(AuthCheckFilter.java:234) which should have redirected to the login page. As it did not, it's likely that the page was added to the 'excludes' - while it really shouldn't have.

@guusdk
Copy link
Member Author

guusdk commented Mar 15, 2023

This seems to have been introduced by the changes for #35

@guusdk
Copy link
Member Author

guusdk commented Mar 15, 2023

Hmpf.

The public API that's part of the Monitoring Service (to get the logs) is instantiated under https://example.org:7443/monitoring/

To make this API available, the context root monitoring is added to AuthCheckFilter's 'excludes', which is a list of URL patterns that skip authentication.

The admin console pages are under https://example.org:7443/plugins/monitoring/

Both the BOSH and Admin servers use the same AuthCheckFilter.

AuthCheckFilter strips any leading plugins/ from the URL, before it evaluates if the URL matches an exclude.

This causes the API's URL base (monitoring) to be equal to the admin console page's base plugins/monitoring.

guusdk added a commit to guusdk/openfire-monitoring-plugin that referenced this issue Mar 15, 2023
…ser session expired

The NPE shown was an artifact of the page being processed without authentication in place. This should be prevented by the AuthCheckFilter.

Sadly, a naming collision prevents the AuthCheckFilter to operate on the Monitoring Service admin console pages.

This commit prevents the naming collision, by renaming the endpoint on which the public API for logs is exposed (from 'monitoring' to 'logs').
guusdk added a commit to guusdk/openfire-monitoring-plugin that referenced this issue Mar 15, 2023
…ser session expired

The NPE shown was an artifact of the page being processed without authentication in place. This should be prevented by the AuthCheckFilter.

Sadly, a naming collision prevents the AuthCheckFilter to operate on the Monitoring Service admin console pages.

This commit prevents the naming collision, by renaming the endpoint on which the public API for logs is exposed (from 'monitoring' to 'logs').
@Fishbowler
Copy link
Member

Can't reproduce this following #360 - close?

guusdk added a commit to guusdk/openfire-monitoring-plugin that referenced this issue Nov 22, 2024
…ser session expired

The NPE shown was an artifact of the page being processed without authentication in place. This should be prevented by the AuthCheckFilter.

Sadly, a naming collision prevents the AuthCheckFilter to operate on the Monitoring Service admin console pages.

This commit prevents the naming collision, by renaming the endpoint on which the public API for logs is exposed (from 'monitoring' to 'logs').
guusdk added a commit to guusdk/openfire-monitoring-plugin that referenced this issue Nov 22, 2024
…ser session expired

The NPE shown was an artifact of the page being processed without authentication in place. This should be prevented by the AuthCheckFilter.

Sadly, a naming collision prevents the AuthCheckFilter to operate on the Monitoring Service admin console pages.

This commit prevents the naming collision, by renaming the endpoint on which the public API for logs is exposed (from 'monitoring' to 'logs').
@guusdk guusdk closed this as completed in 3632cf9 Nov 22, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants