You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@brooklyn.apache.org by he...@apache.org on 2016/03/30 15:59:47 UTC
[10/50] brooklyn-server git commit: [BROOKLYN-183] Split servlet
filter BrooklynPropertiesSecurityFilter into various JAX-RS parts
[BROOKLYN-183] Split servlet filter BrooklynPropertiesSecurityFilter into various JAX-RS parts
* LogoutApi & LogoutResource
* RequestTaggingRsFilter - still need a servlet version of it because of the LoggingFilter, so get the tag from the request if one is present, generate otherwise
* EntitlementContextFilter - initialise thread request entitlements
* Support identical functionality in Jersey
* Deprecate BrooklynPropertiesSecurityFilter
Project: http://git-wip-us.apache.org/repos/asf/brooklyn-server/repo
Commit: http://git-wip-us.apache.org/repos/asf/brooklyn-server/commit/857fd21d
Tree: http://git-wip-us.apache.org/repos/asf/brooklyn-server/tree/857fd21d
Diff: http://git-wip-us.apache.org/repos/asf/brooklyn-server/diff/857fd21d
Branch: refs/heads/master
Commit: 857fd21d70e710b31f0eeb9fafce9752c351a167
Parents: 5aab739
Author: Svetoslav Neykov <sv...@cloudsoftcorp.com>
Authored: Sun Feb 28 15:48:13 2016 +0200
Committer: Svetoslav Neykov <sv...@cloudsoftcorp.com>
Committed: Thu Mar 17 15:25:45 2016 +0200
----------------------------------------------------------------------
.../brooklyn/launcher/BrooklynWebServer.java | 4 +-
.../org/apache/brooklyn/rest/api/LogoutApi.java | 36 ++++++++
.../apache/brooklyn/rest/BrooklynRestApi.java | 2 +
.../rest/filter/EntitlementContextFilter.java | 63 +++++++++++++
.../brooklyn/rest/filter/NoCacheFilter.java | 2 +
.../rest/filter/RequestTaggingRsFilter.java | 77 ++++++++++++++++
.../brooklyn/rest/resources/LogoutResource.java | 47 ++++++++++
.../resources/OSGI-INF/blueprint/service.xml | 15 ++++
.../filter/EntitlementContextFilterTest.java | 94 ++++++++++++++++++++
.../rest/filter/RequestTaggingRsFilterTest.java | 75 ++++++++++++++++
rest/rest-server-jersey/pom.xml | 3 +
.../rest/filter/EntitlementContextFilter.java | 63 +++++++++++++
.../brooklyn/rest/filter/NoCacheFilter.java | 2 +
.../rest/filter/RequestTaggingRsFilter.java | 76 ++++++++++++++++
.../brooklyn/rest/filter/SwaggerFilter.java | 3 -
.../BrooklynPropertiesSecurityFilter.java | 6 +-
.../rest/filter/RequestTaggingFilter.java | 3 +-
.../rest-server/src/main/webapp/WEB-INF/web.xml | 24 ++---
.../brooklyn/rest/BrooklynRestApiLauncher.java | 22 +++--
19 files changed, 584 insertions(+), 33 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/857fd21d/launcher/src/main/java/org/apache/brooklyn/launcher/BrooklynWebServer.java
----------------------------------------------------------------------
diff --git a/launcher/src/main/java/org/apache/brooklyn/launcher/BrooklynWebServer.java b/launcher/src/main/java/org/apache/brooklyn/launcher/BrooklynWebServer.java
index b42a5f0..449c0f4 100644
--- a/launcher/src/main/java/org/apache/brooklyn/launcher/BrooklynWebServer.java
+++ b/launcher/src/main/java/org/apache/brooklyn/launcher/BrooklynWebServer.java
@@ -434,8 +434,10 @@ public class BrooklynWebServer {
RestApiSetup.installRest(context,
new ManagementContextProvider(),
new ShutdownHandlerProvider(shutdownHandler),
+ new RequestTaggingRsFilter(),
new NoCacheFilter(),
- new HaHotCheckResourceFilter());
+ new HaHotCheckResourceFilter(),
+ new EntitlementContextFilter());
RestApiSetup.installServletFilters(context,
RequestTaggingFilter.class,
LoggingFilter.class);
http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/857fd21d/rest/rest-api/src/main/java/org/apache/brooklyn/rest/api/LogoutApi.java
----------------------------------------------------------------------
diff --git a/rest/rest-api/src/main/java/org/apache/brooklyn/rest/api/LogoutApi.java b/rest/rest-api/src/main/java/org/apache/brooklyn/rest/api/LogoutApi.java
new file mode 100644
index 0000000..2b9c0c5
--- /dev/null
+++ b/rest/rest-api/src/main/java/org/apache/brooklyn/rest/api/LogoutApi.java
@@ -0,0 +1,36 @@
+/*
+ * 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.
+ */
+package org.apache.brooklyn.rest.api;
+
+import javax.ws.rs.POST;
+import javax.ws.rs.Path;
+import javax.ws.rs.core.Response;
+
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+
+@Path("/logout")
+@Api("Logout")
+public interface LogoutApi {
+
+ @POST
+ @ApiOperation(value = "Logout and clean session")
+ Response logout();
+
+}
http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/857fd21d/rest/rest-resources/src/main/java/org/apache/brooklyn/rest/BrooklynRestApi.java
----------------------------------------------------------------------
diff --git a/rest/rest-resources/src/main/java/org/apache/brooklyn/rest/BrooklynRestApi.java b/rest/rest-resources/src/main/java/org/apache/brooklyn/rest/BrooklynRestApi.java
index f42548f..df2be65 100644
--- a/rest/rest-resources/src/main/java/org/apache/brooklyn/rest/BrooklynRestApi.java
+++ b/rest/rest-resources/src/main/java/org/apache/brooklyn/rest/BrooklynRestApi.java
@@ -31,6 +31,7 @@ import org.apache.brooklyn.rest.resources.EffectorResource;
import org.apache.brooklyn.rest.resources.EntityConfigResource;
import org.apache.brooklyn.rest.resources.EntityResource;
import org.apache.brooklyn.rest.resources.LocationResource;
+import org.apache.brooklyn.rest.resources.LogoutResource;
import org.apache.brooklyn.rest.resources.PolicyConfigResource;
import org.apache.brooklyn.rest.resources.PolicyResource;
import org.apache.brooklyn.rest.resources.ScriptResource;
@@ -67,6 +68,7 @@ public class BrooklynRestApi {
resources.add(new ServerResource());
resources.add(new UsageResource());
resources.add(new VersionResource());
+ resources.add(new LogoutResource());
return resources;
}
http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/857fd21d/rest/rest-resources/src/main/java/org/apache/brooklyn/rest/filter/EntitlementContextFilter.java
----------------------------------------------------------------------
diff --git a/rest/rest-resources/src/main/java/org/apache/brooklyn/rest/filter/EntitlementContextFilter.java b/rest/rest-resources/src/main/java/org/apache/brooklyn/rest/filter/EntitlementContextFilter.java
new file mode 100644
index 0000000..a039b57
--- /dev/null
+++ b/rest/rest-resources/src/main/java/org/apache/brooklyn/rest/filter/EntitlementContextFilter.java
@@ -0,0 +1,63 @@
+/*
+ * 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.
+ */
+package org.apache.brooklyn.rest.filter;
+
+import java.io.IOException;
+import java.security.Principal;
+
+import javax.annotation.Priority;
+import javax.servlet.http.HttpServletRequest;
+import javax.ws.rs.container.ContainerRequestContext;
+import javax.ws.rs.container.ContainerRequestFilter;
+import javax.ws.rs.container.ContainerResponseContext;
+import javax.ws.rs.container.ContainerResponseFilter;
+import javax.ws.rs.core.Context;
+import javax.ws.rs.core.SecurityContext;
+import javax.ws.rs.ext.Provider;
+
+import org.apache.brooklyn.core.mgmt.entitlement.Entitlements;
+import org.apache.brooklyn.core.mgmt.entitlement.WebEntitlementContext;
+
+@Provider
+@Priority(400)
+public class EntitlementContextFilter implements ContainerRequestFilter, ContainerResponseFilter {
+ @Context
+ private HttpServletRequest request;
+
+ @Override
+ public void filter(ContainerRequestContext requestContext) throws IOException {
+ SecurityContext securityContext = requestContext.getSecurityContext();
+ Principal user = securityContext.getUserPrincipal();
+
+ if (user != null) {
+ String uri = request.getRequestURI();
+ String remoteAddr = request.getRemoteAddr();
+
+ String uid = RequestTaggingRsFilter.getTag();
+ WebEntitlementContext entitlementContext = new WebEntitlementContext(user.getName(), remoteAddr, uri, uid);
+ Entitlements.setEntitlementContext(entitlementContext);
+ }
+ }
+
+ @Override
+ public void filter(ContainerRequestContext requestContext, ContainerResponseContext responseContext) throws IOException {
+ Entitlements.clearEntitlementContext();
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/857fd21d/rest/rest-resources/src/main/java/org/apache/brooklyn/rest/filter/NoCacheFilter.java
----------------------------------------------------------------------
diff --git a/rest/rest-resources/src/main/java/org/apache/brooklyn/rest/filter/NoCacheFilter.java b/rest/rest-resources/src/main/java/org/apache/brooklyn/rest/filter/NoCacheFilter.java
index 97fdda1..ed33594 100644
--- a/rest/rest-resources/src/main/java/org/apache/brooklyn/rest/filter/NoCacheFilter.java
+++ b/rest/rest-resources/src/main/java/org/apache/brooklyn/rest/filter/NoCacheFilter.java
@@ -18,6 +18,7 @@
*/
package org.apache.brooklyn.rest.filter;
+import javax.annotation.Priority;
import javax.ws.rs.container.ContainerRequestContext;
import javax.ws.rs.container.ContainerResponseContext;
import javax.ws.rs.container.ContainerResponseFilter;
@@ -26,6 +27,7 @@ import javax.ws.rs.core.MultivaluedMap;
import javax.ws.rs.ext.Provider;
@Provider
+@Priority(200)
public class NoCacheFilter implements ContainerResponseFilter {
@Override
http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/857fd21d/rest/rest-resources/src/main/java/org/apache/brooklyn/rest/filter/RequestTaggingRsFilter.java
----------------------------------------------------------------------
diff --git a/rest/rest-resources/src/main/java/org/apache/brooklyn/rest/filter/RequestTaggingRsFilter.java b/rest/rest-resources/src/main/java/org/apache/brooklyn/rest/filter/RequestTaggingRsFilter.java
new file mode 100644
index 0000000..95e8533
--- /dev/null
+++ b/rest/rest-resources/src/main/java/org/apache/brooklyn/rest/filter/RequestTaggingRsFilter.java
@@ -0,0 +1,77 @@
+/*
+ * 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.
+ */
+package org.apache.brooklyn.rest.filter;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+
+import java.io.IOException;
+
+import javax.annotation.Priority;
+import javax.servlet.http.HttpServletRequest;
+import javax.ws.rs.container.ContainerRequestContext;
+import javax.ws.rs.container.ContainerRequestFilter;
+import javax.ws.rs.container.ContainerResponseContext;
+import javax.ws.rs.container.ContainerResponseFilter;
+import javax.ws.rs.core.Context;
+import javax.ws.rs.ext.Provider;
+
+import org.apache.brooklyn.util.text.Identifiers;
+
+/**
+ * Tags each request with a probabilistically unique id. Should be included before other
+ * filters to make sense.
+ */
+@Provider
+@Priority(100)
+public class RequestTaggingRsFilter implements ContainerRequestFilter, ContainerResponseFilter {
+ public static final String ATT_REQUEST_ID = RequestTaggingRsFilter.class.getName() + ".id";
+
+ @Context
+ private HttpServletRequest req;
+
+ private static ThreadLocal<String> tag = new ThreadLocal<String>();
+
+ protected static String getTag() {
+ // Alternatively could use
+ // PhaseInterceptorChain.getCurrentMessage().getId()
+
+ return checkNotNull(tag.get());
+ }
+
+ @Override
+ public void filter(ContainerRequestContext requestContext) throws IOException {
+ String requestId = getRequestId();
+ tag.set(requestId);
+ }
+
+ private String getRequestId() {
+ Object id = req.getAttribute(ATT_REQUEST_ID);
+ if (id != null) {
+ return id.toString();
+ } else {
+ return Identifiers.makeRandomId(6);
+ }
+ }
+
+ @Override
+ public void filter(ContainerRequestContext requestContext, ContainerResponseContext responseContext) throws IOException {
+ tag.remove();
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/857fd21d/rest/rest-resources/src/main/java/org/apache/brooklyn/rest/resources/LogoutResource.java
----------------------------------------------------------------------
diff --git a/rest/rest-resources/src/main/java/org/apache/brooklyn/rest/resources/LogoutResource.java b/rest/rest-resources/src/main/java/org/apache/brooklyn/rest/resources/LogoutResource.java
new file mode 100644
index 0000000..bc300b9
--- /dev/null
+++ b/rest/rest-resources/src/main/java/org/apache/brooklyn/rest/resources/LogoutResource.java
@@ -0,0 +1,47 @@
+/*
+ * 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.
+ */
+package org.apache.brooklyn.rest.resources;
+
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServletRequest;
+import javax.ws.rs.core.Context;
+import javax.ws.rs.core.Response;
+import javax.ws.rs.core.Response.Status;
+
+import org.apache.brooklyn.rest.api.LogoutApi;
+import org.apache.brooklyn.util.exceptions.Exceptions;
+
+public class LogoutResource extends AbstractBrooklynRestResource implements LogoutApi {
+ @Context HttpServletRequest req;
+
+ @Override
+ public Response logout() {
+ try {
+ req.logout();
+ } catch (ServletException e) {
+ Exceptions.propagate(e);
+ }
+
+ req.getSession().invalidate();
+ return Response.status(Status.UNAUTHORIZED)
+ .header("WWW-Authenticate", "Basic realm=\"webconsole\"")
+ .build();
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/857fd21d/rest/rest-resources/src/main/resources/OSGI-INF/blueprint/service.xml
----------------------------------------------------------------------
diff --git a/rest/rest-resources/src/main/resources/OSGI-INF/blueprint/service.xml b/rest/rest-resources/src/main/resources/OSGI-INF/blueprint/service.xml
index 9106d31..42ab968 100644
--- a/rest/rest-resources/src/main/resources/OSGI-INF/blueprint/service.xml
+++ b/rest/rest-resources/src/main/resources/OSGI-INF/blueprint/service.xml
@@ -110,6 +110,9 @@ limitations under the License.
<property name="managementContext" ref="localManagementContext" />
<property name="managementContextInternal" ref="localManagementContextInternal" />
</bean>
+ <bean id="logoutResourceBean" class="org.apache.brooklyn.rest.resources.LogoutResource">
+ <property name="managementContext" ref="localManagementContext" />
+ </bean>
<jaxrs:server id="brooklynRestApiV1" address="/">
<jaxrs:serviceBeans>
@@ -129,6 +132,7 @@ limitations under the License.
<ref component-id="serverResourceBean" />
<ref component-id="usageResourceBean" />
<ref component-id="versionResourceBean" />
+ <ref component-id="logoutResourceBean" />
</jaxrs:serviceBeans>
<jaxrs:providers>
@@ -138,6 +142,17 @@ limitations under the License.
<bean class="org.apache.cxf.jaxrs.security.JAASAuthenticationFilter">
<property name="contextName" value="webconsole"/>
</bean>
+ <bean class="org.apache.brooklyn.rest.util.ManagementContextProvider">
+ <argument ref="localManagementContextInternal" />
+ </bean>
+ <!--
+ TODO ShutdownHandlerProvider, sync with init work.
+ Needs to be custom OSGi implementation?
+ -->
+ <bean class="org.apache.brooklyn.rest.filter.RequestTaggingRsFilter" />
+ <bean class="org.apache.brooklyn.rest.filter.NoCacheFilter" />
+ <bean class="org.apache.brooklyn.rest.filter.HaHotCheckResourceFilter" />
+ <bean class="org.apache.brooklyn.rest.filter.EntitlementContextFilter" />
</jaxrs:providers>
</jaxrs:server>
http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/857fd21d/rest/rest-resources/src/test/java/org/apache/brooklyn/rest/filter/EntitlementContextFilterTest.java
----------------------------------------------------------------------
diff --git a/rest/rest-resources/src/test/java/org/apache/brooklyn/rest/filter/EntitlementContextFilterTest.java b/rest/rest-resources/src/test/java/org/apache/brooklyn/rest/filter/EntitlementContextFilterTest.java
new file mode 100644
index 0000000..cdd2867
--- /dev/null
+++ b/rest/rest-resources/src/test/java/org/apache/brooklyn/rest/filter/EntitlementContextFilterTest.java
@@ -0,0 +1,94 @@
+/*
+ * 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.
+ */
+package org.apache.brooklyn.rest.filter;
+
+import static org.testng.Assert.assertEquals;
+
+import javax.ws.rs.GET;
+import javax.ws.rs.Path;
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.Response;
+
+import org.apache.brooklyn.core.internal.BrooklynProperties;
+import org.apache.brooklyn.core.mgmt.entitlement.Entitlements;
+import org.apache.brooklyn.core.mgmt.entitlement.WebEntitlementContext;
+import org.apache.brooklyn.rest.BrooklynWebConfig;
+import org.apache.brooklyn.rest.security.jaas.JaasUtils;
+import org.apache.brooklyn.rest.security.provider.ExplicitUsersSecurityProvider;
+import org.apache.brooklyn.rest.testing.BrooklynRestResourceTest;
+import org.apache.cxf.interceptor.security.JAASLoginInterceptor;
+import org.apache.cxf.jaxrs.JAXRSServerFactoryBean;
+import org.apache.cxf.jaxrs.client.WebClient;
+import org.apache.http.HttpStatus;
+import org.testng.annotations.Test;
+
+public class EntitlementContextFilterTest extends BrooklynRestResourceTest {
+
+ private static final String USER_PASS = "admin";
+
+ public static class EntitlementResource {
+ @GET
+ @Path("/test")
+ public String test() {
+ WebEntitlementContext context = (WebEntitlementContext)Entitlements.getEntitlementContext();
+ return context.user();
+ }
+ }
+
+ @Override
+ protected void configureCXF(JAXRSServerFactoryBean sf) {
+ BrooklynProperties props = (BrooklynProperties)getManagementContext().getConfig();
+ props.put(BrooklynWebConfig.USERS, USER_PASS);
+ props.put(BrooklynWebConfig.PASSWORD_FOR_USER(USER_PASS), USER_PASS);
+ props.put(BrooklynWebConfig.SECURITY_PROVIDER_INSTANCE, new ExplicitUsersSecurityProvider(getManagementContext()));
+
+ super.configureCXF(sf);
+
+ JaasUtils.init(getManagementContext());
+
+ JAASLoginInterceptor jaas = new JAASLoginInterceptor();
+ jaas.setContextName("webconsole");
+ sf.getInInterceptors().add(jaas);
+
+ }
+
+ @Override
+ protected void addBrooklynResources() {
+ addResource(new RequestTaggingRsFilter());
+ addResource(new EntitlementContextFilter());
+ addResource(new EntitlementResource());
+ }
+
+ @Test
+ public void testEntitlementContextSet() {
+ Response response = fetch("/test");
+ assertEquals(response.getStatus(), HttpStatus.SC_OK);
+ String tag = (String) response.readEntity(String.class);
+ assertEquals(tag, USER_PASS);
+ }
+
+ protected Response fetch(String path) {
+ WebClient resource = WebClient.create(getEndpointAddress(), clientProviders, USER_PASS, USER_PASS, null)
+ .path(path)
+ .accept(MediaType.APPLICATION_JSON_TYPE);
+ Response response = resource.get();
+ return response;
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/857fd21d/rest/rest-resources/src/test/java/org/apache/brooklyn/rest/filter/RequestTaggingRsFilterTest.java
----------------------------------------------------------------------
diff --git a/rest/rest-resources/src/test/java/org/apache/brooklyn/rest/filter/RequestTaggingRsFilterTest.java b/rest/rest-resources/src/test/java/org/apache/brooklyn/rest/filter/RequestTaggingRsFilterTest.java
new file mode 100644
index 0000000..0154055
--- /dev/null
+++ b/rest/rest-resources/src/test/java/org/apache/brooklyn/rest/filter/RequestTaggingRsFilterTest.java
@@ -0,0 +1,75 @@
+/*
+ * 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.
+ */
+package org.apache.brooklyn.rest.filter;
+
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertNotEquals;
+import static org.testng.Assert.assertNotNull;
+
+import javax.ws.rs.GET;
+import javax.ws.rs.Path;
+import javax.ws.rs.Produces;
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.Response;
+
+import org.apache.brooklyn.rest.testing.BrooklynRestResourceTest;
+import org.apache.cxf.jaxrs.client.WebClient;
+import org.apache.http.HttpStatus;
+import org.testng.annotations.Test;
+
+public class RequestTaggingRsFilterTest extends BrooklynRestResourceTest {
+
+ @Path("/tag")
+ @Produces(MediaType.APPLICATION_JSON)
+ public static class TagResource {
+ @GET
+ public String tag() {
+ return RequestTaggingRsFilter.getTag();
+ }
+ }
+
+ @Override
+ protected void addBrooklynResources() {
+ addResource(new RequestTaggingRsFilter());
+ addResource(new TagResource());
+ }
+
+ @Test
+ public void testTaggingFilter() {
+ String tag1 = fetchTag();
+ String tag2 = fetchTag();
+ assertNotEquals(tag1, tag2);
+ }
+
+ private String fetchTag() {
+ Response response = fetch("/tag");
+ assertEquals(response.getStatus(), HttpStatus.SC_OK);
+ String tag = (String) response.readEntity(String.class);
+ assertNotNull(tag);
+ return tag;
+ }
+
+ protected Response fetch(String path) {
+ WebClient resource = client().path(path)
+ .accept(MediaType.APPLICATION_JSON_TYPE);
+ Response response = resource.get();
+ return response;
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/857fd21d/rest/rest-server-jersey/pom.xml
----------------------------------------------------------------------
diff --git a/rest/rest-server-jersey/pom.xml b/rest/rest-server-jersey/pom.xml
index 6a92dfb..baaf31e 100644
--- a/rest/rest-server-jersey/pom.xml
+++ b/rest/rest-server-jersey/pom.xml
@@ -259,6 +259,9 @@
<exclude>**/HaHotCheckResourceFilter.java</exclude>
<exclude>**/FormMapProvider.java</exclude>
<exclude>**/ApidocResource.java</exclude>
+ <exclude>**/RequestTaggingFilter.java</exclude>
+ <exclude>**/EntitlementContextFilter.java</exclude>
+ <exclude>**/RequestTaggingRsFilter.java</exclude>
</excludes>
</resource>
<resource>
http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/857fd21d/rest/rest-server-jersey/src/main/java/org/apache/brooklyn/rest/filter/EntitlementContextFilter.java
----------------------------------------------------------------------
diff --git a/rest/rest-server-jersey/src/main/java/org/apache/brooklyn/rest/filter/EntitlementContextFilter.java b/rest/rest-server-jersey/src/main/java/org/apache/brooklyn/rest/filter/EntitlementContextFilter.java
new file mode 100644
index 0000000..2c3e200
--- /dev/null
+++ b/rest/rest-server-jersey/src/main/java/org/apache/brooklyn/rest/filter/EntitlementContextFilter.java
@@ -0,0 +1,63 @@
+/*
+ * 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.
+ */
+package org.apache.brooklyn.rest.filter;
+
+import java.security.Principal;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.ws.rs.core.Context;
+import javax.ws.rs.core.SecurityContext;
+
+import org.apache.brooklyn.core.mgmt.entitlement.Entitlements;
+import org.apache.brooklyn.core.mgmt.entitlement.WebEntitlementContext;
+
+import com.sun.jersey.core.util.Priority;
+import com.sun.jersey.spi.container.ContainerRequest;
+import com.sun.jersey.spi.container.ContainerRequestFilter;
+import com.sun.jersey.spi.container.ContainerResponse;
+import com.sun.jersey.spi.container.ContainerResponseFilter;
+
+@Priority(400)
+public class EntitlementContextFilter implements ContainerRequestFilter, ContainerResponseFilter {
+ @Context
+ private HttpServletRequest servletRequest;
+
+ @Override
+ public ContainerRequest filter(ContainerRequest request) {
+ SecurityContext securityContext = request.getSecurityContext();
+ Principal user = securityContext.getUserPrincipal();
+
+ if (user != null) {
+ String uri = servletRequest.getRequestURI();
+ String remoteAddr = servletRequest.getRemoteAddr();
+
+ String uid = RequestTaggingFilter.getTag();
+ WebEntitlementContext entitlementContext = new WebEntitlementContext(user.getName(), remoteAddr, uri, uid);
+ Entitlements.setEntitlementContext(entitlementContext);
+ }
+ return request;
+ }
+
+ @Override
+ public ContainerResponse filter(ContainerRequest request, ContainerResponse response) {
+ Entitlements.clearEntitlementContext();
+ return response;
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/857fd21d/rest/rest-server-jersey/src/main/java/org/apache/brooklyn/rest/filter/NoCacheFilter.java
----------------------------------------------------------------------
diff --git a/rest/rest-server-jersey/src/main/java/org/apache/brooklyn/rest/filter/NoCacheFilter.java b/rest/rest-server-jersey/src/main/java/org/apache/brooklyn/rest/filter/NoCacheFilter.java
index 8a3c1c6..b66b3dc 100644
--- a/rest/rest-server-jersey/src/main/java/org/apache/brooklyn/rest/filter/NoCacheFilter.java
+++ b/rest/rest-server-jersey/src/main/java/org/apache/brooklyn/rest/filter/NoCacheFilter.java
@@ -21,10 +21,12 @@ package org.apache.brooklyn.rest.filter;
import javax.ws.rs.core.HttpHeaders;
import javax.ws.rs.core.MultivaluedMap;
+import com.sun.jersey.core.util.Priority;
import com.sun.jersey.spi.container.ContainerRequest;
import com.sun.jersey.spi.container.ContainerResponse;
import com.sun.jersey.spi.container.ContainerResponseFilter;
+@Priority(200)
public class NoCacheFilter implements ContainerResponseFilter {
@Override
http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/857fd21d/rest/rest-server-jersey/src/main/java/org/apache/brooklyn/rest/filter/RequestTaggingRsFilter.java
----------------------------------------------------------------------
diff --git a/rest/rest-server-jersey/src/main/java/org/apache/brooklyn/rest/filter/RequestTaggingRsFilter.java b/rest/rest-server-jersey/src/main/java/org/apache/brooklyn/rest/filter/RequestTaggingRsFilter.java
new file mode 100644
index 0000000..588c5c1
--- /dev/null
+++ b/rest/rest-server-jersey/src/main/java/org/apache/brooklyn/rest/filter/RequestTaggingRsFilter.java
@@ -0,0 +1,76 @@
+/*
+ * 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.
+ */
+package org.apache.brooklyn.rest.filter;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.ws.rs.core.Context;
+
+import org.apache.brooklyn.util.text.Identifiers;
+
+import com.sun.jersey.core.util.Priority;
+import com.sun.jersey.spi.container.ContainerRequest;
+import com.sun.jersey.spi.container.ContainerRequestFilter;
+import com.sun.jersey.spi.container.ContainerResponse;
+import com.sun.jersey.spi.container.ContainerResponseFilter;
+
+/**
+ * Tags each request with a probabilistically unique id. Should be included before other
+ * filters to make sense.
+ */
+@Priority(100)
+public class RequestTaggingRsFilter implements ContainerRequestFilter, ContainerResponseFilter {
+ public static final String ATT_REQUEST_ID = RequestTaggingRsFilter.class.getName() + ".id";
+
+ @Context
+ private HttpServletRequest req;
+
+ private static ThreadLocal<String> tag = new ThreadLocal<String>();
+
+ protected static String getTag() {
+ // Alternatively could use
+ // PhaseInterceptorChain.getCurrentMessage().getId()
+
+ return checkNotNull(tag.get());
+ }
+
+ @Override
+ public ContainerRequest filter(ContainerRequest request) {
+ String requestId = getRequestId();
+ tag.set(requestId);
+ return request;
+ }
+
+ private String getRequestId() {
+ Object id = req.getAttribute(ATT_REQUEST_ID);
+ if (id != null) {
+ return id.toString();
+ } else {
+ return Identifiers.makeRandomId(6);
+ }
+ }
+
+ @Override
+ public ContainerResponse filter(ContainerRequest request, ContainerResponse response) {
+ tag.remove();
+ return response;
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/857fd21d/rest/rest-server-jersey/src/main/java/org/apache/brooklyn/rest/filter/SwaggerFilter.java
----------------------------------------------------------------------
diff --git a/rest/rest-server-jersey/src/main/java/org/apache/brooklyn/rest/filter/SwaggerFilter.java b/rest/rest-server-jersey/src/main/java/org/apache/brooklyn/rest/filter/SwaggerFilter.java
index d9013f0..ce8b747 100644
--- a/rest/rest-server-jersey/src/main/java/org/apache/brooklyn/rest/filter/SwaggerFilter.java
+++ b/rest/rest-server-jersey/src/main/java/org/apache/brooklyn/rest/filter/SwaggerFilter.java
@@ -18,9 +18,7 @@
*/
package org.apache.brooklyn.rest.filter;
-import java.io.File;
import java.io.IOException;
-import java.net.URISyntaxException;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
@@ -29,7 +27,6 @@ import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
-import javax.ws.rs.core.UriBuilder;
import org.apache.brooklyn.rest.apidoc.RestApiResourceScanner;
http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/857fd21d/rest/rest-server/src/main/java/org/apache/brooklyn/rest/filter/BrooklynPropertiesSecurityFilter.java
----------------------------------------------------------------------
diff --git a/rest/rest-server/src/main/java/org/apache/brooklyn/rest/filter/BrooklynPropertiesSecurityFilter.java b/rest/rest-server/src/main/java/org/apache/brooklyn/rest/filter/BrooklynPropertiesSecurityFilter.java
index 6dd84e0..a7af6de 100644
--- a/rest/rest-server/src/main/java/org/apache/brooklyn/rest/filter/BrooklynPropertiesSecurityFilter.java
+++ b/rest/rest-server/src/main/java/org/apache/brooklyn/rest/filter/BrooklynPropertiesSecurityFilter.java
@@ -35,6 +35,7 @@ import org.apache.brooklyn.api.mgmt.ManagementContext;
import org.apache.brooklyn.core.mgmt.entitlement.Entitlements;
import org.apache.brooklyn.core.mgmt.entitlement.WebEntitlementContext;
import org.apache.brooklyn.rest.BrooklynWebConfig;
+import org.apache.brooklyn.rest.security.jaas.BrooklynLoginModule;
import org.apache.brooklyn.rest.security.provider.DelegatingSecurityProvider;
import org.apache.brooklyn.rest.util.OsgiCompat;
import org.apache.brooklyn.util.text.Strings;
@@ -44,7 +45,10 @@ import org.slf4j.LoggerFactory;
/**
* Provides basic HTTP authentication.
+ *
+ * @deprecated since 0.9.0, use JAAS authentication instead, see {@link BrooklynLoginModule}.
*/
+@Deprecated
public class BrooklynPropertiesSecurityFilter implements Filter {
/**
@@ -53,7 +57,7 @@ public class BrooklynPropertiesSecurityFilter implements Filter {
* the providers may impose additional criteria such as timeouts,
* or a null user (no login) may be permitted)
*/
- public static final String AUTHENTICATED_USER_SESSION_ATTRIBUTE = "brooklyn.user";
+ public static final String AUTHENTICATED_USER_SESSION_ATTRIBUTE = BrooklynLoginModule.AUTHENTICATED_USER_SESSION_ATTRIBUTE;
/**
* The session attribute set to indicate the remote address of the HTTP request.
http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/857fd21d/rest/rest-server/src/main/java/org/apache/brooklyn/rest/filter/RequestTaggingFilter.java
----------------------------------------------------------------------
diff --git a/rest/rest-server/src/main/java/org/apache/brooklyn/rest/filter/RequestTaggingFilter.java b/rest/rest-server/src/main/java/org/apache/brooklyn/rest/filter/RequestTaggingFilter.java
index 3553aaa..85f5bf2 100644
--- a/rest/rest-server/src/main/java/org/apache/brooklyn/rest/filter/RequestTaggingFilter.java
+++ b/rest/rest-server/src/main/java/org/apache/brooklyn/rest/filter/RequestTaggingFilter.java
@@ -33,7 +33,7 @@ import org.apache.brooklyn.util.text.Identifiers;
* Tags each request with a probabilistically unique id. Should be included before other
* filters to make sense.
*/
-//TODO Re-implement as JAX-RS filter
+// TODO Deprecate after porting LoggingFilter
public class RequestTaggingFilter implements Filter {
private static ThreadLocal<String> tag = new ThreadLocal<String>();
@@ -45,6 +45,7 @@ public class RequestTaggingFilter implements Filter {
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
String requestId = Identifiers.makeRandomId(6);
+ request.setAttribute(RequestTaggingRsFilter.ATT_REQUEST_ID, requestId);
tag.set(requestId);
try {
chain.doFilter(request, response);
http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/857fd21d/rest/rest-server/src/main/webapp/WEB-INF/web.xml
----------------------------------------------------------------------
diff --git a/rest/rest-server/src/main/webapp/WEB-INF/web.xml b/rest/rest-server/src/main/webapp/WEB-INF/web.xml
index cd1f38f..b763b8e 100644
--- a/rest/rest-server/src/main/webapp/WEB-INF/web.xml
+++ b/rest/rest-server/src/main/webapp/WEB-INF/web.xml
@@ -30,15 +30,6 @@
</filter-mapping>
<filter>
- <filter-name>Brooklyn Properties Authentication Filter</filter-name>
- <filter-class>org.apache.brooklyn.rest.filter.BrooklynPropertiesSecurityFilter</filter-class>
- </filter>
- <filter-mapping>
- <filter-name>Brooklyn Properties Authentication Filter</filter-name>
- <url-pattern>/*</url-pattern>
- </filter-mapping>
-
- <filter>
<filter-name>Brooklyn Logging Filter</filter-name>
<filter-class>org.apache.brooklyn.rest.filter.LoggingFilter</filter-class>
</filter>
@@ -47,15 +38,6 @@
<url-pattern>/*</url-pattern>
</filter-mapping>
- <filter>
- <filter-name>Brooklyn HA Master Filter</filter-name>
- <filter-class>org.apache.brooklyn.rest.filter.HaMasterCheckFilter</filter-class>
- </filter>
- <filter-mapping>
- <filter-name>Brooklyn HA Master Filter</filter-name>
- <url-pattern>/*</url-pattern>
- </filter-mapping>
-
<!-- Brooklyn REST is usually run as a filter so static content can be placed in a webapp
to which this is added; to run as a servlet directly, replace the filter tags
below (after the comment) with the servlet tags (commented out immediately below),
@@ -95,7 +77,11 @@
<param-value>
io.swagger.jaxrs.listing.SwaggerSerializers,
org.apache.brooklyn.rest.util.FormMapProvider,
- com.fasterxml.jackson.jaxrs.json.JacksonJsonProvider
+ com.fasterxml.jackson.jaxrs.json.JacksonJsonProvider,
+ org.apache.brooklyn.rest.filter.RequestTaggingRsFilter,
+ org.apache.brooklyn.rest.filter.NoCacheFilter,
+ org.apache.brooklyn.rest.filter.HaHotCheckResourceFilter,
+ org.apache.brooklyn.rest.filter.EntitlementContextFilter,
org.apache.brooklyn.rest.util.ManagementContextProvider
<!-- org.apache.brooklyn.rest.util.ShutdownHandlerProvider -->
</param-value>
http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/857fd21d/rest/rest-server/src/test/java/org/apache/brooklyn/rest/BrooklynRestApiLauncher.java
----------------------------------------------------------------------
diff --git a/rest/rest-server/src/test/java/org/apache/brooklyn/rest/BrooklynRestApiLauncher.java b/rest/rest-server/src/test/java/org/apache/brooklyn/rest/BrooklynRestApiLauncher.java
index 1dc9bd5..afec450 100644
--- a/rest/rest-server/src/test/java/org/apache/brooklyn/rest/BrooklynRestApiLauncher.java
+++ b/rest/rest-server/src/test/java/org/apache/brooklyn/rest/BrooklynRestApiLauncher.java
@@ -36,10 +36,13 @@ import org.apache.brooklyn.core.mgmt.internal.LocalManagementContext;
import org.apache.brooklyn.core.mgmt.internal.ManagementContextInternal;
import org.apache.brooklyn.core.server.BrooklynServerConfig;
import org.apache.brooklyn.core.server.BrooklynServiceAttributes;
-import org.apache.brooklyn.rest.filter.BrooklynPropertiesSecurityFilter;
-import org.apache.brooklyn.rest.filter.HaMasterCheckFilter;
+import org.apache.brooklyn.rest.filter.EntitlementContextFilter;
+import org.apache.brooklyn.rest.filter.HaHotCheckResourceFilter;
import org.apache.brooklyn.rest.filter.LoggingFilter;
+import org.apache.brooklyn.rest.filter.NoCacheFilter;
import org.apache.brooklyn.rest.filter.RequestTaggingFilter;
+import org.apache.brooklyn.rest.filter.RequestTaggingRsFilter;
+import org.apache.brooklyn.rest.security.jaas.BrooklynLoginModule.RolePrincipal;
import org.apache.brooklyn.rest.security.provider.AnyoneSecurityProvider;
import org.apache.brooklyn.rest.security.provider.SecurityProvider;
import org.apache.brooklyn.rest.util.ManagementContextProvider;
@@ -51,6 +54,7 @@ import org.apache.brooklyn.util.guava.Maybe;
import org.apache.brooklyn.util.net.Networking;
import org.apache.brooklyn.util.os.Os;
import org.apache.brooklyn.util.text.WildcardGlobs;
+import org.eclipse.jetty.jaas.JAASLoginService;
import org.eclipse.jetty.server.NetworkConnector;
import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.server.handler.ContextHandler;
@@ -89,11 +93,9 @@ public class BrooklynRestApiLauncher {
SERVLET, /** web-xml is not fully supported */ @Beta WEB_XML
}
- public static final List<Class<? extends Filter>> DEFAULT_FILTERS = ImmutableList.of(
+ public static final List<Class<? extends Filter>> DEFAULT_FILTERS = ImmutableList.<Class<? extends Filter>>of(
RequestTaggingFilter.class,
- BrooklynPropertiesSecurityFilter.class,
- LoggingFilter.class,
- HaMasterCheckFilter.class);
+ LoggingFilter.class);
private boolean forceUseOfDefaultCatalogWithJavaClassPath = false;
private Class<? extends SecurityProvider> securityProvider;
@@ -217,8 +219,12 @@ public class BrooklynRestApiLauncher {
installWar(context);
RestApiSetup.installRest(context,
- new ManagementContextProvider(managementContext),
- new ShutdownHandlerProvider(shutdownListener));
+ new ManagementContextProvider(),
+ new ShutdownHandlerProvider(shutdownListener),
+ new RequestTaggingRsFilter(),
+ new NoCacheFilter(),
+ new HaHotCheckResourceFilter(),
+ new EntitlementContextFilter());
RestApiSetup.installServletFilters(context, this.filters);
context.setContextPath("/");