changeset 232:8fe9127fb648

Enable basic authentication by default Reviewed-by: jerboaa Review-thread: http://icedtea.classpath.org/pipermail/thermostat/2017-August/024617.html
author Jie Kang <jkang@redhat.com>
date Wed, 23 Aug 2017 08:34:51 -0400
parents eb87674844fd
children f872349e7038
files common/core/src/main/java/com/redhat/thermostat/gateway/common/core/auth/DefaultRealmAuthorizer.java common/core/src/main/java/com/redhat/thermostat/gateway/common/core/auth/basic/BasicRealmAuthorizer.java common/core/src/main/java/com/redhat/thermostat/gateway/common/core/auth/basic/BasicWebUser.java common/core/src/main/java/com/redhat/thermostat/gateway/common/core/config/IllegalConfigurationException.java common/core/src/main/java/com/redhat/thermostat/gateway/common/core/config/ServiceConfiguration.java common/core/src/test/java/com/redhat/thermostat/gateway/common/core/auth/DefaultRealmAuthorizerTest.java common/core/src/test/java/com/redhat/thermostat/gateway/common/core/auth/basic/BasicRealmAuthorizerTest.java distribution/src/etc/basic-config.properties distribution/src/etc/global-config.properties server/src/main/java/com/redhat/thermostat/gateway/server/auth/BasicAuthFilter.java server/src/main/java/com/redhat/thermostat/gateway/server/auth/DefaultAuthFilter.java server/src/main/java/com/redhat/thermostat/gateway/server/auth/basic/BasicLoginService.java server/src/main/java/com/redhat/thermostat/gateway/server/auth/basic/BasicUserStore.java server/src/main/java/com/redhat/thermostat/gateway/server/auth/basic/BasicWebUser.java server/src/main/java/com/redhat/thermostat/gateway/server/services/WebArchiveCoreService.java server/src/test/java/com/redhat/thermostat/gateway/server/services/WebArchiveCoreServiceTest.java tests/integration-tests/src/test/java/com/redhat/thermostat/gateway/service/jvm/gc/JvmGcServiceIntegrationTest.java tests/integration-tests/src/test/java/com/redhat/thermostat/gateway/tests/integration/IntegrationTest.java
diffstat 18 files changed, 453 insertions(+), 298 deletions(-) [+]
line wrap: on
line diff
--- a/common/core/src/main/java/com/redhat/thermostat/gateway/common/core/auth/DefaultRealmAuthorizer.java	Mon Aug 21 16:44:08 2017 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,54 +0,0 @@
-/*
- * Copyright 2012-2017 Red Hat, Inc.
- *
- * This file is part of Thermostat.
- *
- * Thermostat is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published
- * by the Free Software Foundation; either version 2, or (at your
- * option) any later version.
- *
- * Thermostat is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Thermostat; see the file COPYING.  If not see
- * <http://www.gnu.org/licenses/>.
- *
- * Linking this code with other modules is making a combined work
- * based on this code.  Thus, the terms and conditions of the GNU
- * General Public License cover the whole combination.
- *
- * As a special exception, the copyright holders of this code give
- * you permission to link this code with independent modules to
- * produce an executable, regardless of the license terms of these
- * independent modules, and to copy and distribute the resulting
- * executable under terms of your choice, provided that you also
- * meet, for each linked independent module, the terms and conditions
- * of the license of that module.  An independent module is a module
- * which is not derived from or based on this code.  If you modify
- * this code, you may extend this exception to your version of the
- * library, but you are not obligated to do so.  If you do not wish
- * to do so, delete this exception statement from your version.
- */
-
-package com.redhat.thermostat.gateway.common.core.auth;
-
-import java.util.Collections;
-import java.util.HashSet;
-import java.util.Set;
-
-public class DefaultRealmAuthorizer extends RealmAuthorizer {
-    public static final String DEFAULT_REALM = "thermostat";
-
-    public DefaultRealmAuthorizer() throws InvalidRoleException {
-        RoleFactory roleFactory = new RoleFactory();
-        Role r = roleFactory.buildRole("r,w,u,d-" + DEFAULT_REALM);
-        Set<Role> roles = new HashSet<>();
-        roles.add(r);
-
-        clientRoles = Collections.unmodifiableSet(roles);
-    }
-}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/common/core/src/main/java/com/redhat/thermostat/gateway/common/core/auth/basic/BasicRealmAuthorizer.java	Wed Aug 23 08:34:51 2017 -0400
@@ -0,0 +1,70 @@
+/*
+ * Copyright 2012-2017 Red Hat, Inc.
+ *
+ * This file is part of Thermostat.
+ *
+ * Thermostat is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published
+ * by the Free Software Foundation; either version 2, or (at your
+ * option) any later version.
+ *
+ * Thermostat is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Thermostat; see the file COPYING.  If not see
+ * <http://www.gnu.org/licenses/>.
+ *
+ * Linking this code with other modules is making a combined work
+ * based on this code.  Thus, the terms and conditions of the GNU
+ * General Public License cover the whole combination.
+ *
+ * As a special exception, the copyright holders of this code give
+ * you permission to link this code with independent modules to
+ * produce an executable, regardless of the license terms of these
+ * independent modules, and to copy and distribute the resulting
+ * executable under terms of your choice, provided that you also
+ * meet, for each linked independent module, the terms and conditions
+ * of the license of that module.  An independent module is a module
+ * which is not derived from or based on this code.  If you modify
+ * this code, you may extend this exception to your version of the
+ * library, but you are not obligated to do so.  If you do not wish
+ * to do so, delete this exception statement from your version.
+ */
+
+package com.redhat.thermostat.gateway.common.core.auth.basic;
+
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.Set;
+
+import com.redhat.thermostat.gateway.common.core.auth.InvalidRoleException;
+import com.redhat.thermostat.gateway.common.core.auth.RealmAuthorizer;
+import com.redhat.thermostat.gateway.common.core.auth.Role;
+import com.redhat.thermostat.gateway.common.core.auth.RoleFactory;
+import com.redhat.thermostat.gateway.common.core.auth.basic.BasicWebUser;
+
+public class BasicRealmAuthorizer extends RealmAuthorizer {
+    public static final String DEFAULT_REALM = "thermostat";
+
+    public BasicRealmAuthorizer(BasicWebUser user) throws InvalidRoleException {
+        RoleFactory roleFactory = new RoleFactory();
+
+        Set<Role> roles = new HashSet<>();
+        for (String role : user.getRoles()) {
+            Role r = roleFactory.buildRole(role);
+            roles.add(r);
+        }
+
+        clientRoles = Collections.unmodifiableSet(roles);
+    }
+
+    /**
+     * Package private for testing
+     */
+    Set<Role> getAllRoles() {
+        return clientRoles;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/common/core/src/main/java/com/redhat/thermostat/gateway/common/core/auth/basic/BasicWebUser.java	Wed Aug 23 08:34:51 2017 -0400
@@ -0,0 +1,69 @@
+/*
+ * Copyright 2012-2017 Red Hat, Inc.
+ *
+ * This file is part of Thermostat.
+ *
+ * Thermostat is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published
+ * by the Free Software Foundation; either version 2, or (at your
+ * option) any later version.
+ *
+ * Thermostat is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Thermostat; see the file COPYING.  If not see
+ * <http://www.gnu.org/licenses/>.
+ *
+ * Linking this code with other modules is making a combined work
+ * based on this code.  Thus, the terms and conditions of the GNU
+ * General Public License cover the whole combination.
+ *
+ * As a special exception, the copyright holders of this code give
+ * you permission to link this code with independent modules to
+ * produce an executable, regardless of the license terms of these
+ * independent modules, and to copy and distribute the resulting
+ * executable under terms of your choice, provided that you also
+ * meet, for each linked independent module, the terms and conditions
+ * of the license of that module.  An independent module is a module
+ * which is not derived from or based on this code.  If you modify
+ * this code, you may extend this exception to your version of the
+ * library, but you are not obligated to do so.  If you do not wish
+ * to do so, delete this exception statement from your version.
+ */
+
+package com.redhat.thermostat.gateway.common.core.auth.basic;
+
+import java.util.Set;
+
+public class BasicWebUser implements RoleAwareUser {
+    private final String username;
+    private final Set<String> roles;
+    private final char[] password;
+
+    public BasicWebUser(String username, char[] password, Set<String> roles) {
+        this.username = username;
+        this.roles = roles;
+        this.password = password;
+    }
+
+    @Override
+    public String getName() {
+        return this.username;
+    }
+
+    @Override
+    public boolean isUserInRole(String role) {
+        return this.roles.contains(role);
+    }
+
+    public String getPassword() {
+        return new String(password);
+    }
+
+    public Set<String> getRoles() {
+        return roles;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/common/core/src/main/java/com/redhat/thermostat/gateway/common/core/config/IllegalConfigurationException.java	Wed Aug 23 08:34:51 2017 -0400
@@ -0,0 +1,43 @@
+/*
+ * Copyright 2012-2017 Red Hat, Inc.
+ *
+ * This file is part of Thermostat.
+ *
+ * Thermostat is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published
+ * by the Free Software Foundation; either version 2, or (at your
+ * option) any later version.
+ *
+ * Thermostat is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Thermostat; see the file COPYING.  If not see
+ * <http://www.gnu.org/licenses/>.
+ *
+ * Linking this code with other modules is making a combined work
+ * based on this code.  Thus, the terms and conditions of the GNU
+ * General Public License cover the whole combination.
+ *
+ * As a special exception, the copyright holders of this code give
+ * you permission to link this code with independent modules to
+ * produce an executable, regardless of the license terms of these
+ * independent modules, and to copy and distribute the resulting
+ * executable under terms of your choice, provided that you also
+ * meet, for each linked independent module, the terms and conditions
+ * of the license of that module.  An independent module is a module
+ * which is not derived from or based on this code.  If you modify
+ * this code, you may extend this exception to your version of the
+ * library, but you are not obligated to do so.  If you do not wish
+ * to do so, delete this exception statement from your version.
+ */
+
+package com.redhat.thermostat.gateway.common.core.config;
+
+public class IllegalConfigurationException extends RuntimeException {
+    public IllegalConfigurationException(String s) {
+        super(s);
+    }
+}
--- a/common/core/src/main/java/com/redhat/thermostat/gateway/common/core/config/ServiceConfiguration.java	Mon Aug 21 16:44:08 2017 -0400
+++ b/common/core/src/main/java/com/redhat/thermostat/gateway/common/core/config/ServiceConfiguration.java	Wed Aug 23 08:34:51 2017 -0400
@@ -58,13 +58,17 @@
     }
 
     public enum ConfigurationKey {
+
         /**
-         * Set to {@code true} for basic authentication
+         * Set to {@code true} for BASIC authentication
+         * and authorization. Disabled if SECURITY_KEYCLOAK
+         * is also {@code true}
          */
         SECURITY_BASIC,
         /**
-         * Only useful together with SECURITY_BASIC.
-         * Specifies the users a service knows about.
+         * Specifies the users a service knows about for
+         * BASIC authentication and authorization. Only
+         * useful together with SECURITY_BASIC
          */
         SECURITY_BASIC_USERS,
         /**
@@ -74,9 +78,8 @@
         WEBSOCKETS,
 
         /**
-         * Set to {@code true} for keycloak authentication
-         * and authorization. Cannot be used along with
-         * {@link ConfigurationKey#SECURITY_BASIC}
+         * Set to {@code true} for Keycloak authentication
+         * and authorization. Disables Basic authentication
          */
         SECURITY_KEYCLOAK,
 
--- a/common/core/src/test/java/com/redhat/thermostat/gateway/common/core/auth/DefaultRealmAuthorizerTest.java	Mon Aug 21 16:44:08 2017 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,60 +0,0 @@
-/*
- * Copyright 2012-2017 Red Hat, Inc.
- *
- * This file is part of Thermostat.
- *
- * Thermostat is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published
- * by the Free Software Foundation; either version 2, or (at your
- * option) any later version.
- *
- * Thermostat is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Thermostat; see the file COPYING.  If not see
- * <http://www.gnu.org/licenses/>.
- *
- * Linking this code with other modules is making a combined work
- * based on this code.  Thus, the terms and conditions of the GNU
- * General Public License cover the whole combination.
- *
- * As a special exception, the copyright holders of this code give
- * you permission to link this code with independent modules to
- * produce an executable, regardless of the license terms of these
- * independent modules, and to copy and distribute the resulting
- * executable under terms of your choice, provided that you also
- * meet, for each linked independent module, the terms and conditions
- * of the license of that module.  An independent module is a module
- * which is not derived from or based on this code.  If you modify
- * this code, you may extend this exception to your version of the
- * library, but you are not obligated to do so.  If you do not wish
- * to do so, delete this exception statement from your version.
- */
-
-package com.redhat.thermostat.gateway.common.core.auth;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertTrue;
-
-import org.junit.Test;
-
-public class DefaultRealmAuthorizerTest {
-
-    @Test
-    public void testDefaultRoleExists() throws InvalidRoleException {
-        DefaultRealmAuthorizer realmAuthorizer = new DefaultRealmAuthorizer();
-
-        assertEquals(1, realmAuthorizer.clientRoles.size());
-
-        for (Role r : realmAuthorizer.clientRoles) {
-            assertEquals("thermostat", r.getRealm());
-            assertTrue(r.containsAction("r"));
-            assertTrue(r.containsAction("w"));
-            assertTrue(r.containsAction("u"));
-            assertTrue(r.containsAction("d"));
-        }
-    }
-}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/common/core/src/test/java/com/redhat/thermostat/gateway/common/core/auth/basic/BasicRealmAuthorizerTest.java	Wed Aug 23 08:34:51 2017 -0400
@@ -0,0 +1,73 @@
+/*
+ * Copyright 2012-2017 Red Hat, Inc.
+ *
+ * This file is part of Thermostat.
+ *
+ * Thermostat is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published
+ * by the Free Software Foundation; either version 2, or (at your
+ * option) any later version.
+ *
+ * Thermostat is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Thermostat; see the file COPYING.  If not see
+ * <http://www.gnu.org/licenses/>.
+ *
+ * Linking this code with other modules is making a combined work
+ * based on this code.  Thus, the terms and conditions of the GNU
+ * General Public License cover the whole combination.
+ *
+ * As a special exception, the copyright holders of this code give
+ * you permission to link this code with independent modules to
+ * produce an executable, regardless of the license terms of these
+ * independent modules, and to copy and distribute the resulting
+ * executable under terms of your choice, provided that you also
+ * meet, for each linked independent module, the terms and conditions
+ * of the license of that module.  An independent module is a module
+ * which is not derived from or based on this code.  If you modify
+ * this code, you may extend this exception to your version of the
+ * library, but you are not obligated to do so.  If you do not wish
+ * to do so, delete this exception statement from your version.
+ */
+
+package com.redhat.thermostat.gateway.common.core.auth.basic;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+import java.util.HashSet;
+import java.util.Set;
+
+import org.junit.Test;
+
+import com.redhat.thermostat.gateway.common.core.auth.InvalidRoleException;
+import com.redhat.thermostat.gateway.common.core.auth.Role;
+
+public class BasicRealmAuthorizerTest {
+
+    @Test
+    public void testDefaultRoleExists() throws InvalidRoleException {
+        BasicWebUser basicWebUser = mock(BasicWebUser.class);
+        Set<String> mockRoles = new HashSet<>();
+        mockRoles.add("r,w,u,d-thermostat");
+        when(basicWebUser.getRoles()).thenReturn(mockRoles);
+
+        BasicRealmAuthorizer realmAuthorizer = new BasicRealmAuthorizer(basicWebUser);
+
+        assertEquals(1, realmAuthorizer.getAllRoles().size());
+
+        for (Role r : realmAuthorizer.getAllRoles()) {
+            assertEquals("thermostat", r.getRealm());
+            assertTrue(r.containsAction("r"));
+            assertTrue(r.containsAction("w"));
+            assertTrue(r.containsAction("u"));
+            assertTrue(r.containsAction("d"));
+        }
+    }
+}
--- a/distribution/src/etc/basic-config.properties	Mon Aug 21 16:44:08 2017 -0400
+++ b/distribution/src/etc/basic-config.properties	Wed Aug 23 08:34:51 2017 -0400
@@ -1,1 +1,2 @@
-admin=password,thermostat-admin
\ No newline at end of file
+agent=agent-pwd,r-thermostat,w-thermostat,u-thermostat,d-thermostat
+client=client-pwd,r-thermostat
\ No newline at end of file
--- a/distribution/src/etc/global-config.properties	Mon Aug 21 16:44:08 2017 -0400
+++ b/distribution/src/etc/global-config.properties	Wed Aug 23 08:34:51 2017 -0400
@@ -5,6 +5,10 @@
 # The file specifying which services to deploy in the
 # servlet container.
 properties|SERVICES=services.properties
+# Sets auth scheme to BASIC
+SECURITY_BASIC=true
+# Specifies location of BASIC AUTH credentials
+properties|SECURITY_BASIC_USERS=basic-config.properties
 #
 # Specifies whether or not the swagger UI handler should get
 # created under context path /doc
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/server/src/main/java/com/redhat/thermostat/gateway/server/auth/BasicAuthFilter.java	Wed Aug 23 08:34:51 2017 -0400
@@ -0,0 +1,129 @@
+/*
+ * Copyright 2012-2017 Red Hat, Inc.
+ *
+ * This file is part of Thermostat.
+ *
+ * Thermostat is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published
+ * by the Free Software Foundation; either version 2, or (at your
+ * option) any later version.
+ *
+ * Thermostat is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Thermostat; see the file COPYING.  If not see
+ * <http://www.gnu.org/licenses/>.
+ *
+ * Linking this code with other modules is making a combined work
+ * based on this code.  Thus, the terms and conditions of the GNU
+ * General Public License cover the whole combination.
+ *
+ * As a special exception, the copyright holders of this code give
+ * you permission to link this code with independent modules to
+ * produce an executable, regardless of the license terms of these
+ * independent modules, and to copy and distribute the resulting
+ * executable under terms of your choice, provided that you also
+ * meet, for each linked independent module, the terms and conditions
+ * of the license of that module.  An independent module is a module
+ * which is not derived from or based on this code.  If you modify
+ * this code, you may extend this exception to your version of the
+ * library, but you are not obligated to do so.  If you do not wish
+ * to do so, delete this exception statement from your version.
+ */
+
+package com.redhat.thermostat.gateway.server.auth;
+
+import java.io.IOException;
+import java.nio.charset.Charset;
+
+import javax.servlet.Filter;
+import javax.servlet.FilterChain;
+import javax.servlet.FilterConfig;
+import javax.servlet.ServletException;
+import javax.servlet.ServletRequest;
+import javax.servlet.ServletResponse;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import javax.ws.rs.NotAuthorizedException;
+import javax.ws.rs.core.HttpHeaders;
+import javax.xml.bind.DatatypeConverter;
+
+import com.redhat.thermostat.gateway.common.core.auth.basic.BasicRealmAuthorizer;
+import com.redhat.thermostat.gateway.common.core.auth.InvalidRoleException;
+import com.redhat.thermostat.gateway.common.core.auth.RealmAuthorizer;
+import com.redhat.thermostat.gateway.server.auth.basic.BasicUserStore;
+import com.redhat.thermostat.gateway.common.core.auth.basic.BasicWebUser;
+
+public class BasicAuthFilter implements Filter {
+    private BasicUserStore userStore;
+
+    public BasicAuthFilter(BasicUserStore userStore) {
+        this.userStore = userStore;
+    }
+
+    @Override
+    public void init(FilterConfig filterConfig) throws ServletException {
+        // Do nothing
+    }
+
+    @Override
+    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
+        HttpServletRequest httpServletRequest = (HttpServletRequest) request;
+
+        String authentication = httpServletRequest.getHeader(HttpHeaders.AUTHORIZATION);
+        if (authentication == null) {
+            sendHttpUnauth(response);
+            return;
+        }
+
+        if (!authentication.startsWith("Basic ")) {
+            sendHttpUnauth(response);
+            return;
+        }
+
+        authentication = authentication.substring("Basic ".length());
+        String[] values = new String(DatatypeConverter.parseBase64Binary(authentication),
+                Charset.forName("ASCII")).split(":");
+        if (values.length < 2) {
+            sendHttpUnauth(response);
+            return;
+        }
+
+        String username = values[0];
+        String password = values[1];
+
+        BasicWebUser user = userStore.getUser(username);
+        if (user == null) {
+            sendHttpUnauth(response);
+            return;
+        }
+
+        if (!user.getPassword().equals(password)) {
+            sendHttpUnauth(response);
+            return;
+        }
+
+        try {
+            RealmAuthorizer realmAuthorizer = new BasicRealmAuthorizer(user);
+            httpServletRequest.setAttribute(RealmAuthorizer.class.getName(), realmAuthorizer);
+
+            chain.doFilter(request, response);
+        } catch (InvalidRoleException e) {
+            throw new IllegalStateException("Unable to create DefaultRealmAuthorizer", e);
+        }
+    }
+
+    private void sendHttpUnauth(ServletResponse response) throws IOException {
+        HttpServletResponse httpServletResponse = (HttpServletResponse) response;
+        httpServletResponse.setHeader("WWW-Authenticate", "Basic realm=\"thermostat\"");
+        httpServletResponse.sendError(HttpServletResponse.SC_UNAUTHORIZED);
+    }
+
+    @Override
+    public void destroy() {
+        // Do nothing
+    }
+}
--- a/server/src/main/java/com/redhat/thermostat/gateway/server/auth/DefaultAuthFilter.java	Mon Aug 21 16:44:08 2017 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,81 +0,0 @@
-/*
- * Copyright 2012-2017 Red Hat, Inc.
- *
- * This file is part of Thermostat.
- *
- * Thermostat is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published
- * by the Free Software Foundation; either version 2, or (at your
- * option) any later version.
- *
- * Thermostat is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Thermostat; see the file COPYING.  If not see
- * <http://www.gnu.org/licenses/>.
- *
- * Linking this code with other modules is making a combined work
- * based on this code.  Thus, the terms and conditions of the GNU
- * General Public License cover the whole combination.
- *
- * As a special exception, the copyright holders of this code give
- * you permission to link this code with independent modules to
- * produce an executable, regardless of the license terms of these
- * independent modules, and to copy and distribute the resulting
- * executable under terms of your choice, provided that you also
- * meet, for each linked independent module, the terms and conditions
- * of the license of that module.  An independent module is a module
- * which is not derived from or based on this code.  If you modify
- * this code, you may extend this exception to your version of the
- * library, but you are not obligated to do so.  If you do not wish
- * to do so, delete this exception statement from your version.
- */
-
-package com.redhat.thermostat.gateway.server.auth;
-
-import java.io.IOException;
-
-import javax.servlet.Filter;
-import javax.servlet.FilterChain;
-import javax.servlet.FilterConfig;
-import javax.servlet.ServletException;
-import javax.servlet.ServletRequest;
-import javax.servlet.ServletResponse;
-import javax.servlet.http.HttpServletRequest;
-
-import com.redhat.thermostat.gateway.common.core.auth.DefaultRealmAuthorizer;
-import com.redhat.thermostat.gateway.common.core.auth.InvalidRoleException;
-import com.redhat.thermostat.gateway.common.core.auth.RealmAuthorizer;
-
-public class DefaultAuthFilter implements Filter {
-    private RealmAuthorizer realmAuthorizer;
-
-    public DefaultAuthFilter() {
-        try {
-            realmAuthorizer = new DefaultRealmAuthorizer();
-        } catch (InvalidRoleException e) {
-            throw new IllegalStateException("Unable to create DefaultRealmAuthorizer", e);
-        }
-    }
-
-    @Override
-    public void init(FilterConfig filterConfig) throws ServletException {
-        // Do nothing
-    }
-
-    @Override
-    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
-        HttpServletRequest httpServletRequest = (HttpServletRequest) request;
-        httpServletRequest.setAttribute(RealmAuthorizer.class.getName(), realmAuthorizer);
-
-        chain.doFilter(request, response);
-    }
-
-    @Override
-    public void destroy() {
-        // Do nothing
-    }
-}
--- a/server/src/main/java/com/redhat/thermostat/gateway/server/auth/basic/BasicLoginService.java	Mon Aug 21 16:44:08 2017 -0400
+++ b/server/src/main/java/com/redhat/thermostat/gateway/server/auth/basic/BasicLoginService.java	Wed Aug 23 08:34:51 2017 -0400
@@ -46,6 +46,8 @@
 import org.eclipse.jetty.security.LoginService;
 import org.eclipse.jetty.server.UserIdentity;
 
+import com.redhat.thermostat.gateway.common.core.auth.basic.BasicWebUser;
+
 public class BasicLoginService implements LoginService {
 
     private final BasicUserStore store;
@@ -64,7 +66,7 @@
 
     @Override
     public UserIdentity login(final String username, Object credentials) {
-        BasicWebUser user = (BasicWebUser)store.getUser(username);
+        BasicWebUser user = store.getUser(username);
         if (user == null) {
             return null;
         }
--- a/server/src/main/java/com/redhat/thermostat/gateway/server/auth/basic/BasicUserStore.java	Mon Aug 21 16:44:08 2017 -0400
+++ b/server/src/main/java/com/redhat/thermostat/gateway/server/auth/basic/BasicUserStore.java	Wed Aug 23 08:34:51 2017 -0400
@@ -42,11 +42,11 @@
 import java.util.HashSet;
 import java.util.Map;
 
-import com.redhat.thermostat.gateway.common.core.auth.basic.RoleAwareUser;
+import com.redhat.thermostat.gateway.common.core.auth.basic.BasicWebUser;
 
 public class BasicUserStore {
 
-    private final Map<String, RoleAwareUser> users = new HashMap<>();
+    private final Map<String, BasicWebUser> users = new HashMap<>();
 
     public BasicUserStore(Map<String, String> userConfig) {
         for (Map.Entry<String, String> entry : userConfig.entrySet()) {
@@ -57,7 +57,7 @@
         }
     }
 
-    public RoleAwareUser getUser(String userName) {
+    public BasicWebUser getUser(String userName) {
         return users.get(userName);
     }
 }
--- a/server/src/main/java/com/redhat/thermostat/gateway/server/auth/basic/BasicWebUser.java	Mon Aug 21 16:44:08 2017 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,71 +0,0 @@
-/*
- * Copyright 2012-2017 Red Hat, Inc.
- *
- * This file is part of Thermostat.
- *
- * Thermostat is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published
- * by the Free Software Foundation; either version 2, or (at your
- * option) any later version.
- *
- * Thermostat is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Thermostat; see the file COPYING.  If not see
- * <http://www.gnu.org/licenses/>.
- *
- * Linking this code with other modules is making a combined work
- * based on this code.  Thus, the terms and conditions of the GNU
- * General Public License cover the whole combination.
- *
- * As a special exception, the copyright holders of this code give
- * you permission to link this code with independent modules to
- * produce an executable, regardless of the license terms of these
- * independent modules, and to copy and distribute the resulting
- * executable under terms of your choice, provided that you also
- * meet, for each linked independent module, the terms and conditions
- * of the license of that module.  An independent module is a module
- * which is not derived from or based on this code.  If you modify
- * this code, you may extend this exception to your version of the
- * library, but you are not obligated to do so.  If you do not wish
- * to do so, delete this exception statement from your version.
- */
-
-package com.redhat.thermostat.gateway.server.auth.basic;
-
-import java.util.Set;
-
-import com.redhat.thermostat.gateway.common.core.auth.basic.RoleAwareUser;
-
-public class BasicWebUser implements RoleAwareUser {
-    private final String username;
-    private final Set<String> roles;
-    private final char[] password;
-
-    public BasicWebUser(String username, char[] password, Set<String> roles) {
-        this.username = username;
-        this.roles = roles;
-        this.password = password;
-    }
-
-    @Override
-    public String getName() {
-        return this.username;
-    }
-
-    @Override
-    public boolean isUserInRole(String role) {
-        return this.roles.contains(role);
-    }
-
-    public String getPassword() {
-        return new String(password);
-    }
-
-    public Set<String> getRoles() {
-        return roles;
-    }
-}
--- a/server/src/main/java/com/redhat/thermostat/gateway/server/services/WebArchiveCoreService.java	Mon Aug 21 16:44:08 2017 -0400
+++ b/server/src/main/java/com/redhat/thermostat/gateway/server/services/WebArchiveCoreService.java	Wed Aug 23 08:34:51 2017 -0400
@@ -50,6 +50,7 @@
 import org.eclipse.jetty.security.LoginService;
 import org.eclipse.jetty.security.SecurityHandler;
 import org.eclipse.jetty.server.Server;
+import org.eclipse.jetty.servlet.FilterHolder;
 import org.eclipse.jetty.servlet.ServletContextHandler;
 import org.eclipse.jetty.util.security.Constraint;
 import org.eclipse.jetty.webapp.WebAppContext;
@@ -57,9 +58,10 @@
 import org.keycloak.adapters.jetty.KeycloakJettyAuthenticator;
 
 import com.redhat.thermostat.gateway.common.core.config.Configuration;
+import com.redhat.thermostat.gateway.common.core.config.IllegalConfigurationException;
 import com.redhat.thermostat.gateway.common.core.config.ServiceConfiguration;
 import com.redhat.thermostat.gateway.common.core.servlet.GlobalConstants;
-import com.redhat.thermostat.gateway.server.auth.DefaultAuthFilter;
+import com.redhat.thermostat.gateway.server.auth.BasicAuthFilter;
 import com.redhat.thermostat.gateway.server.auth.basic.BasicLoginService;
 import com.redhat.thermostat.gateway.server.auth.basic.BasicUserStore;
 import com.redhat.thermostat.gateway.server.auth.keycloak.KeycloakConfiguration;
@@ -98,18 +100,28 @@
     }
 
 
-    private void setupAuthForContext(WebAppContext webAppContext) {
-        if (isSet(ServiceConfiguration.ConfigurationKey.SECURITY_BASIC)) {
+    private void setupAuthForContext(WebAppContext webAppContext) throws IllegalConfigurationException {
+        // Check Keycloak first as it has higher priority. Only one auth scheme allowed
+        if (isSet(ServiceConfiguration.ConfigurationKey.SECURITY_KEYCLOAK)) {
+            setupKeycloakAuthForContext(webAppContext);
+        } else if (isSet(ServiceConfiguration.ConfigurationKey.SECURITY_BASIC)) {
             setupBasicAuthForContext(webAppContext);
-        } else if (isSet(ServiceConfiguration.ConfigurationKey.SECURITY_KEYCLOAK)) {
-            setupKeycloakAuthForContext(webAppContext);
         } else {
-            setupDefaultAuthForContext(webAppContext);
+            throw new IllegalConfigurationException("No auth scheme specified.");
         }
     }
 
-    private void setupDefaultAuthForContext(WebAppContext webAppContext) {
-        webAppContext.addFilter(DefaultAuthFilter.class, "/*", EnumSet.of(DispatcherType.REQUEST));
+    private void setupBasicAuthForContext(WebAppContext webAppContext) {
+        Map<String, String> userConfig = getBasicAuthUserConfig();
+        BasicUserStore userStore = new BasicUserStore(userConfig);
+        BasicAuthFilter basicAuthFilter = new BasicAuthFilter(userStore);
+        FilterHolder filterHolder = new FilterHolder(basicAuthFilter);
+
+        webAppContext.addFilter(filterHolder, "/*", EnumSet.of(DispatcherType.REQUEST));
+
+        SecurityHandler security = webAppContext.getSecurityHandler();
+        LoginService loginService = new BasicLoginService(userStore, security.getRealmName());
+        security.setLoginService(loginService);
     }
 
     private void setupKeycloakAuthForContext(WebAppContext webAppContext) {
@@ -141,14 +153,6 @@
         webAppContext.addFilter(KeycloakRequestFilter.class, "/*", EnumSet.of(DispatcherType.REQUEST));
     }
 
-    private void setupBasicAuthForContext(WebAppContext webAppContext) {
-        Map<String, String> userConfig = getBasicAuthUserConfig();
-        SecurityHandler security = webAppContext.getSecurityHandler();
-        BasicUserStore userStore = new BasicUserStore(userConfig);
-        LoginService loginService = new BasicLoginService(userStore, security.getRealmName());
-        security.setLoginService(loginService);
-    }
-
     @SuppressWarnings("unchecked")
     private Map<String, String> getBasicAuthUserConfig() {
         if (serviceConfig.asMap().containsKey(ServiceConfiguration.ConfigurationKey.SECURITY_BASIC_USERS.name())) {
--- a/server/src/test/java/com/redhat/thermostat/gateway/server/services/WebArchiveCoreServiceTest.java	Mon Aug 21 16:44:08 2017 -0400
+++ b/server/src/test/java/com/redhat/thermostat/gateway/server/services/WebArchiveCoreServiceTest.java	Wed Aug 23 08:34:51 2017 -0400
@@ -58,6 +58,8 @@
 import org.keycloak.adapters.jetty.KeycloakJettyAuthenticator;
 
 import com.redhat.thermostat.gateway.common.core.config.Configuration;
+import com.redhat.thermostat.gateway.common.core.config.GlobalConfiguration;
+import com.redhat.thermostat.gateway.common.core.config.IllegalConfigurationException;
 import com.redhat.thermostat.gateway.common.core.config.ServiceConfiguration;
 import com.redhat.thermostat.gateway.common.core.servlet.GlobalConstants;
 import com.redhat.thermostat.gateway.server.auth.basic.BasicLoginService;
@@ -75,9 +77,22 @@
             "  \"resource\": \"thermostat-bearer\"\n" +
             "}";
 
+    @Test(expected = IllegalConfigurationException.class)
+    public void testNoAuthException() {
+        Map<String, Object> configurationMap = new HashMap<>();
+
+        Configuration configuration = mock(Configuration.class);
+        when(configuration.asMap()).thenReturn(configurationMap);
+
+        WebArchiveCoreService service = new WebArchiveCoreService(contextPath, warPath, configuration);
+
+        service.createServletContextHandler(mock(Server.class));
+    }
+
     @Test
     public void testBasicService() {
         Map<String, Object> configurationMap = new HashMap<>();
+        configurationMap.put(ServiceConfiguration.ConfigurationKey.SECURITY_BASIC.name(), "true");
 
         Configuration configuration = mock(Configuration.class);
         when(configuration.asMap()).thenReturn(configurationMap);
@@ -96,6 +111,7 @@
     @Test
     public void testServiceConfigIsAdded() {
         Map<String, Object> configurationMap = new HashMap<>();
+        configurationMap.put(ServiceConfiguration.ConfigurationKey.SECURITY_BASIC.name(), "true");
 
         Configuration configuration = mock(Configuration.class);
         when(configuration.asMap()).thenReturn(configurationMap);
@@ -172,6 +188,7 @@
     @Test
     public void testServiceWithWebSockets() {
         Map<String, Object> configurationMap = new HashMap<>();
+        configurationMap.put(ServiceConfiguration.ConfigurationKey.SECURITY_BASIC.name(), "true");
         configurationMap.put(ServiceConfiguration.ConfigurationKey.WEBSOCKETS.name(), "true");
         Configuration configuration = mock(Configuration.class);
         when(configuration.asMap()).thenReturn(configurationMap);
--- a/tests/integration-tests/src/test/java/com/redhat/thermostat/gateway/service/jvm/gc/JvmGcServiceIntegrationTest.java	Mon Aug 21 16:44:08 2017 -0400
+++ b/tests/integration-tests/src/test/java/com/redhat/thermostat/gateway/service/jvm/gc/JvmGcServiceIntegrationTest.java	Wed Aug 23 08:34:51 2017 -0400
@@ -46,7 +46,7 @@
 import java.util.concurrent.ExecutionException;
 import java.util.concurrent.TimeoutException;
 
-import com.redhat.thermostat.gateway.common.core.auth.DefaultRealmAuthorizer;
+import com.redhat.thermostat.gateway.common.core.auth.basic.BasicRealmAuthorizer;
 import com.redhat.thermostat.gateway.common.mongodb.servlet.RequestParameters;
 import com.redhat.thermostat.gateway.tests.integration.MongoIntegrationTest;
 import org.bson.Document;
@@ -413,7 +413,7 @@
         documents.forEach(new Block<Document>() {
             @Override
             public void apply(Document document) {
-                assertEquals(getRealmArray(DefaultRealmAuthorizer.DEFAULT_REALM), gson.toJson(document.get("realms"), listType));
+                assertEquals(getRealmArray(BasicRealmAuthorizer.DEFAULT_REALM), gson.toJson(document.get("realms"), listType));
             }
         });
     }
@@ -466,7 +466,7 @@
         documents.forEach(new Block<Document>() {
             @Override
             public void apply(Document document) {
-                assertEquals(getRealmArray(DefaultRealmAuthorizer.DEFAULT_REALM), gson.toJson(document.get("realms"), listType));
+                assertEquals(getRealmArray(BasicRealmAuthorizer.DEFAULT_REALM), gson.toJson(document.get("realms"), listType));
             }
         });
     }
@@ -502,7 +502,7 @@
 
 
         ContentResponse response = client.newRequest(gcUrl)
-                .param(RequestParameters.QUERY, "realms==" + getRealmArray(DefaultRealmAuthorizer.DEFAULT_REALM))
+                .param(RequestParameters.QUERY, "realms==" + getRealmArray(BasicRealmAuthorizer.DEFAULT_REALM))
                 .method(HttpMethod.GET).send();
 
         assertEquals(400, response.getStatus());
@@ -524,7 +524,7 @@
         documents.forEach(new Block<Document>() {
             @Override
             public void apply(Document document) {
-                assertEquals(getRealmArray(DefaultRealmAuthorizer.DEFAULT_REALM), gson.toJson(document.get("realms"), listType));
+                assertEquals(getRealmArray(BasicRealmAuthorizer.DEFAULT_REALM), gson.toJson(document.get("realms"), listType));
             }
         });
     }
--- a/tests/integration-tests/src/test/java/com/redhat/thermostat/gateway/tests/integration/IntegrationTest.java	Mon Aug 21 16:44:08 2017 -0400
+++ b/tests/integration-tests/src/test/java/com/redhat/thermostat/gateway/tests/integration/IntegrationTest.java	Wed Aug 23 08:34:51 2017 -0400
@@ -37,11 +37,14 @@
 package com.redhat.thermostat.gateway.tests.integration;
 
 import java.io.IOException;
+import java.net.URI;
 import java.nio.file.Path;
 import java.nio.file.Paths;
 import java.util.concurrent.CountDownLatch;
 
 import org.eclipse.jetty.client.HttpClient;
+import org.eclipse.jetty.client.api.AuthenticationStore;
+import org.eclipse.jetty.client.util.BasicAuthentication;
 import org.eclipse.jetty.util.component.AbstractLifeCycle;
 import org.eclipse.jetty.util.component.LifeCycle;
 import org.eclipse.jetty.util.ssl.SslContextFactory;
@@ -100,6 +103,9 @@
         } else {
             theclient = new HttpClient();
         }
+        AuthenticationStore authenticationStore = theclient.getAuthenticationStore();
+        URI uri = URI.create(baseUrl);
+        authenticationStore.addAuthentication(new BasicAuthentication(uri, "thermostat", "agent", "agent-pwd"));
         theclient.start();
         return theclient;
     }