diff --git a/pom.xml b/pom.xml
index 01d020f..7a3a478 100644
--- a/pom.xml
+++ b/pom.xml
@@ -55,5 +55,6 @@
workflow-sample
datasource-samples
cache-control-sample
+ protected-servlet-sample
diff --git a/protected-servlet-sample/README.md b/protected-servlet-sample/README.md
new file mode 100644
index 0000000..89051d2
--- /dev/null
+++ b/protected-servlet-sample/README.md
@@ -0,0 +1,10 @@
+# Jahia Filter with OSGi
+
+This repository contains samples of Jahia Filter declared with OSGi
+
+## How to test it
+
+- Deploy the module on your server
+- You should see servlet filter activate successfully from the logs
+- Go to any page on jahia and check response headers
+- You should be able to see header value injected ("x-sample-filter-header": "some-test-value")
diff --git a/protected-servlet-sample/pom.xml b/protected-servlet-sample/pom.xml
new file mode 100644
index 0000000..c592cc0
--- /dev/null
+++ b/protected-servlet-sample/pom.xml
@@ -0,0 +1,53 @@
+
+
+ 4.0.0
+
+
+ jahia-modules
+ org.jahia.modules
+ 8.1.8.0
+
+
+ protected-servlet-samples
+ org.foo.modules
+ 1.0.0-SNAPSHOT
+ bundle
+ Jahia protected API samples
+ This is a module providing a servlet protected by scope
+
+
+ scm:git:git@github.com:Jahia/OSGi-modules-samples.git
+ scm:git:git@github.com:Jahia/OSGi-modules-samples.git
+ https://github.com/Jahia/OSGi-modules-samples
+ HEAD
+
+
+
+
+ jahia-public
+ Jahia public Repository
+ https://devtools.jahia.com/nexus/content/groups/public/
+
+ true
+ never
+
+
+
+
+
+
+
+ org.apache.felix
+ maven-bundle-plugin
+ true
+
+
+ <_dsannotations>*
+
+
+
+
+
+
diff --git a/protected-servlet-sample/src/main/java/org/sample/modules/sampleservlet/SampleServlet.java b/protected-servlet-sample/src/main/java/org/sample/modules/sampleservlet/SampleServlet.java
new file mode 100644
index 0000000..2a0681e
--- /dev/null
+++ b/protected-servlet-sample/src/main/java/org/sample/modules/sampleservlet/SampleServlet.java
@@ -0,0 +1,79 @@
+package org.sample.modules.sampleservlet;
+
+import org.jahia.exceptions.JahiaException;
+import org.jahia.services.securityfilter.PermissionService;
+import org.osgi.service.component.annotations.Component;
+import org.osgi.service.component.annotations.Reference;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import javax.jcr.RepositoryException;
+import javax.servlet.*;
+import javax.servlet.http.HttpServlet;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import java.io.IOException;
+
+/**
+ * Example servlet which is accessible for users having the scope sampleApi
+ * This scope is automatically applied for user having the admin permission.
+ */
+@Component(service = { javax.servlet.http.HttpServlet.class, javax.servlet.Servlet.class }, property = { "alias=/sample" })
+public class SampleServlet extends HttpServlet {
+
+ private static final String SCOPE = "sampleApi";
+ private static final Logger LOGGER = LoggerFactory.getLogger(SampleServlet.class);
+
+ private PermissionService permissionService;
+
+ @Reference
+ public void setPermissionService(PermissionService permissionService) {
+ this.permissionService = permissionService;
+ }
+
+ @Override
+ public void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
+ LOGGER.info("Received request");
+ String api = request.getPathInfo().substring(1);
+ try {
+ checkUserAccess(api);
+ } catch (RepositoryException e) {
+ response.sendError(500, "Error while calling api, check logs for more details");
+ LOGGER.error("Error while calling action, check logs for more details", e);
+ return;
+ } catch (JahiaException e) {
+ LOGGER.debug("Access denied to call api {}", api, e);
+ response.sendError(404, "Entrypoint not found: " + api);
+ return;
+ }
+
+ response.setStatus(HttpServletResponse.SC_OK);
+ response.setContentType("text/plain; charset=UTF-8");
+ switch (api) {
+ case "sayHello":
+ response.getWriter().write("Hello!");
+ break;
+ case "sayHi":
+ response.getWriter().write("Hi!");
+ break;
+ case "sayBye":
+ response.getWriter().write("Bye!");
+ break;
+ default:
+ response.getWriter().write("Unknown API");
+ }
+
+ }
+
+ public SampleServlet() {
+ LOGGER.info("Sample servlet started");
+ }
+
+ public void checkUserAccess(String api) throws RepositoryException, JahiaException {
+ if (!this.permissionService.hasPermission(SCOPE + "." + api)) {
+ LOGGER.warn("Access not permitted to call api {}", api);
+ throw new JahiaException(SCOPE + "." + api, "Access to api [" + api + "] is secured and restricted",
+ JahiaException.SECURITY_ERROR, JahiaException.WARNING_SEVERITY);
+ }
+ }
+}
diff --git a/protected-servlet-sample/src/main/resources/META-INF/configurations/org.jahia.bundles.api.authorization-sample.yaml b/protected-servlet-sample/src/main/resources/META-INF/configurations/org.jahia.bundles.api.authorization-sample.yaml
new file mode 100644
index 0000000..6cf9114
--- /dev/null
+++ b/protected-servlet-sample/src/main/resources/META-INF/configurations/org.jahia.bundles.api.authorization-sample.yaml
@@ -0,0 +1,17 @@
+# This file is an example of a scope configuration file that can be used to define access control rules for an API in Jahia.
+# It defines a scope called "sampleScope" that grants access to the "sampleApi" API
+# for users with the "admin" permission.
+# The scope is automatically applied to all requests.
+# To go further and see more advanced configurations, please refer to the following page:
+# https://academy.jahia.com/documentation/jahia-cms/jahia-8.2/developer/working-with-our-apis/security-service-and-filter
+sampleScope:
+ description: Can access to the sample API
+ metadata:
+ visible: true
+ constraints:
+ - user_permission: admin
+ path: /
+ auto_apply:
+ - always: true
+ grants:
+ - api: sampleApi