FELIX-3006 : Please create a logout button for the web console screen
git-svn-id: https://svn.apache.org/repos/asf/felix/trunk@1662638 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/webconsole/src/main/java/org/apache/felix/webconsole/AbstractWebConsolePlugin.java b/webconsole/src/main/java/org/apache/felix/webconsole/AbstractWebConsolePlugin.java
index e571565..9d52489 100644
--- a/webconsole/src/main/java/org/apache/felix/webconsole/AbstractWebConsolePlugin.java
+++ b/webconsole/src/main/java/org/apache/felix/webconsole/AbstractWebConsolePlugin.java
@@ -737,6 +737,9 @@
SortedMap categoryMap = sortMenuCategoryMap( menuMap, appRoot );
pw.println( "<ul id=\"navmenu\">" );
renderSubmenu( categoryMap, appRoot, pw, 0 );
+ pw.println("<li class=\"logoutButton navMenuItem-0\">");
+ pw.println("<a href=\"" + appRoot + "/logout\">${logout}</a>");
+ pw.println("</li>");
pw.println( "</ul>" );
}
}
diff --git a/webconsole/src/main/java/org/apache/felix/webconsole/internal/servlet/OsgiManager.java b/webconsole/src/main/java/org/apache/felix/webconsole/internal/servlet/OsgiManager.java
index 477559b..3f63db6 100644
--- a/webconsole/src/main/java/org/apache/felix/webconsole/internal/servlet/OsgiManager.java
+++ b/webconsole/src/main/java/org/apache/felix/webconsole/internal/servlet/OsgiManager.java
@@ -53,6 +53,8 @@
import org.apache.felix.webconsole.BrandingPlugin;
import org.apache.felix.webconsole.WebConsoleConstants;
import org.apache.felix.webconsole.WebConsoleSecurityProvider;
+import org.apache.felix.webconsole.WebConsoleSecurityProvider2;
+import org.apache.felix.webconsole.WebConsoleSecurityProvider3;
import org.apache.felix.webconsole.internal.OsgiManagerPlugin;
import org.apache.felix.webconsole.internal.Util;
import org.apache.felix.webconsole.internal.core.BundlesServlet;
@@ -168,6 +170,10 @@
static final String DEFAULT_HTTP_SERVICE_SELECTOR = ""; //$NON-NLS-1$
+ private static final String HEADER_AUTHORIZATION = "Authorization"; //$NON-NLS-1$
+
+ private static final String HEADER_WWW_AUTHENTICATE = "WWW-Authenticate"; //$NON-NLS-1$
+
/**
* The default value for the {@link #PROP_MANAGER_ROOT} configuration
* property (value is "/system/console").
@@ -514,10 +520,16 @@
}
path = path.concat(holder.getDefaultPluginLabel());
response.sendRedirect(path);
+ response.setContentLength(0);
return;
}
- int slash = pathInfo.indexOf("/", 1);
+ if (pathInfo.equals("/logout")) { //$NON-NLS-1$
+ logout(request, response);
+ return;
+ }
+
+ int slash = pathInfo.indexOf("/", 1); //$NON-NLS-1$
if (slash < 2)
{
slash = pathInfo.length();
@@ -568,6 +580,63 @@
}
}
+ private final void logout(HttpServletRequest request, HttpServletResponse response)
+ throws IOException
+ {
+ // check if special logout cookie is set, this is used to prevent
+ // from an endless loop with basic auth
+ Cookie[] cookies = request.getCookies();
+ boolean found = false;
+ if ( cookies != null )
+ {
+ for(int i=0;i<cookies.length;i++)
+ {
+ if ( cookies[i].getName().equals("logout") ) //$NON-NLS-1$
+ {
+ found = true;
+ break;
+ }
+ }
+ }
+ if ( found )
+ {
+ // redirect to main page
+ String url = request.getRequestURI();
+ final int lastSlash = url.lastIndexOf('/');
+ final Cookie c = new Cookie("logout", "true"); //$NON-NLS-1$ //$NON-NLS-2$
+ c.setMaxAge(0);
+ response.addCookie(c);
+ response.sendRedirect(url.substring(0, lastSlash));
+ return;
+ }
+ Object securityProvider = securityProviderTracker.getService();
+ if (securityProvider instanceof WebConsoleSecurityProvider3)
+ {
+ ((WebConsoleSecurityProvider3) securityProvider).logout(request, response);
+ }
+ else
+ {
+ // if the security provider doesn't support logout, we try to
+ // logout the default basic authentication mechanism
+ // See https://issues.apache.org/jira/browse/FELIX-3006
+
+ // check for basic authentication
+ String auth = request.getHeader(HEADER_AUTHORIZATION); //$NON-NLS-1$
+ if (null != auth && auth.toLowerCase().startsWith("basic ")) { //$NON-NLS-1$
+ Map config = getConfiguration();
+ String realm = ConfigurationUtil.getProperty(config, PROP_REALM, DEFAULT_REALM);
+ response.setHeader(HEADER_WWW_AUTHENTICATE, "Basic realm=\"" + realm + "\""); //$NON-NLS-1$ //$NON-NLS-2$
+ response.addCookie(new Cookie("logout", "true")); //$NON-NLS-1$ //$NON-NLS-2$
+ response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
+ }
+ }
+
+ // clean-up
+ request.removeAttribute(HttpContext.REMOTE_USER);
+ request.removeAttribute(HttpContext.AUTHORIZATION);
+ request.removeAttribute(WebConsoleSecurityProvider2.USER_ATTRIBUTE);
+ }
+
private final AbstractWebConsolePlugin getConsolePlugin(final String label)
{
// backwards compatibility for the former "install" action which is
diff --git a/webconsole/src/main/resources/OSGI-INF/l10n/bundle.properties b/webconsole/src/main/resources/OSGI-INF/l10n/bundle.properties
index c5a1cea..3383e15 100644
--- a/webconsole/src/main/resources/OSGI-INF/l10n/bundle.properties
+++ b/webconsole/src/main/resources/OSGI-INF/l10n/bundle.properties
@@ -46,6 +46,7 @@
reset=Reset
delete=Delete
refresh=Refresh
+logout=Log out
# VMStat plugin
vmstat.pluginTitle=System Information
diff --git a/webconsole/src/main/resources/res/ui/webconsole.css b/webconsole/src/main/resources/res/ui/webconsole.css
index 0ddc954..a2fc654 100644
--- a/webconsole/src/main/resources/res/ui/webconsole.css
+++ b/webconsole/src/main/resources/res/ui/webconsole.css
@@ -189,8 +189,11 @@
list-style: none
}
/* language selection element */
-#langSelect { position: absolute; top: 5px; right: 5px }
+#langSelect { position: absolute; top: 5px; right: 5px }
#langSelect img { display: block; padding: 2px 0 }
+/* logout element */
+.logoutButton { float: right; text-decoration: none }
+
.filterBox { float: left; margin-left: 1em }
.servicesFilter { width: 400px; }