Modified: qpid/java/branches/6.0.x/broker-core/src/main/java/org/apache/qpid/server/security/auth/manager/oauth2/google/GoogleOAuth2IdentityResolverService.java URL: http://svn.apache.org/viewvc/qpid/java/branches/6.0.x/broker-core/src/main/java/org/apache/qpid/server/security/auth/manager/oauth2/google/GoogleOAuth2IdentityResolverService.java?rev=1730565&r1=1729215&r2=1730565&view=diff ============================================================================== --- qpid/java/branches/6.0.x/broker-core/src/main/java/org/apache/qpid/server/security/auth/manager/oauth2/google/GoogleOAuth2IdentityResolverService.java (original) +++ qpid/java/branches/6.0.x/broker-core/src/main/java/org/apache/qpid/server/security/auth/manager/oauth2/google/GoogleOAuth2IdentityResolverService.java Mon Feb 15 16:48:12 2016 @@ -21,27 +21,36 @@ package org.apache.qpid.server.security.auth.manager.oauth2.google; +import static org.apache.qpid.server.util.ParameterizedTypes.LIST_OF_STRINGS; + import java.io.IOException; import java.io.InputStream; +import java.net.HttpURLConnection; import java.net.URI; +import java.net.URISyntaxException; +import java.net.URL; import java.nio.charset.StandardCharsets; +import java.security.GeneralSecurityException; import java.security.Principal; +import java.util.List; import java.util.Map; -import javax.net.ssl.HttpsURLConnection; - import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.ObjectMapper; import com.google.common.collect.Sets; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import org.apache.qpid.server.configuration.IllegalConfigurationException; import org.apache.qpid.server.model.TrustStore; +import org.apache.qpid.server.plugin.PluggableService; import org.apache.qpid.server.security.auth.UsernamePrincipal; import org.apache.qpid.server.security.auth.manager.oauth2.IdentityResolverException; import org.apache.qpid.server.security.auth.manager.oauth2.OAuth2AuthenticationProvider; import org.apache.qpid.server.security.auth.manager.oauth2.OAuth2IdentityResolverService; import org.apache.qpid.server.security.auth.manager.oauth2.OAuth2Utils; +import org.apache.qpid.server.util.ConnectionBuilder; +import org.apache.qpid.server.util.ServerScopedRuntimeException; /** * An identity resolver that calls Google's userinfo endpoint https://www.googleapis.com/oauth2/v3/userinfo. @@ -53,52 +62,81 @@ import org.apache.qpid.server.security.a * * https://developers.google.com/identity/protocols/OpenIDConnect */ +@PluggableService public class GoogleOAuth2IdentityResolverService implements OAuth2IdentityResolverService { private static final Logger LOGGER = LoggerFactory.getLogger(GoogleOAuth2IdentityResolverService.class); private static final String UTF8 = StandardCharsets.UTF_8.name(); - private final OAuth2AuthenticationProvider _authenticationProvider; - private final URI _userInfoEndpoint; - private final TrustStore _trustStore; + public static final String TYPE = "GoogleUserInfo"; + private final ObjectMapper _objectMapper = new ObjectMapper(); - public GoogleOAuth2IdentityResolverService(final OAuth2AuthenticationProvider authenticationProvider) + @Override + public String getType() { - _authenticationProvider = authenticationProvider; - _userInfoEndpoint = _authenticationProvider.getIdentityResolverEndpointURI(); - _trustStore = _authenticationProvider.getTrustStore(); + return TYPE; + } - if (!Sets.newHashSet(_authenticationProvider.getScope().split("\\s")).contains("profile")) + @Override + public void validate(final OAuth2AuthenticationProvider<?> authProvider) throws IllegalConfigurationException + { + if (!Sets.newHashSet(authProvider.getScope().split("\\s")).contains("profile")) { - throw new IllegalArgumentException("This identity resolver requires that scope 'profile' is included in" + throw new IllegalConfigurationException("This identity resolver requires that scope 'profile' is included in" + " the authentication request."); } } @Override - public Principal getUserPrincipal(String accessToken) throws IOException, IdentityResolverException + public Principal getUserPrincipal(final OAuth2AuthenticationProvider<?> authenticationProvider, + String accessToken) throws IOException, IdentityResolverException { - LOGGER.debug("About to call identity service '{}'", _userInfoEndpoint); - - HttpsURLConnection connection = (HttpsURLConnection) _userInfoEndpoint.toURL().openConnection(); - if (_trustStore != null) + URL userInfoEndpoint = authenticationProvider.getIdentityResolverEndpointURI().toURL(); + TrustStore trustStore = authenticationProvider.getTrustStore(); + int connectTimeout = authenticationProvider.getContextValue(Integer.class, OAuth2AuthenticationProvider.AUTHENTICATION_OAUTH2_CONNECT_TIMEOUT); + int readTimeout = authenticationProvider.getContextValue(Integer.class, OAuth2AuthenticationProvider.AUTHENTICATION_OAUTH2_READ_TIMEOUT); + List<String> enabledTlsProtocols = + authenticationProvider.getContextValue(List.class, LIST_OF_STRINGS, OAuth2AuthenticationProvider.AUTHENTICATION_OAUTH2_ENABLED_TLS_PROTOCOLS); + List<String> disabledTlsProtocols = + authenticationProvider.getContextValue(List.class, LIST_OF_STRINGS, OAuth2AuthenticationProvider.AUTHENTICATION_OAUTH2_DISABLED_TLS_PROTOCOLS); + List<String> enabledCipherSuites = + authenticationProvider.getContextValue(List.class, LIST_OF_STRINGS, OAuth2AuthenticationProvider.AUTHENTICATION_OAUTH2_ENABLED_CIPHER_SUITES); + List<String> disabledCipherSuites = + authenticationProvider.getContextValue(List.class, LIST_OF_STRINGS, OAuth2AuthenticationProvider.AUTHENTICATION_OAUTH2_DISABLED_CIPHER_SUITES); + + ConnectionBuilder connectionBuilder = new ConnectionBuilder(userInfoEndpoint); + connectionBuilder.setConnectTimeout(connectTimeout).setReadTimeout(readTimeout); + if (trustStore != null) { - OAuth2Utils.setTrustedCertificates(connection, _trustStore); + try + { + connectionBuilder.setTrustMangers(trustStore.getTrustManagers()); + } + catch (GeneralSecurityException e) + { + throw new ServerScopedRuntimeException("Cannot initialise TLS", e); + } } + connectionBuilder.setEnabledTlsProtocols(enabledTlsProtocols) + .setDisabledTlsProtocols(disabledTlsProtocols) + .setEnabledCipherSuites(enabledCipherSuites) + .setDisabledCipherSuites(disabledCipherSuites); + + LOGGER.debug("About to call identity service '{}'", userInfoEndpoint); + HttpURLConnection connection = connectionBuilder.build(); connection.setRequestProperty("Accept-Charset", UTF8); - connection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded;charset=" + UTF8); connection.setRequestProperty("Accept", "application/json"); connection.setRequestProperty("Authorization", "Bearer " + accessToken); connection.connect(); - try (InputStream input = connection.getInputStream()) + try (InputStream input = OAuth2Utils.getResponseStream(connection)) { int responseCode = connection.getResponseCode(); LOGGER.debug("Call to identity service '{}' complete, response code : {}", - _userInfoEndpoint, responseCode); + userInfoEndpoint, responseCode); Map<String, String> responseMap; try @@ -108,13 +146,13 @@ public class GoogleOAuth2IdentityResolve catch (JsonProcessingException e) { throw new IOException(String.format("Identity resolver '%s' did not return json", - _userInfoEndpoint), e); + userInfoEndpoint), e); } if (responseCode != 200) { throw new IdentityResolverException(String.format( "Identity resolver '%s' failed, response code %d", - _userInfoEndpoint, responseCode)); + userInfoEndpoint, responseCode)); } final String googleId = responseMap.get("sub"); @@ -122,9 +160,54 @@ public class GoogleOAuth2IdentityResolve { throw new IdentityResolverException(String.format( "Identity resolver '%s' failed, response did not include 'sub'", - _userInfoEndpoint)); + userInfoEndpoint)); } return new UsernamePrincipal(googleId); } } + + @Override + public URI getDefaultAuthorizationEndpointURI(final OAuth2AuthenticationProvider<?> oAuth2AuthenticationProvider) + { + try + { + return new URI("https://accounts.google.com/o/oauth2/v2/auth"); + } + catch (URISyntaxException e) + { + return null; + } + } + + @Override + public URI getDefaultTokenEndpointURI(final OAuth2AuthenticationProvider<?> oAuth2AuthenticationProvider) + { + try + { + return new URI("https://www.googleapis.com/oauth2/v4/token"); + } + catch (URISyntaxException e) + { + return null; + } + } + + @Override + public URI getDefaultIdentityResolverEndpointURI(final OAuth2AuthenticationProvider<?> oAuth2AuthenticationProvider) + { + try + { + return new URI("https://www.googleapis.com/oauth2/v3/userinfo"); + } + catch (URISyntaxException e) + { + return null; + } + } + + @Override + public String getDefaultScope(final OAuth2AuthenticationProvider<?> oAuth2AuthenticationProvider) + { + return "profile"; + } }
Modified: qpid/java/branches/6.0.x/broker-core/src/main/java/org/apache/qpid/server/security/auth/manager/oauth2/google/package-info.java URL: http://svn.apache.org/viewvc/qpid/java/branches/6.0.x/broker-core/src/main/java/org/apache/qpid/server/security/auth/manager/oauth2/google/package-info.java?rev=1730565&r1=1729215&r2=1730565&view=diff ============================================================================== --- qpid/java/branches/6.0.x/broker-core/src/main/java/org/apache/qpid/server/security/auth/manager/oauth2/google/package-info.java (original) +++ qpid/java/branches/6.0.x/broker-core/src/main/java/org/apache/qpid/server/security/auth/manager/oauth2/google/package-info.java Mon Feb 15 16:48:12 2016 @@ -30,7 +30,7 @@ * "authorizationEndpointURI" : "https://accounts.google.com/o/oauth2/v2/auth", * "tokenEndpointURI" : "https://www.googleapis.com/oauth2/v4/token", * "tokenEndpointNeedsAuth" : false, - * "identityResolverFactoryType" : "GoogleUserInfo", + * "identityResolverType" : "GoogleUserInfo", * "identityResolverEndpointURI" : "https://www.googleapis.com/oauth2/v3/userinfo", * "clientId" : "......", * "clientSecret" : "....", Modified: qpid/java/branches/6.0.x/broker-core/src/main/java/org/apache/qpid/server/security/auth/manager/oauth2/microsoftlive/MicrosoftLiveOAuth2IdentityResolverService.java URL: http://svn.apache.org/viewvc/qpid/java/branches/6.0.x/broker-core/src/main/java/org/apache/qpid/server/security/auth/manager/oauth2/microsoftlive/MicrosoftLiveOAuth2IdentityResolverService.java?rev=1730565&r1=1729515&r2=1730565&view=diff ============================================================================== --- qpid/java/branches/6.0.x/broker-core/src/main/java/org/apache/qpid/server/security/auth/manager/oauth2/microsoftlive/MicrosoftLiveOAuth2IdentityResolverService.java (original) +++ qpid/java/branches/6.0.x/broker-core/src/main/java/org/apache/qpid/server/security/auth/manager/oauth2/microsoftlive/MicrosoftLiveOAuth2IdentityResolverService.java Mon Feb 15 16:48:12 2016 @@ -21,19 +21,22 @@ package org.apache.qpid.server.security.auth.manager.oauth2.microsoftlive; +import static org.apache.qpid.server.util.ParameterizedTypes.LIST_OF_STRINGS; + import java.io.IOException; import java.io.InputStream; +import java.net.HttpURLConnection; import java.net.URI; import java.net.URISyntaxException; +import java.net.URL; import java.nio.charset.StandardCharsets; +import java.security.GeneralSecurityException; import java.security.Principal; +import java.util.List; import java.util.Map; -import javax.net.ssl.HttpsURLConnection; - import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.ObjectMapper; -import com.google.common.collect.Sets; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -45,6 +48,8 @@ import org.apache.qpid.server.security.a import org.apache.qpid.server.security.auth.manager.oauth2.OAuth2AuthenticationProvider; import org.apache.qpid.server.security.auth.manager.oauth2.OAuth2IdentityResolverService; import org.apache.qpid.server.security.auth.manager.oauth2.OAuth2Utils; +import org.apache.qpid.server.util.ConnectionBuilder; +import org.apache.qpid.server.util.ServerScopedRuntimeException; /** * An identity resolver that calls Microsoft Live's REST API. @@ -75,21 +80,39 @@ public class MicrosoftLiveOAuth2Identity public Principal getUserPrincipal(final OAuth2AuthenticationProvider<?> authenticationProvider, String accessToken) throws IOException, IdentityResolverException { - URI userInfoEndpoint = authenticationProvider.getIdentityResolverEndpointURI(); + URL userInfoEndpoint = authenticationProvider.getIdentityResolverEndpointURI().toURL(); TrustStore trustStore = authenticationProvider.getTrustStore(); int connectTimeout = authenticationProvider.getContextValue(Integer.class, OAuth2AuthenticationProvider.AUTHENTICATION_OAUTH2_CONNECT_TIMEOUT); int readTimeout = authenticationProvider.getContextValue(Integer.class, OAuth2AuthenticationProvider.AUTHENTICATION_OAUTH2_READ_TIMEOUT); + List<String> enabledTlsProtocols = + authenticationProvider.getContextValue(List.class, LIST_OF_STRINGS, OAuth2AuthenticationProvider.AUTHENTICATION_OAUTH2_ENABLED_TLS_PROTOCOLS); + List<String> disabledTlsProtocols = + authenticationProvider.getContextValue(List.class, LIST_OF_STRINGS, OAuth2AuthenticationProvider.AUTHENTICATION_OAUTH2_DISABLED_TLS_PROTOCOLS); + List<String> enabledCipherSuites = + authenticationProvider.getContextValue(List.class, LIST_OF_STRINGS, OAuth2AuthenticationProvider.AUTHENTICATION_OAUTH2_ENABLED_CIPHER_SUITES); + List<String> disabledCipherSuites = + authenticationProvider.getContextValue(List.class, LIST_OF_STRINGS, OAuth2AuthenticationProvider.AUTHENTICATION_OAUTH2_DISABLED_CIPHER_SUITES); - LOGGER.debug("About to call identity service '{}'", userInfoEndpoint); - - HttpsURLConnection connection = (HttpsURLConnection) userInfoEndpoint.toURL().openConnection(); - connection.setConnectTimeout(connectTimeout); - connection.setReadTimeout(readTimeout); - + ConnectionBuilder connectionBuilder = new ConnectionBuilder(userInfoEndpoint); + connectionBuilder.setConnectTimeout(connectTimeout).setReadTimeout(readTimeout); if (trustStore != null) { - OAuth2Utils.setTrustedCertificates(connection, trustStore); + try + { + connectionBuilder.setTrustMangers(trustStore.getTrustManagers()); + } + catch (GeneralSecurityException e) + { + throw new ServerScopedRuntimeException("Cannot initialise TLS", e); + } } + connectionBuilder.setEnabledTlsProtocols(enabledTlsProtocols) + .setDisabledTlsProtocols(disabledTlsProtocols) + .setEnabledCipherSuites(enabledCipherSuites) + .setDisabledCipherSuites(disabledCipherSuites); + + LOGGER.debug("About to call identity service '{}'", userInfoEndpoint); + HttpURLConnection connection = connectionBuilder.build(); connection.setRequestProperty("Accept-Charset", UTF8); connection.setRequestProperty("Accept", "application/json"); Modified: qpid/java/branches/6.0.x/broker-core/src/main/java/org/apache/qpid/server/security/group/GroupProviderImpl.java URL: http://svn.apache.org/viewvc/qpid/java/branches/6.0.x/broker-core/src/main/java/org/apache/qpid/server/security/group/GroupProviderImpl.java?rev=1730565&r1=1730564&r2=1730565&view=diff ============================================================================== --- qpid/java/branches/6.0.x/broker-core/src/main/java/org/apache/qpid/server/security/group/GroupProviderImpl.java (original) +++ qpid/java/branches/6.0.x/broker-core/src/main/java/org/apache/qpid/server/security/group/GroupProviderImpl.java Mon Feb 15 16:48:12 2016 @@ -56,7 +56,7 @@ public class GroupProviderImpl extends A @Override - public Set<Principal> getGroupPrincipalsForUser(final String username) + public Set<Principal> getGroupPrincipalsForUser(final Principal userPrincipal) { Set<Principal> principals = new HashSet<>(); @@ -65,7 +65,7 @@ public class GroupProviderImpl extends A { for(GroupMember<?> member : group.getChildren(GroupMember.class)) { - if(member.getPrincipal().getName().equals(username)) + if(member.getPrincipal().getName().equals(userPrincipal.getName())) { principals.add(group.getGroupPrincipal()); } Modified: qpid/java/branches/6.0.x/broker-core/src/test/java/org/apache/qpid/server/security/SubjectCreatorTest.java URL: http://svn.apache.org/viewvc/qpid/java/branches/6.0.x/broker-core/src/test/java/org/apache/qpid/server/security/SubjectCreatorTest.java?rev=1730565&r1=1730564&r2=1730565&view=diff ============================================================================== --- qpid/java/branches/6.0.x/broker-core/src/test/java/org/apache/qpid/server/security/SubjectCreatorTest.java (original) +++ qpid/java/branches/6.0.x/broker-core/src/test/java/org/apache/qpid/server/security/SubjectCreatorTest.java Mon Feb 15 16:48:12 2016 @@ -36,11 +36,12 @@ import org.apache.qpid.server.security.a import org.apache.qpid.server.security.auth.AuthenticationResult; import org.apache.qpid.server.security.auth.AuthenticationResult.AuthenticationStatus; import org.apache.qpid.server.security.auth.SubjectAuthenticationResult; +import org.apache.qpid.server.security.auth.UsernamePrincipal; import org.apache.qpid.test.utils.QpidTestCase; public class SubjectCreatorTest extends QpidTestCase { - private static final String USERNAME = "username"; + private static final UsernamePrincipal USERNAME_PRINCIPAL = new UsernamePrincipal("username"); private static final String PASSWORD = "password"; private AuthenticationProvider<?> _authenticationProvider = mock(AuthenticationProvider.class); @@ -48,7 +49,6 @@ public class SubjectCreatorTest extends private GroupProvider<?> _groupManager1 = mock(GroupProvider.class); private GroupProvider<?> _groupManager2 = mock(GroupProvider.class); - private Principal _userPrincipal = mock(Principal.class); private Principal _group1 = mock(Principal.class); private Principal _group2 = mock(Principal.class); @@ -60,26 +60,26 @@ public class SubjectCreatorTest extends @Override public void setUp() { - when(_groupManager1.getGroupPrincipalsForUser(USERNAME)).thenReturn(Collections.singleton(_group1)); - when(_groupManager2.getGroupPrincipalsForUser(USERNAME)).thenReturn(Collections.singleton(_group2)); + when(_groupManager1.getGroupPrincipalsForUser(USERNAME_PRINCIPAL)).thenReturn(Collections.singleton(_group1)); + when(_groupManager2.getGroupPrincipalsForUser(USERNAME_PRINCIPAL)).thenReturn(Collections.singleton(_group2)); _subjectCreator = new SubjectCreator(_authenticationProvider, new HashSet<GroupProvider<?>>(Arrays.asList(_groupManager1, _groupManager2)), false); - _authenticationResult = new AuthenticationResult(_userPrincipal); + _authenticationResult = new AuthenticationResult(USERNAME_PRINCIPAL); } public void testSaslAuthenticationSuccessReturnsSubjectWithUserAndGroupPrincipals() throws Exception { when(_authenticationProvider.authenticate(_testSaslServer, _saslResponseBytes)).thenReturn(_authenticationResult); when(_testSaslServer.isComplete()).thenReturn(true); - when(_testSaslServer.getAuthorizationID()).thenReturn(USERNAME); + when(_testSaslServer.getAuthorizationID()).thenReturn(USERNAME_PRINCIPAL.getName()); SubjectAuthenticationResult result = _subjectCreator.authenticate(_testSaslServer, _saslResponseBytes); final Subject actualSubject = result.getSubject(); assertEquals("Should contain one user principal and two groups ", 3, actualSubject.getPrincipals().size()); - assertTrue(actualSubject.getPrincipals().contains(new AuthenticatedPrincipal(_userPrincipal))); + assertTrue(actualSubject.getPrincipals().contains(new AuthenticatedPrincipal(USERNAME_PRINCIPAL))); assertTrue(actualSubject.getPrincipals().contains(_group1)); assertTrue(actualSubject.getPrincipals().contains(_group2)); @@ -113,21 +113,21 @@ public class SubjectCreatorTest extends public void testGetGroupPrincipalsWhenAGroupManagerReturnsNull() { - when(_groupManager1.getGroupPrincipalsForUser(USERNAME)).thenReturn(null); + when(_groupManager1.getGroupPrincipalsForUser(USERNAME_PRINCIPAL)).thenReturn(null); getAndAssertGroupPrincipals(_group2); } public void testGetGroupPrincipalsWhenAGroupManagerReturnsEmptySet() { - when(_groupManager2.getGroupPrincipalsForUser(USERNAME)).thenReturn(new HashSet<Principal>()); + when(_groupManager2.getGroupPrincipalsForUser(USERNAME_PRINCIPAL)).thenReturn(new HashSet<Principal>()); getAndAssertGroupPrincipals(_group1); } private void getAndAssertGroupPrincipals(Principal... expectedGroups) { - Set<Principal> actualGroupPrincipals = _subjectCreator.getGroupPrincipals(USERNAME); + Set<Principal> actualGroupPrincipals = _subjectCreator.getGroupPrincipals(USERNAME_PRINCIPAL); Set<Principal> expectedGroupPrincipals = new HashSet<Principal>(Arrays.asList(expectedGroups)); assertEquals(expectedGroupPrincipals, actualGroupPrincipals); } Modified: qpid/java/branches/6.0.x/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/HttpManagement.java URL: http://svn.apache.org/viewvc/qpid/java/branches/6.0.x/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/HttpManagement.java?rev=1730565&r1=1730564&r2=1730565&view=diff ============================================================================== --- qpid/java/branches/6.0.x/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/HttpManagement.java (original) +++ qpid/java/branches/6.0.x/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/HttpManagement.java Mon Feb 15 16:48:12 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; @@ -107,6 +108,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_"; @@ -256,7 +259,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)); @@ -279,7 +281,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/branches/6.0.x/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/HttpManagementUtil.java URL: http://svn.apache.org/viewvc/qpid/java/branches/6.0.x/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/HttpManagementUtil.java?rev=1730565&r1=1730564&r2=1730565&view=diff ============================================================================== --- qpid/java/branches/6.0.x/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/HttpManagementUtil.java (original) +++ qpid/java/branches/6.0.x/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/HttpManagementUtil.java Mon Feb 15 16:48:12 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/branches/6.0.x/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/HttpRequestInteractiveAuthenticator.java URL: http://svn.apache.org/viewvc/qpid/java/branches/6.0.x/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/HttpRequestInteractiveAuthenticator.java?rev=1730565&r1=1730564&r2=1730565&view=diff ============================================================================== --- qpid/java/branches/6.0.x/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/HttpRequestInteractiveAuthenticator.java (original) +++ qpid/java/branches/6.0.x/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/HttpRequestInteractiveAuthenticator.java Mon Feb 15 16:48:12 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/branches/6.0.x/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/auth/AnonymousPreemptiveAuthenticator.java URL: http://svn.apache.org/viewvc/qpid/java/branches/6.0.x/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/auth/AnonymousPreemptiveAuthenticator.java?rev=1730565&r1=1730564&r2=1730565&view=diff ============================================================================== --- qpid/java/branches/6.0.x/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/auth/AnonymousPreemptiveAuthenticator.java (original) +++ qpid/java/branches/6.0.x/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/auth/AnonymousPreemptiveAuthenticator.java Mon Feb 15 16:48:12 2016 @@ -44,8 +44,7 @@ public class AnonymousPreemptiveAuthenti SubjectCreator subjectCreator = authenticationProvider.getSubjectCreator(request.isSecure()); if(authenticationProvider instanceof AnonymousAuthenticationManager) { - return subjectCreator.createResultWithGroups(AnonymousAuthenticationManager.ANONYMOUS_USERNAME, - AnonymousAuthenticationManager.ANONYMOUS_AUTHENTICATION).getSubject(); + return subjectCreator.createResultWithGroups(AnonymousAuthenticationManager.ANONYMOUS_AUTHENTICATION).getSubject(); } return null; Modified: qpid/java/branches/6.0.x/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/auth/BasicAuthPreemptiveAuthenticator.java URL: http://svn.apache.org/viewvc/qpid/java/branches/6.0.x/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/auth/BasicAuthPreemptiveAuthenticator.java?rev=1730565&r1=1730564&r2=1730565&view=diff ============================================================================== --- qpid/java/branches/6.0.x/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/auth/BasicAuthPreemptiveAuthenticator.java (original) +++ qpid/java/branches/6.0.x/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/auth/BasicAuthPreemptiveAuthenticator.java Mon Feb 15 16:48:12 2016 @@ -29,7 +29,6 @@ import javax.xml.bind.DatatypeConverter; import org.apache.qpid.server.management.plugin.HttpManagementConfiguration; import org.apache.qpid.server.management.plugin.HttpRequestPreemptiveAuthenticator; import org.apache.qpid.server.model.AuthenticationProvider; -import org.apache.qpid.server.model.port.HttpPort; import org.apache.qpid.server.plugin.PluggableService; import org.apache.qpid.server.security.SubjectCreator; import org.apache.qpid.server.security.auth.AuthenticationResult; @@ -75,8 +74,7 @@ public class BasicAuthPreemptiveAuthenti String username = credentials[0]; String password = credentials[1]; AuthenticationResult authenticationResult = namePasswdAuthProvider.authenticate(username, password); - SubjectAuthenticationResult result = subjectCreator.createResultWithGroups(username, - authenticationResult); + SubjectAuthenticationResult result = subjectCreator.createResultWithGroups(authenticationResult); return result.getSubject(); Copied: qpid/java/branches/6.0.x/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/auth/OAuth2InteractiveAuthenticator.java (from r1729215, 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/branches/6.0.x/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/auth/OAuth2InteractiveAuthenticator.java?p2=qpid/java/branches/6.0.x/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/auth/OAuth2InteractiveAuthenticator.java&p1=qpid/java/trunk/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/auth/OAuth2InteractiveAuthenticator.java&r1=1729215&r2=1730565&rev=1730565&view=diff ============================================================================== --- qpid/java/trunk/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/auth/OAuth2InteractiveAuthenticator.java (original) +++ qpid/java/branches/6.0.x/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/auth/OAuth2InteractiveAuthenticator.java Mon Feb 15 16:48:12 2016 @@ -20,7 +20,11 @@ package org.apache.qpid.server.management.plugin.auth; import java.io.IOException; +import java.net.URI; +import java.net.URISyntaxException; +import java.security.AccessControlException; import java.security.SecureRandom; +import java.util.Collections; import java.util.Enumeration; import java.util.HashMap; import java.util.Map; @@ -53,6 +57,25 @@ public class OAuth2InteractiveAuthentica private static final int STATE_NONCE_BIT_SIZE = 256; private static final String STATE_NAME = "stateNonce"; private static final String TYPE = "OAuth2"; + private static final String ORIGINAL_REQUEST_URI_SESSION_ATTRIBUTE = "originalRequestURI"; + private static final String REDIRECT_URI_SESSION_ATTRIBUTE = "redirectURI"; + + /** Authentication Endpoint error responses https://tools.ietf.org/html/rfc6749#section-4.2.2.1 */ + private static final Map<String, Integer> ERROR_RESPONSES; + + static + { + // Authentication Endpoint + Map<String, Integer> errorResponses = new HashMap<>(); + errorResponses.put("invalid_request", 400); + errorResponses.put("unauthorized_client", 400); + errorResponses.put("unsupported_response_type", 400); + errorResponses.put("invalid_scope", 400); + errorResponses.put("access_denied", 403); + errorResponses.put("server_error", 500); + errorResponses.put("temporarily_unavailable", 503); + ERROR_RESPONSES = Collections.unmodifiableMap(errorResponses); + } private SecureRandom _random = new SecureRandom(); @@ -80,6 +103,25 @@ public class OAuth2InteractiveAuthentica return new FailedAuthenticationHandler(400, "Some request parameters are included more than once " + request, e); } + String error = requestParameters.get("error"); + if (error != null) + { + int responseCode = decodeErrorAsResponseCode(error); + String errorDescription = requestParameters.get("error_description"); + if (responseCode == 403) + { + LOGGER.debug("Resource owner denies the access request"); + return new FailedAuthenticationHandler(responseCode, "Resource owner denies the access request"); + + } + else + { + LOGGER.warn("Authorization endpoint failed, error : '{}', error description '{}'", + error, errorDescription); + return new FailedAuthenticationHandler(responseCode, String.format("Authorization request failed :'%s'", error)); + } + } + final String authorizationCode = requestParameters.get("code"); if (authorizationCode == null) { @@ -102,7 +144,7 @@ public class OAuth2InteractiveAuthentica if (state == null) { LOGGER.warn("Deny login attempt with wrong state: {}", state); - return new FailedAuthenticationHandler(400, "no state set on request with authorization code grant: " + return new FailedAuthenticationHandler(400, "No state set on request with authorization code grant: " + request); } if (!checkState(httpSession, state)) @@ -110,26 +152,34 @@ public class OAuth2InteractiveAuthentica LOGGER.warn("Deny login attempt with wrong state: {}", state); return new FailedAuthenticationHandler(401, "Received request with wrong state: " + state); } - final String redirectUri = (String) httpSession.getAttribute("redirectUri"); + final String redirectUri = (String) httpSession.getAttribute(REDIRECT_URI_SESSION_ATTRIBUTE); + final String originalRequestUri = (String) httpSession.getAttribute(ORIGINAL_REQUEST_URI_SESSION_ATTRIBUTE); return new AuthenticationHandler() { @Override public void handleAuthentication(final HttpServletResponse response) throws IOException { AuthenticationResult authenticationResult = oauth2Provider.authenticateViaAuthorizationCode(authorizationCode, redirectUri); - createSubject(authenticationResult); + try + { + Subject subject = createSubject(authenticationResult); + authoriseManagement(subject); + HttpManagementUtil.saveAuthorisedSubject(httpSession, subject); - LOGGER.debug("Successful login. Redirect to original resource {}", redirectUri); - response.sendRedirect(redirectUri); + LOGGER.debug("Successful login. Redirect to original resource {}", originalRequestUri); + response.sendRedirect(originalRequestUri); + } + catch (AccessControlException e) + { + LOGGER.info("User '{}' is not authorised for management", authenticationResult.getMainPrincipal()); + response.sendError(403, "User is not authorised for management"); + } } - private void createSubject(final AuthenticationResult authenticationResult) + private Subject createSubject(final AuthenticationResult authenticationResult) { - String username = authenticationResult.getMainPrincipal().getName(); - SubjectCreator subjectCreator = oauth2Provider.getSubjectCreator(request.isSecure()); - SubjectAuthenticationResult - result = subjectCreator.createResultWithGroups(username, authenticationResult); + SubjectAuthenticationResult result = subjectCreator.createResultWithGroups(authenticationResult); Subject subject = result.getSubject(); @@ -145,11 +195,13 @@ public class OAuth2InteractiveAuthentica original.getPrivateCredentials()); subject.getPrincipals().add(new ServletConnectionPrincipal(request)); subject.setReadOnly(); + return subject; + } + private void authoriseManagement(final Subject subject) + { Broker broker = (Broker) oauth2Provider.getParent(Broker.class); HttpManagementUtil.assertManagementAccess(broker.getSecurityManager(), subject); - - HttpManagementUtil.saveAuthorisedSubject(httpSession, subject); } }; } @@ -160,13 +212,40 @@ 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); + + if (oauth2Provider.getPostLogoutURI() != null) + { + final String postLogoutRedirect = oauth2Provider.getPostLogoutURI().toString(); + return new LogoutHandler() + { + @Override + public void handleLogout(final HttpServletResponse response) throws IOException + { + response.sendRedirect(postLogoutRedirect); + } + }; + } + } + return null; + } + private String buildAuthorizationRedirectURL(final HttpServletRequest request, final OAuth2AuthenticationProvider oauth2Provider) { final String redirectUri = getRedirectUri(request); + final String originalRequestUri = getOriginalRequestUri(request); final String authorizationEndpoint = oauth2Provider.getAuthorizationEndpointURI().toString(); final HttpSession httpSession = request.getSession(); - httpSession.setAttribute("redirectUri", redirectUri); + httpSession.setAttribute(REDIRECT_URI_SESSION_ATTRIBUTE, redirectUri); + httpSession.setAttribute(ORIGINAL_REQUEST_URI_SESSION_ATTRIBUTE, originalRequestUri); Map<String, String> queryArgs = new HashMap<>(); queryArgs.put("client_id", oauth2Provider.getClientId()); @@ -178,14 +257,32 @@ public class OAuth2InteractiveAuthentica queryArgs.put("scope", oauth2Provider.getScope()); } - // TODO: currently we assume, but don't check, that the authorizationEndpointURI does not contain a query string StringBuilder urlBuilder = new StringBuilder(authorizationEndpoint); - urlBuilder.append("?"); + String query = oauth2Provider.getAuthorizationEndpointURI().getQuery(); + if (query == null) + { + urlBuilder.append("?"); + } + else if (query.length() > 0) + { + urlBuilder.append("&"); + } urlBuilder.append(OAuth2Utils.buildRequestQuery(queryArgs)); return urlBuilder.toString(); } + private String getOriginalRequestUri(final HttpServletRequest request) + { + StringBuffer originalRequestURL = request.getRequestURL(); + final String queryString = request.getQueryString(); + if (queryString != null) + { + originalRequestURL.append("?").append(queryString); + } + return originalRequestURL.toString(); + } + private Map<String, String> getRequestParameters(final HttpServletRequest request) { Map<String, String> requestParameters = new HashMap<>(); @@ -211,13 +308,26 @@ public class OAuth2InteractiveAuthentica private String getRedirectUri(final HttpServletRequest request) { - StringBuffer redirectUri = request.getRequestURL(); - final String queryString = request.getQueryString(); - if (queryString != null) + String servletPath = request.getServletPath() != null ? request.getServletPath() : ""; + String pathInfo = request.getPathInfo() != null ? request.getPathInfo() : ""; + final String requestURL = request.getRequestURL().toString(); + try + { + URI redirectURI = new URI(requestURL); + String redirectString = redirectURI.normalize().toString(); + if (!redirectString.endsWith(servletPath + pathInfo)) + { + throw new IllegalStateException(String.format("RequestURL has unexpected format '%s'", redirectString)); + } + redirectString = redirectString.substring(0, redirectString.length() - (servletPath.length() + pathInfo.length())); + + return redirectString; + } + catch (URISyntaxException e) { - redirectUri.append(queryString); + throw new IllegalStateException(String.format("RequestURL has unexpected format '%s'", + requestURL), e); } - return redirectUri.toString(); } private String createState(HttpSession session) @@ -237,6 +347,11 @@ public class OAuth2InteractiveAuthentica return state != null && state.equals(nonce); } + private int decodeErrorAsResponseCode(final String error) + { + return ERROR_RESPONSES.containsKey(error) ? ERROR_RESPONSES.get(error) : 500; + } + class FailedAuthenticationHandler implements AuthenticationHandler { private final int _errorCode; Copied: qpid/java/branches/6.0.x/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/auth/OAuth2PreemptiveAuthenticator.java (from r1729215, qpid/java/trunk/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/auth/OAuth2PreemptiveAuthenticator.java) URL: http://svn.apache.org/viewvc/qpid/java/branches/6.0.x/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/auth/OAuth2PreemptiveAuthenticator.java?p2=qpid/java/branches/6.0.x/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/auth/OAuth2PreemptiveAuthenticator.java&p1=qpid/java/trunk/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/auth/OAuth2PreemptiveAuthenticator.java&r1=1729215&r2=1730565&rev=1730565&view=diff ============================================================================== --- qpid/java/trunk/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/auth/OAuth2PreemptiveAuthenticator.java (original) +++ qpid/java/branches/6.0.x/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/auth/OAuth2PreemptiveAuthenticator.java Mon Feb 15 16:48:12 2016 @@ -61,15 +61,9 @@ public class OAuth2PreemptiveAuthenticat { OAuth2AuthenticationProvider<?> oAuth2AuthProvider = (OAuth2AuthenticationProvider<?>) authenticationProvider; AuthenticationResult authenticationResult = oAuth2AuthProvider.authenticateViaAccessToken(accessToken); - Principal mainPrincipal = authenticationResult.getMainPrincipal(); - if (mainPrincipal == null) - { - LOGGER.debug("Preemptive OAuth2 authentication failed", authenticationResult.getCause()); - return null; - } SubjectCreator subjectCreator = authenticationProvider.getSubjectCreator(request.isSecure()); - SubjectAuthenticationResult result = subjectCreator.createResultWithGroups(mainPrincipal.getName(), authenticationResult); + SubjectAuthenticationResult result = subjectCreator.createResultWithGroups(authenticationResult); return result.getSubject(); } Modified: qpid/java/branches/6.0.x/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/auth/UsernamePasswordInteractiveLogin.java URL: http://svn.apache.org/viewvc/qpid/java/branches/6.0.x/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/auth/UsernamePasswordInteractiveLogin.java?rev=1730565&r1=1730564&r2=1730565&view=diff ============================================================================== --- qpid/java/branches/6.0.x/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/auth/UsernamePasswordInteractiveLogin.java (original) +++ qpid/java/branches/6.0.x/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/auth/UsernamePasswordInteractiveLogin.java Mon Feb 15 16:48:12 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 web fragments, move login.html (and logout.html) + // to WEB-INF/ and dispatch (forward) to them, rather than using a client side redirect. + // This would keep the login/logout pages private and inaccessible to the user 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/branches/6.0.x/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/branches/6.0.x/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/servlet/rest/LogoutServlet.java?rev=1730565&r1=1730564&r2=1730565&view=diff ============================================================================== --- qpid/java/branches/6.0.x/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/servlet/rest/LogoutServlet.java (original) +++ qpid/java/branches/6.0.x/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/servlet/rest/LogoutServlet.java Mon Feb 15 16:48:12 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); + } + } } Modified: qpid/java/branches/6.0.x/broker-plugins/management-http/src/main/java/resources/index.html URL: http://svn.apache.org/viewvc/qpid/java/branches/6.0.x/broker-plugins/management-http/src/main/java/resources/index.html?rev=1730565&r1=1730564&r2=1730565&view=diff ============================================================================== --- qpid/java/branches/6.0.x/broker-plugins/management-http/src/main/java/resources/index.html (original) +++ qpid/java/branches/6.0.x/broker-plugins/management-http/src/main/java/resources/index.html Mon Feb 15 16:48:12 2016 @@ -141,7 +141,7 @@ </div> <div class="dijitDialogPaneActionBar qpidDialogPaneActionBar"> <input type="button" id="errorDialog.button.cancel" value="Cancel" label="Cancel" dojoType="dijit.form.Button" onClick="dijit.byId('errorDialog').hide();"/> - <input type="button" id="errorDialog.button.relogin" value="Login" label="Login" dojoType="dijit.form.Button" onClick="dijit.byId('errorDialog').hide(); window.location='logout';"/> + <input type="button" id="errorDialog.button.relogin" value="Login" label="Login" dojoType="dijit.form.Button" onClick="dijit.byId('errorDialog').hide(); window.location='/';"/> </div> </div> </div> Modified: qpid/java/branches/6.0.x/client/src/main/java/org/apache/qpid/client/security/CallbackHandlerRegistry.properties URL: http://svn.apache.org/viewvc/qpid/java/branches/6.0.x/client/src/main/java/org/apache/qpid/client/security/CallbackHandlerRegistry.properties?rev=1730565&r1=1730564&r2=1730565&view=diff ============================================================================== --- qpid/java/branches/6.0.x/client/src/main/java/org/apache/qpid/client/security/CallbackHandlerRegistry.properties (original) +++ qpid/java/branches/6.0.x/client/src/main/java/org/apache/qpid/client/security/CallbackHandlerRegistry.properties Mon Feb 15 16:48:12 2016 @@ -33,4 +33,5 @@ CRAM-MD5.6=org.apache.qpid.client.securi PLAIN.7=org.apache.qpid.client.security.UsernamePasswordCallbackHandler AMQPLAIN.8=org.apache.qpid.client.security.UsernamePasswordCallbackHandler ANONYMOUS.9=org.apache.qpid.client.security.UsernamePasswordCallbackHandler +XOAUTH2.10=org.apache.qpid.client.security.oauth2.OAuth2AccessTokenCallbackHandler Modified: qpid/java/branches/6.0.x/client/src/main/java/org/apache/qpid/client/security/DynamicSaslRegistrar.properties URL: http://svn.apache.org/viewvc/qpid/java/branches/6.0.x/client/src/main/java/org/apache/qpid/client/security/DynamicSaslRegistrar.properties?rev=1730565&r1=1730564&r2=1730565&view=diff ============================================================================== --- qpid/java/branches/6.0.x/client/src/main/java/org/apache/qpid/client/security/DynamicSaslRegistrar.properties (original) +++ qpid/java/branches/6.0.x/client/src/main/java/org/apache/qpid/client/security/DynamicSaslRegistrar.properties Mon Feb 15 16:48:12 2016 @@ -21,3 +21,4 @@ CRAM-MD5-HASHED=org.apache.qpid.client.s ANONYMOUS=org.apache.qpid.client.security.anonymous.AnonymousSaslClientFactory SCRAM-SHA-1=org.apache.qpid.client.security.scram.ScramSHA1SaslClientFactory SCRAM-SHA-256=org.apache.qpid.client.security.scram.ScramSHA256SaslClientFactory +XOAUTH2=org.apache.qpid.client.security.oauth2.OAuth2SaslClientFactory Modified: qpid/java/branches/6.0.x/common/src/main/java/org/apache/qpid/transport/network/security/ssl/SSLUtil.java URL: http://svn.apache.org/viewvc/qpid/java/branches/6.0.x/common/src/main/java/org/apache/qpid/transport/network/security/ssl/SSLUtil.java?rev=1730565&r1=1730564&r2=1730565&view=diff ============================================================================== --- qpid/java/branches/6.0.x/common/src/main/java/org/apache/qpid/transport/network/security/ssl/SSLUtil.java (original) +++ qpid/java/branches/6.0.x/common/src/main/java/org/apache/qpid/transport/network/security/ssl/SSLUtil.java Mon Feb 15 16:48:12 2016 @@ -562,25 +562,40 @@ public class SSLUtil // version overloaded on SSLSocket is needed for RMI public static void updateEnabledCipherSuites(final SSLSocket socket, - final Collection<String> enabledCipherSuites, - final Collection<String> disabledCipherSuites) + final List<String> enabledCipherSuites, + final List<String> disabledCipherSuites) { - if(enabledCipherSuites != null && !enabledCipherSuites.isEmpty()) + if (enabledCipherSuites != null && !enabledCipherSuites.isEmpty()) { - final Set<String> supportedSuites = - new HashSet<>(Arrays.asList(socket.getSupportedCipherSuites())); + List<String> supportedSuites = Arrays.asList(socket.getSupportedCipherSuites()); supportedSuites.retainAll(enabledCipherSuites); socket.setEnabledCipherSuites(supportedSuites.toArray(new String[supportedSuites.size()])); } - if(disabledCipherSuites != null && !disabledCipherSuites.isEmpty()) + if (disabledCipherSuites != null && !disabledCipherSuites.isEmpty()) { - final Set<String> enabledSuites = new HashSet<>(Arrays.asList(socket.getEnabledCipherSuites())); + List<String> enabledSuites = Arrays.asList(socket.getEnabledCipherSuites()); enabledSuites.removeAll(disabledCipherSuites); socket.setEnabledCipherSuites(enabledSuites.toArray(new String[enabledSuites.size()])); } - } + public static void updateEnabledTlsProtocols(final SSLSocket socket, + final List<String> enabledTlsProtocols, + final List<String> disabledTlsProtocols) + { + if (enabledTlsProtocols != null && !enabledTlsProtocols.isEmpty()) + { + List<String> supportedProtocols = Arrays.asList(socket.getSupportedProtocols()); + supportedProtocols.retainAll(enabledTlsProtocols); + socket.setEnabledProtocols(supportedProtocols.toArray(new String[supportedProtocols.size()])); + } + if (disabledTlsProtocols != null && !disabledTlsProtocols.isEmpty()) + { + List<String> enabledProtocols = Arrays.asList(socket.getEnabledProtocols()); + enabledProtocols.removeAll(disabledTlsProtocols); + socket.setEnabledProtocols(enabledProtocols.toArray(new String[enabledProtocols.size()])); + } + } } --------------------------------------------------------------------- To unsubscribe, e-mail: [email protected] For additional commands, e-mail: [email protected]
