Author: kwall
Date: Fri Feb 12 16:17:32 2016
New Revision: 1730052
URL: http://svn.apache.org/viewvc?rev=1730052&view=rev
Log:
QPID-7028: [Java Broker] Allow the OAuth2 provider to specify an optional
logout URI
* HttpRequestInteractiveAuthenticators are now responsible for producing a
logout handler to perform a redirect/forward after the logout
* OAuth2InteractiveAuthenticator logout handler redirects to an optional URI
once Web Management Console logout is complete. This allows
the user to be directed back into a page belonging to the overarching service
Added:
qpid/java/trunk/broker-plugins/management-http/src/main/java/resources/logout.html
Modified:
qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/security/auth/manager/oauth2/OAuth2AuthenticationProvider.java
qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/security/auth/manager/oauth2/OAuth2AuthenticationProviderImpl.java
qpid/java/trunk/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/HttpManagement.java
qpid/java/trunk/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/HttpManagementUtil.java
qpid/java/trunk/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/HttpRequestInteractiveAuthenticator.java
qpid/java/trunk/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/auth/OAuth2InteractiveAuthenticator.java
qpid/java/trunk/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/auth/UsernamePasswordInteractiveLogin.java
qpid/java/trunk/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/servlet/rest/LogoutServlet.java
Modified:
qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/security/auth/manager/oauth2/OAuth2AuthenticationProvider.java
URL:
http://svn.apache.org/viewvc/qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/security/auth/manager/oauth2/OAuth2AuthenticationProvider.java?rev=1730052&r1=1730051&r2=1730052&view=diff
==============================================================================
---
qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/security/auth/manager/oauth2/OAuth2AuthenticationProvider.java
(original)
+++
qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/security/auth/manager/oauth2/OAuth2AuthenticationProvider.java
Fri Feb 12 16:17:32 2016
@@ -73,6 +73,9 @@ public interface OAuth2AuthenticationPro
validValues =
{"org.apache.qpid.server.security.auth.manager.oauth2.OAuth2AuthenticationProviderImpl#validIdentityResolvers()"})
String getIdentityResolverType();
+ @ManagedAttribute( description = "Redirect URI used when the user leaves
the Web Management Console. If not specified, an internal page is used
instead.")
+ URI getLogoutURI();
+
@ManagedAttribute( description = "Client ID to identify qpid to the OAuth
endpoints", mandatory = true )
String getClientId();
Modified:
qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/security/auth/manager/oauth2/OAuth2AuthenticationProviderImpl.java
URL:
http://svn.apache.org/viewvc/qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/security/auth/manager/oauth2/OAuth2AuthenticationProviderImpl.java?rev=1730052&r1=1730051&r2=1730052&view=diff
==============================================================================
---
qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/security/auth/manager/oauth2/OAuth2AuthenticationProviderImpl.java
(original)
+++
qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/security/auth/manager/oauth2/OAuth2AuthenticationProviderImpl.java
Fri Feb 12 16:17:32 2016
@@ -19,7 +19,7 @@
package org.apache.qpid.server.security.auth.manager.oauth2;
-import static org.apache.qpid.server.util.ParameterizedTypes.*;
+import static org.apache.qpid.server.util.ParameterizedTypes.LIST_OF_STRINGS;
import java.io.IOException;
import java.io.InputStream;
@@ -56,7 +56,6 @@ import org.apache.qpid.server.plugin.Qpi
import org.apache.qpid.server.security.auth.AuthenticationResult;
import
org.apache.qpid.server.security.auth.manager.AbstractAuthenticationManager;
import org.apache.qpid.server.util.ConnectionBuilder;
-import org.apache.qpid.server.util.ParameterizedTypes;
import org.apache.qpid.server.util.ServerScopedRuntimeException;
public class OAuth2AuthenticationProviderImpl
@@ -82,6 +81,9 @@ public class OAuth2AuthenticationProvide
private boolean _tokenEndpointNeedsAuth;
@ManagedAttributeField
+ private URI _logoutURI;
+
+ @ManagedAttributeField
private String _clientId;
@ManagedAttributeField
@@ -346,6 +348,12 @@ public class OAuth2AuthenticationProvide
}
@Override
+ public URI getLogoutURI()
+ {
+ return _logoutURI;
+ }
+
+ @Override
public boolean getTokenEndpointNeedsAuth()
{
return _tokenEndpointNeedsAuth;
Modified:
qpid/java/trunk/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/HttpManagement.java
URL:
http://svn.apache.org/viewvc/qpid/java/trunk/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/HttpManagement.java?rev=1730052&r1=1730051&r2=1730052&view=diff
==============================================================================
---
qpid/java/trunk/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/HttpManagement.java
(original)
+++
qpid/java/trunk/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/HttpManagement.java
Fri Feb 12 16:17:32 2016
@@ -44,6 +44,7 @@ import javax.servlet.http.HttpServletReq
import com.google.common.util.concurrent.Futures;
import com.google.common.util.concurrent.ListenableFuture;
+
import org.apache.qpid.server.management.plugin.filter.ExceptionHandlingFilter;
import org.eclipse.jetty.io.EndPoint;
import org.eclipse.jetty.server.Connector;
@@ -109,6 +110,8 @@ public class HttpManagement extends Abst
public static final String PLUGIN_TYPE = "MANAGEMENT-HTTP";
+ public static final String DEFAULT_LOGOUT_URL = "/logout.html";
+
private static final String OPERATIONAL_LOGGING_NAME = "Web";
private static final String JSESSIONID_COOKIE_PREFIX = "JSESSIONID_";
@@ -258,7 +261,6 @@ public class HttpManagement extends Abst
root.addFilter(restAuthorizationFilter, "/apidocs/*",
EnumSet.of(DispatcherType.REQUEST));
root.addFilter(restAuthorizationFilter, "/service/*",
EnumSet.of(DispatcherType.REQUEST));
- root.addFilter(new FilterHolder(new RedirectingAuthorisationFilter()),
HttpManagementUtil.ENTRY_POINT_PATH, EnumSet.of(DispatcherType.REQUEST));
root.addFilter(new FilterHolder(new RedirectingAuthorisationFilter()),
"/index.html", EnumSet.of(DispatcherType.REQUEST));
root.addFilter(new FilterHolder(new RedirectingAuthorisationFilter()),
"/", EnumSet.of(DispatcherType.REQUEST));
@@ -290,7 +292,6 @@ public class HttpManagement extends Abst
root.addServlet(new ServletHolder(new SaslServlet()), "/service/sasl");
- root.addServlet(new ServletHolder(new
DefinedFileServlet("index.html")), HttpManagementUtil.ENTRY_POINT_PATH);
root.addServlet(new ServletHolder(new
RootServlet("/","/apidocs/","index.html")), "/");
root.addServlet(new ServletHolder(new LogoutServlet()), "/logout");
Modified:
qpid/java/trunk/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/HttpManagementUtil.java
URL:
http://svn.apache.org/viewvc/qpid/java/trunk/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/HttpManagementUtil.java?rev=1730052&r1=1730051&r2=1730052&view=diff
==============================================================================
---
qpid/java/trunk/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/HttpManagementUtil.java
(original)
+++
qpid/java/trunk/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/HttpManagementUtil.java
Fri Feb 12 16:17:32 2016
@@ -70,11 +70,6 @@ public class HttpManagementUtil
*/
public static final String ATTR_MANAGEMENT_CONFIGURATION =
"Qpid.managementConfiguration";
- /**
- * Default management entry URL
- */
- public static final String ENTRY_POINT_PATH = "/management";
-
private static final String ATTR_LOGIN_LOGOUT_REPORTER =
"Qpid.loginLogoutReporter";
private static final String ATTR_SUBJECT = "Qpid.subject";
private static final String ATTR_LOG_ACTOR = "Qpid.logActor";
Modified:
qpid/java/trunk/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/HttpRequestInteractiveAuthenticator.java
URL:
http://svn.apache.org/viewvc/qpid/java/trunk/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/HttpRequestInteractiveAuthenticator.java?rev=1730052&r1=1730051&r2=1730052&view=diff
==============================================================================
---
qpid/java/trunk/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/HttpRequestInteractiveAuthenticator.java
(original)
+++
qpid/java/trunk/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/HttpRequestInteractiveAuthenticator.java
Fri Feb 12 16:17:32 2016
@@ -22,6 +22,7 @@ package org.apache.qpid.server.managemen
import java.io.IOException;
+import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
@@ -31,10 +32,18 @@ public interface HttpRequestInteractiveA
{
interface AuthenticationHandler
{
- void handleAuthentication(HttpServletResponse response) throws
IOException;
+ void handleAuthentication(HttpServletResponse response) throws
IOException, ServletException;
+ }
+
+ interface LogoutHandler
+ {
+ void handleLogout(HttpServletResponse response) throws IOException,
ServletException;
}
AuthenticationHandler getAuthenticationHandler(HttpServletRequest request,
HttpManagementConfiguration
configuration);
+ LogoutHandler getLogoutHandler(HttpServletRequest request,
+ HttpManagementConfiguration configuration);
+
}
Modified:
qpid/java/trunk/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/auth/OAuth2InteractiveAuthenticator.java
URL:
http://svn.apache.org/viewvc/qpid/java/trunk/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/auth/OAuth2InteractiveAuthenticator.java?rev=1730052&r1=1730051&r2=1730052&view=diff
==============================================================================
---
qpid/java/trunk/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/auth/OAuth2InteractiveAuthenticator.java
(original)
+++
qpid/java/trunk/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/auth/OAuth2InteractiveAuthenticator.java
Fri Feb 12 16:17:32 2016
@@ -20,8 +20,10 @@
package org.apache.qpid.server.management.plugin.auth;
import java.io.IOException;
+import java.net.MalformedURLException;
import java.net.URI;
import java.net.URISyntaxException;
+import java.net.URL;
import java.security.AccessControlException;
import java.security.SecureRandom;
import java.util.Collections;
@@ -212,6 +214,39 @@ public class OAuth2InteractiveAuthentica
}
}
+ @Override
+ public LogoutHandler getLogoutHandler(final HttpServletRequest request,
+ final HttpManagementConfiguration
configuration)
+ {
+ if (configuration.getAuthenticationProvider(request) instanceof
OAuth2AuthenticationProvider)
+ {
+ final OAuth2AuthenticationProvider oauth2Provider =
+ (OAuth2AuthenticationProvider)
configuration.getAuthenticationProvider(request);
+
+ try
+ {
+ if (oauth2Provider.getLogoutURI() != null)
+ {
+ final URL logoutUri =
oauth2Provider.getLogoutURI().toURL();
+ return new LogoutHandler()
+ {
+ @Override
+ public void handleLogout(final HttpServletResponse
response) throws IOException
+ {
+ response.sendRedirect(logoutUri.toString());
+ }
+ };
+ }
+ }
+ catch (MalformedURLException e)
+ {
+ throw new IllegalStateException(String.format("LogoutURI has
unexpected format '%s'",
+
oauth2Provider.getLogoutURI()), e);
+ }
+ }
+ return null;
+ }
+
private String buildAuthorizationRedirectURL(final HttpServletRequest
request,
final
OAuth2AuthenticationProvider oauth2Provider)
{
Modified:
qpid/java/trunk/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/auth/UsernamePasswordInteractiveLogin.java
URL:
http://svn.apache.org/viewvc/qpid/java/trunk/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/auth/UsernamePasswordInteractiveLogin.java?rev=1730052&r1=1730051&r2=1730052&view=diff
==============================================================================
---
qpid/java/trunk/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/auth/UsernamePasswordInteractiveLogin.java
(original)
+++
qpid/java/trunk/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/auth/UsernamePasswordInteractiveLogin.java
Fri Feb 12 16:17:32 2016
@@ -22,9 +22,11 @@ package org.apache.qpid.server.managemen
import java.io.IOException;
+import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
+import org.apache.qpid.server.management.plugin.HttpManagement;
import org.apache.qpid.server.management.plugin.HttpManagementConfiguration;
import
org.apache.qpid.server.management.plugin.HttpRequestInteractiveAuthenticator;
import org.apache.qpid.server.plugin.PluggableService;
@@ -33,7 +35,11 @@ import org.apache.qpid.server.security.a
@PluggableService
public class UsernamePasswordInteractiveLogin implements
HttpRequestInteractiveAuthenticator
{
- private static String DEFAULT_LOGIN_URL = "login.html";
+ // TODO: When we refactor web management and adopt a web fragments, move
login.html and login.html
+ // to WEB-INF/ and dispatch (forward) to them, rather than client side
redirect.
+ // This would keep the login/logout pages private and inaccessible when
using auth providers
+ // such as Ouath2.
+ private static final String DEFAULT_LOGIN_URL = "login.html";
private static final AuthenticationHandler REDIRECT_HANDLER = new
AuthenticationHandler()
{
@@ -44,6 +50,15 @@ public class UsernamePasswordInteractive
}
};
+ private static final LogoutHandler LOGOUT_HANDLER = new LogoutHandler()
+ {
+ @Override
+ public void handleLogout(final HttpServletResponse response) throws
IOException
+ {
+ response.sendRedirect(HttpManagement.DEFAULT_LOGOUT_URL);
+ }
+ };
+
@Override
public AuthenticationHandler getAuthenticationHandler(final
HttpServletRequest request,
final
HttpManagementConfiguration configuration)
@@ -54,6 +69,20 @@ public class UsernamePasswordInteractive
}
else
{
+ return null;
+ }
+ }
+
+ @Override
+ public LogoutHandler getLogoutHandler(final HttpServletRequest request,
+ final HttpManagementConfiguration
configuration)
+ {
+ if(configuration.getAuthenticationProvider(request) instanceof
UsernamePasswordAuthenticationProvider)
+ {
+ return LOGOUT_HANDLER;
+ }
+ else
+ {
return null;
}
}
Modified:
qpid/java/trunk/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/servlet/rest/LogoutServlet.java
URL:
http://svn.apache.org/viewvc/qpid/java/trunk/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/servlet/rest/LogoutServlet.java?rev=1730052&r1=1730051&r2=1730052&view=diff
==============================================================================
---
qpid/java/trunk/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/servlet/rest/LogoutServlet.java
(original)
+++
qpid/java/trunk/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/servlet/rest/LogoutServlet.java
Fri Feb 12 16:17:32 2016
@@ -21,6 +21,10 @@
package org.apache.qpid.server.management.plugin.servlet.rest;
import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.List;
import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
@@ -29,37 +33,65 @@ import javax.servlet.http.HttpServletReq
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
+import org.apache.qpid.server.management.plugin.HttpManagement;
+import org.apache.qpid.server.management.plugin.HttpManagementConfiguration;
import org.apache.qpid.server.management.plugin.HttpManagementUtil;
+import
org.apache.qpid.server.management.plugin.HttpRequestInteractiveAuthenticator;
+import
org.apache.qpid.server.management.plugin.HttpRequestInteractiveAuthenticator.LogoutHandler;
+import org.apache.qpid.server.plugin.QpidServiceLoader;
@SuppressWarnings("serial")
public class LogoutServlet extends HttpServlet
{
- public static final String RETURN_URL_INIT_PARAM =
"qpid.webui_logout_redirect";
- private String _returnUrl = HttpManagementUtil.ENTRY_POINT_PATH;
+ private static final Collection<HttpRequestInteractiveAuthenticator>
AUTHENTICATORS;
+ static
+ {
+ List<HttpRequestInteractiveAuthenticator> authenticators = new
ArrayList<>();
+ for(HttpRequestInteractiveAuthenticator authenticator : (new
QpidServiceLoader()).instancesOf(HttpRequestInteractiveAuthenticator.class))
+ {
+ authenticators.add(authenticator);
+ }
+ AUTHENTICATORS = Collections.unmodifiableList(authenticators);
+ }
+
+ private HttpManagementConfiguration _managementConfiguration;
@Override
public void init(ServletConfig config) throws ServletException
{
super.init(config);
-
- String initValue =
config.getServletContext().getInitParameter(RETURN_URL_INIT_PARAM);
- if(initValue != null)
- {
- _returnUrl = initValue;
- }
+ _managementConfiguration =
HttpManagementUtil.getManagementConfiguration(config.getServletContext());
}
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse resp)
throws ServletException, IOException
{
HttpSession session = request.getSession(false);
- if(session != null)
+ if (session != null)
{
// Invalidating the session will cause LoginLogoutReporter to log
the user logoff.
session.invalidate();
}
- resp.sendRedirect(_returnUrl);
+ LogoutHandler logoutHandler = null;
+ for (HttpRequestInteractiveAuthenticator authenticator :
AUTHENTICATORS)
+ {
+ logoutHandler = authenticator.getLogoutHandler(request,
_managementConfiguration);
+ if (logoutHandler != null)
+ {
+ break;
+ }
+ }
+
+ if (logoutHandler != null)
+ {
+ logoutHandler.handleLogout(resp);
+ }
+ else
+ {
+ resp.sendRedirect(HttpManagement.DEFAULT_LOGOUT_URL);
+ }
+
}
}
Added:
qpid/java/trunk/broker-plugins/management-http/src/main/java/resources/logout.html
URL:
http://svn.apache.org/viewvc/qpid/java/trunk/broker-plugins/management-http/src/main/java/resources/logout.html?rev=1730052&view=auto
==============================================================================
---
qpid/java/trunk/broker-plugins/management-http/src/main/java/resources/logout.html
(added)
+++
qpid/java/trunk/broker-plugins/management-http/src/main/java/resources/logout.html
Fri Feb 12 16:17:32 2016
@@ -0,0 +1,92 @@
+<!DOCTYPE HTML>
+<!--
+ ~ Licensed to the Apache Software Foundation (ASF) under one or more
+ ~ contributor license agreements. See the NOTICE file distributed with
+ ~ this work for additional information regarding copyright ownership.
+ ~ The ASF licenses this file to You under the Apache License, Version 2.0
+ ~ (the "License"); you may not use this file except in compliance with
+ ~ the License. You may obtain a copy of the License at
+ ~
+ ~ http://www.apache.org/licenses/LICENSE-2.0
+ ~
+ ~ Unless required by applicable law or agreed to in writing, software
+ ~ distributed under the License is distributed on an "AS IS" BASIS,
+ ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ ~ See the License for the specific language governing permissions and
+ ~ limitations under the License.
+ -->
+<html lang="en">
+<head>
+ <meta charset="utf-8">
+ <title>Qpid Management Login</title>
+ <link rel="stylesheet" href="dojo/dojo/resources/dojo.css">
+ <link rel="stylesheet" href="dojo/dijit/themes/claro/claro.css">
+ <link rel="stylesheet" href="css/common.css" media="screen">
+ <script>
+ function getContextPath()
+ {
+ var contextPath = "/";
+ var documentURL = document.URL;
+ var managementPageStart = documentURL.lastIndexOf("/");
+ var firstSlashPos = documentURL.indexOf("/",
documentURL.indexOf("//") + 2);
+ if (managementPageStart > firstSlashPos)
+ {
+ contextPath = documentURL.substring(firstSlashPos,
managementPageStart);
+ }
+ return contextPath;
+ }
+
+ var dojoConfig = {
+ tlmSiblingOfDojo:false,
+ parseOnLoad:true,
+ async:true,
+ baseUrl: getContextPath(),
+ packages:[
+ { name:"dojo", location:"dojo/dojo" },
+ { name:"dijit", location:"dojo/dijit" },
+ { name:"dojox", location:"dojo/dojox" },
+ { name:"qpid", location:"js/qpid" }
+ ]
+ };
+
+ </script>
+ <script src="dojo/dojo/dojo.js">
+ </script>
+
+ <script>
+ require(["dijit/form/Button",
+ "dijit/layout/BorderContainer",
+ "dijit/layout/ContentPane",
+ "dijit/TitlePane",
+ "dojox/layout/TableContainer",
+ "qpid/common/footer"]);
+ </script>
+
+</head>
+<body class="claro">
+
+<div id="pageLayout" data-dojo-type="dijit.layout.BorderContainer"
data-dojo-props="design: 'headline', gutters: false">
+ <div data-dojo-type="dijit.layout.ContentPane"
data-dojo-props="region:'top'">
+ <div id="header" class="header" style="float: left; width:
300px"></div>
+ <div id="login" style="float: right"></div>
+ </div>
+ <div data-dojo-type="dijit.layout.ContentPane"
data-dojo-props="region:'center'">
+ <div style="width:350px; margin-left: auto; margin-right: auto;">
+ <div data-dojo-type="dijit.TitlePane"
data-dojo-props="title:'Logout', toggleable: false" >
+ <div class="dijitDialogPaneContentArea">
+ You have been successfully logged out.
+ </div>
+ <div class="dijitDialogPaneActionBar qpidDialogPaneActionBar">
+ <button data-dojo-type="dijit.form.Button" type="submit"
id="logoutButton" onclick="window.location = 'index.html';">Login again</button>
+ </div>
+ </div>
+ </div>
+ </div>
+
+ <div data-dojo-type="dijit.layout.ContentPane"
data-dojo-props="region:'bottom'">
+ <div qpid-type="footer"></div>
+ </div>
+</div>
+
+</body>
+</html>
\ No newline at end of file
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]