Mercurial > hg > thermostat-ng > web-gateway
changeset 233:f872349e7038
Align all microservices for BASIC auth.
Reviewed-by: jkang
Review-thread: http://icedtea.classpath.org/pipermail/thermostat/2017-August/024649.html
line wrap: on
line diff
--- a/common/core/src/main/java/com/redhat/thermostat/gateway/common/core/auth/basic/BasicRealmAuthorizer.java Wed Aug 23 08:34:51 2017 -0400 +++ b/common/core/src/main/java/com/redhat/thermostat/gateway/common/core/auth/basic/BasicRealmAuthorizer.java Wed Aug 23 13:43:11 2017 +0200 @@ -44,18 +44,21 @@ 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 { + public BasicRealmAuthorizer(BasicWebUser user) { RoleFactory roleFactory = new RoleFactory(); Set<Role> roles = new HashSet<>(); for (String role : user.getRoles()) { - Role r = roleFactory.buildRole(role); - roles.add(r); + try { + Role r = roleFactory.buildRole(role); + roles.add(r); + } catch (InvalidRoleException e) { + // ignore role + } } clientRoles = Collections.unmodifiableSet(roles);
--- a/distribution/src/etc/basic-config.properties Wed Aug 23 08:34:51 2017 -0400 +++ b/distribution/src/etc/basic-config.properties Wed Aug 23 13:43:11 2017 +0200 @@ -1,2 +1,2 @@ -agent=agent-pwd,r-thermostat,w-thermostat,u-thermostat,d-thermostat -client=client-pwd,r-thermostat \ No newline at end of file +agent=agent-pwd,r-thermostat,w-thermostat,u-thermostat,d-thermostat,receiver_provider-commands,thermostat +client=client-pwd,r-thermostat,kill_vm-commands,ping-commands,thermostat \ No newline at end of file
--- a/server/src/main/java/com/redhat/thermostat/gateway/server/auth/BasicAuthFilter.java Wed Aug 23 08:34:51 2017 -0400 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,129 +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 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 - } -}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/server/src/main/java/com/redhat/thermostat/gateway/server/auth/basic/BasicAuthFilter.java Wed Aug 23 13:43:11 2017 +0200 @@ -0,0 +1,81 @@ +/* + * 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.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.RealmAuthorizer; +import com.redhat.thermostat.gateway.common.core.auth.basic.BasicRealmAuthorizer; +import com.redhat.thermostat.gateway.common.core.auth.basic.BasicWebUser; + +public class BasicAuthFilter implements Filter { + + @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; + + BasicWebUser user = (BasicWebUser)httpServletRequest.getUserPrincipal(); + RealmAuthorizer realmAuthorizer; + if (user == null) { + realmAuthorizer = new RealmAuthorizer() {}; // Deny-all realm authorizer + } else { + realmAuthorizer = new BasicRealmAuthorizer(user); + } + + 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/services/WebArchiveCoreService.java Wed Aug 23 08:34:51 2017 -0400 +++ b/server/src/main/java/com/redhat/thermostat/gateway/server/services/WebArchiveCoreService.java Wed Aug 23 13:43:11 2017 +0200 @@ -47,8 +47,7 @@ import org.eclipse.jetty.security.ConstraintMapping; import org.eclipse.jetty.security.ConstraintSecurityHandler; -import org.eclipse.jetty.security.LoginService; -import org.eclipse.jetty.security.SecurityHandler; +import org.eclipse.jetty.security.authentication.BasicAuthenticator; import org.eclipse.jetty.server.Server; import org.eclipse.jetty.servlet.FilterHolder; import org.eclipse.jetty.servlet.ServletContextHandler; @@ -61,7 +60,7 @@ 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.BasicAuthFilter; +import com.redhat.thermostat.gateway.server.auth.basic.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; @@ -70,6 +69,9 @@ class WebArchiveCoreService implements CoreService { + // Users need to be in at least this role for authentication to succeed. + // This applies for keycloak and basic. + private static final String AUTH_ACCESS_ROLE = "thermostat"; private final String contextPath; private final String warPath; private final Configuration serviceConfig; @@ -113,15 +115,25 @@ 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); + ConstraintSecurityHandler security = new ConstraintSecurityHandler(); + String realmName = "Thermostat Realm"; // must match name of login service + Constraint cons = new Constraint(); + cons.setName(realmName); + cons.setRoles(new String[] { AUTH_ACCESS_ROLE }); + cons.setAuthenticate(true); + cons.setDataConstraint(Constraint.DC_CONFIDENTIAL); + ConstraintMapping mapping = new ConstraintMapping(); + mapping.setConstraint(cons); + mapping.setMethodOmissions(new String[] {}); + mapping.setPathSpec("/*"); + security.setConstraintMappings(Collections.singletonList(mapping)); + security.setAuthenticator(new BasicAuthenticator()); + security.setLoginService(new BasicLoginService(new BasicUserStore(userConfig), realmName)); + webAppContext.setSecurityHandler(security); + // Add the realm authorizer + FilterHolder filterHolder = new FilterHolder(new 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) { @@ -137,7 +149,7 @@ Constraint constraint = new Constraint(); constraint.setName(Constraint.__BASIC_AUTH); - constraint.setRoles(new String[]{"thermostat"}); + constraint.setRoles(new String[]{ AUTH_ACCESS_ROLE }); constraint.setAuthenticate(true); ConstraintMapping constraintMapping = new ConstraintMapping();
--- a/server/src/test/java/com/redhat/thermostat/gateway/server/services/WebArchiveCoreServiceTest.java Wed Aug 23 08:34:51 2017 -0400 +++ b/server/src/test/java/com/redhat/thermostat/gateway/server/services/WebArchiveCoreServiceTest.java Wed Aug 23 13:43:11 2017 +0200 @@ -58,7 +58,6 @@ 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;
--- a/services/commands/etc/commands/basic-users.properties Wed Aug 23 08:34:51 2017 -0400 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,5 +0,0 @@ -# Agent user(s) -foo-agent-user=agent-pwd,thermostat-commands-realm,thermostat-commands-receiver-provider -agent-user=agent-pwd,thermostat-commands-realm,thermostat-commands-receiver-provider -# Client user -bar-client-user=client-pwd,thermostat-commands-realm,thermostat-commands-grant-kill_vm,thermostat-commands-grant-ping
--- a/services/commands/etc/commands/service-config.properties Wed Aug 23 08:34:51 2017 -0400 +++ b/services/commands/etc/commands/service-config.properties Wed Aug 23 13:43:11 2017 +0200 @@ -1,3 +1,1 @@ -SECURITY_BASIC=true -properties|SECURITY_BASIC_USERS=basic-users.properties WEBSOCKETS=true \ No newline at end of file
--- a/services/commands/pom.xml Wed Aug 23 08:34:51 2017 -0400 +++ b/services/commands/pom.xml Wed Aug 23 13:43:11 2017 +0200 @@ -51,12 +51,25 @@ <name>Thermostat Web Gateway Command Channel Service</name> <properties> + <com.redhat.thermostat.gateway.SERVICE_NAME>commands</com.redhat.thermostat.gateway.SERVICE_NAME> + <!-- Needed for the plugin config assembly --> <thermostat.microservice.name>commands</thermostat.microservice.name> </properties> <build> <plugins> <plugin> + <artifactId>maven-war-plugin</artifactId> + <configuration> + <webResources> + <resource> + <directory>src/main/webapp</directory> + <filtering>true</filtering> + </resource> + </webResources> + </configuration> + </plugin> + <plugin> <artifactId>maven-assembly-plugin</artifactId> <version>3.0.0</version> <dependencies>
--- a/services/commands/src/main/java/com/redhat/thermostat/gateway/service/commands/http/handlers/CommandChannelAgentEndpointHandler.java Wed Aug 23 08:34:51 2017 -0400 +++ b/services/commands/src/main/java/com/redhat/thermostat/gateway/service/commands/http/handlers/CommandChannelAgentEndpointHandler.java Wed Aug 23 13:43:11 2017 +0200 @@ -58,7 +58,8 @@ @ServerEndpoint( value = "/v1/systems/{systemId}/agents/{agentId}", encoders = { AgentRequestEncoder.class, WebSocketResponseEncoder.class }, - decoders = { MessageDecoder.class } + decoders = { MessageDecoder.class }, + configurator = RealmAuthorizerConfigurator.class ) public class CommandChannelAgentEndpointHandler extends CommandChannelEndpointHandler {
--- a/services/commands/src/main/java/com/redhat/thermostat/gateway/service/commands/http/handlers/CommandChannelClientEndpointHandler.java Wed Aug 23 08:34:51 2017 -0400 +++ b/services/commands/src/main/java/com/redhat/thermostat/gateway/service/commands/http/handlers/CommandChannelClientEndpointHandler.java Wed Aug 23 13:43:11 2017 +0200 @@ -61,7 +61,8 @@ @ServerEndpoint( value = "/v1/actions/{action}/systems/{systemId}/agents/{agentId}/jvms/{jvmId}/sequence/{seqId}", encoders = { AgentRequestEncoder.class, WebSocketResponseEncoder.class }, - decoders = { MessageDecoder.class } + decoders = { MessageDecoder.class }, + configurator = RealmAuthorizerConfigurator.class ) public class CommandChannelClientEndpointHandler extends CommandChannelEndpointHandler {
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/services/commands/src/main/java/com/redhat/thermostat/gateway/service/commands/http/handlers/RealmAuthorizerConfigurator.java Wed Aug 23 13:43:11 2017 +0200 @@ -0,0 +1,62 @@ +/* + * 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.service.commands.http.handlers; + +import javax.websocket.HandshakeResponse; +import javax.websocket.server.HandshakeRequest; +import javax.websocket.server.ServerEndpointConfig; +import javax.websocket.server.ServerEndpointConfig.Configurator; + +import com.redhat.thermostat.gateway.common.core.auth.RealmAuthorizer; +import com.redhat.thermostat.gateway.common.core.auth.basic.BasicRealmAuthorizer; +import com.redhat.thermostat.gateway.common.core.auth.basic.BasicWebUser; + +public class RealmAuthorizerConfigurator extends Configurator { + + @Override + public void modifyHandshake(ServerEndpointConfig config, HandshakeRequest request, HandshakeResponse response) { + // FIXME: Set up proper realm authorizer based on config + BasicWebUser user = (BasicWebUser)request.getUserPrincipal(); + RealmAuthorizer realmAuthorizer; + if (user == null) { + realmAuthorizer = new RealmAuthorizer() {}; // deny-all authorizer + } else { + realmAuthorizer = new BasicRealmAuthorizer(user); + } + config.getUserProperties().put(RealmAuthorizer.class.getName(), realmAuthorizer); + } +}
--- a/services/commands/src/main/java/com/redhat/thermostat/gateway/service/commands/socket/CommandChannelAgentSocket.java Wed Aug 23 08:34:51 2017 -0400 +++ b/services/commands/src/main/java/com/redhat/thermostat/gateway/service/commands/socket/CommandChannelAgentSocket.java Wed Aug 23 13:43:11 2017 +0200 @@ -39,6 +39,7 @@ import java.io.IOException; import java.io.UnsupportedEncodingException; import java.nio.ByteBuffer; +import java.util.Set; import java.util.concurrent.TimeUnit; import java.util.logging.Level; import java.util.logging.Logger; @@ -46,7 +47,7 @@ import javax.websocket.PongMessage; import javax.websocket.Session; -import com.redhat.thermostat.gateway.common.core.auth.basic.RoleAwareUser; +import com.redhat.thermostat.gateway.common.core.auth.RealmAuthorizer; import com.redhat.thermostat.gateway.common.util.LoggingUtil; import com.redhat.thermostat.gateway.service.commands.channel.ClientAgentCommunication; import com.redhat.thermostat.gateway.service.commands.channel.CommunicationsRegistry; @@ -58,7 +59,7 @@ private static final Logger logger = LoggingUtil.getLogger(CommandChannelAgentSocket.class); private static final long SOCKET_SESSION_IDLE_TIMEOUT = TimeUnit.MINUTES.toMillis(10); private static final String UNKNOWN_PAYLOAD = "UNKNOWN"; - private static final String RECEIVER_PROVIDER_ROLE = "thermostat-commands-receiver-provider"; + private static final String RECEIVER_PROVIDER_ACTION = "receiver_provider"; CommandChannelAgentSocket(String id, Session session) { super(id, session); @@ -136,9 +137,9 @@ @Override protected boolean checkRoles() { - // FIXME: relies on RoleAwareUser - i.e. specific auth scheme. - RoleAwareUser user = (RoleAwareUser) session.getUserPrincipal(); - if (!user.isUserInRole(RECEIVER_PROVIDER_ROLE)) { + RealmAuthorizer realmAuthorizer = (RealmAuthorizer)session.getUserProperties().get(RealmAuthorizer.class.getName()); + Set<String> receiverProviderActions = realmAuthorizer.getRealmsWithAction(RECEIVER_PROVIDER_ACTION); + if (!receiverProviderActions.contains(COMMANDS_REALM)) { return false; } return true;
--- a/services/commands/src/main/java/com/redhat/thermostat/gateway/service/commands/socket/CommandChannelClientSocket.java Wed Aug 23 08:34:51 2017 -0400 +++ b/services/commands/src/main/java/com/redhat/thermostat/gateway/service/commands/socket/CommandChannelClientSocket.java Wed Aug 23 13:43:11 2017 +0200 @@ -37,12 +37,13 @@ package com.redhat.thermostat.gateway.service.commands.socket; import java.io.IOException; +import java.util.Set; import javax.websocket.EncodeException; import javax.websocket.RemoteEndpoint.Basic; import javax.websocket.Session; -import com.redhat.thermostat.gateway.common.core.auth.basic.RoleAwareUser; +import com.redhat.thermostat.gateway.common.core.auth.RealmAuthorizer; import com.redhat.thermostat.gateway.service.commands.channel.ClientAgentCommunication; import com.redhat.thermostat.gateway.service.commands.channel.CommunicationsRegistry; import com.redhat.thermostat.gateway.service.commands.channel.WebSocketCommunicationBuilder; @@ -53,7 +54,6 @@ class CommandChannelClientSocket extends CommandChannelSocket { - private static final String CLIENT_GRANT_ACTION_PREFIX = "thermostat-commands-grant-"; private static final String PATH_PARAM_ACTION = "action"; private static final String PATH_PARAM_SYSTEM_ID = "systemId"; private static final String PATH_PARAM_JVM_ID = "jvmId"; @@ -112,11 +112,10 @@ @Override protected boolean checkRoles() { - // FIXME: relies on RoleAwareUser - i.e. specific auth scheme. - RoleAwareUser user = (RoleAwareUser) session.getUserPrincipal(); + RealmAuthorizer realmAuthorizer = (RealmAuthorizer)session.getUserProperties().get(RealmAuthorizer.class.getName()); String action = session.getPathParameters().get(PATH_PARAM_ACTION); - String actionAllowedRole = CLIENT_GRANT_ACTION_PREFIX + action; - if (!user.isUserInRole(actionAllowedRole)) { + Set<String> actionRealms = realmAuthorizer.getRealmsWithAction(action); + if (!actionRealms.contains(COMMANDS_REALM)) { return false; } // TODO: Add roles checks for systemId/jvmId, both part of the
--- a/services/commands/src/main/java/com/redhat/thermostat/gateway/service/commands/socket/CommandChannelWebSocket.java Wed Aug 23 08:34:51 2017 -0400 +++ b/services/commands/src/main/java/com/redhat/thermostat/gateway/service/commands/socket/CommandChannelWebSocket.java Wed Aug 23 13:43:11 2017 +0200 @@ -44,6 +44,8 @@ public interface CommandChannelWebSocket { + String COMMANDS_REALM = "commands"; + void onClose(int code, String message); void onConnect() throws IOException;
--- a/services/commands/src/main/webapp/WEB-INF/web.xml Wed Aug 23 08:34:51 2017 -0400 +++ b/services/commands/src/main/webapp/WEB-INF/web.xml Wed Aug 23 13:43:11 2017 +0200 @@ -60,30 +60,12 @@ <listener> <listener-class>com.redhat.thermostat.gateway.service.commands.servlet.SocketRegistrationListener</listener-class> </listener> - <security-constraint> - <web-resource-collection> - <web-resource-name>All of commands API</web-resource-name> - <url-pattern>/*</url-pattern> - </web-resource-collection> - <auth-constraint> - <role-name>thermostat-commands-realm</role-name> - </auth-constraint> - </security-constraint> - <!-- Allow viewing of API json spec without authentication --> + <!-- Allow viewing of API spec without authentication --> <security-constraint> <web-resource-collection> <web-resource-name>Swagger API SPEC YAML File</web-resource-name> - <url-pattern>/v1/static/doc/commands-swagger.yaml</url-pattern> + <url-pattern>/v1/static/doc/@com.redhat.thermostat.gateway.SERVICE_NAME@-swagger.yaml</url-pattern> </web-resource-collection> <!-- Explicitly no auth constraint for this file --> </security-constraint> - - <login-config> - <auth-method>BASIC</auth-method> - <realm-name>Commands Realm</realm-name> - </login-config> - - <security-role> - <role-name>thermostat-commands-realm</role-name> - </security-role> </web-app>
--- a/services/commands/src/test/java/com/redhat/thermostat/gateway/service/commands/http/handlers/AuthBasicCoreServerTest.java Wed Aug 23 08:34:51 2017 -0400 +++ b/services/commands/src/test/java/com/redhat/thermostat/gateway/service/commands/http/handlers/AuthBasicCoreServerTest.java Wed Aug 23 13:43:11 2017 +0200 @@ -146,8 +146,8 @@ protected static Map<String, String> getUserConfig() { Map<String, String> userConfig = new HashMap<>(); - userConfig.put("foo-agent-user", "agent-pwd,thermostat-commands-receiver-provider"); - userConfig.put("bar-client-user", "client-pwd,thermostat-commands-grant-dump-heap"); + userConfig.put("foo-agent-user", "agent-pwd,receiver_provider-commands"); + userConfig.put("bar-client-user", "client-pwd,dump_heap-commands"); userConfig.put("insufficient-roles-agent", "agent-pwd"); userConfig.put("insufficient-roles-client", "client-pwd"); return userConfig;
--- a/services/commands/src/test/java/com/redhat/thermostat/gateway/service/commands/http/handlers/CommandChannelEndpointHandlerTest.java Wed Aug 23 08:34:51 2017 -0400 +++ b/services/commands/src/test/java/com/redhat/thermostat/gateway/service/commands/http/handlers/CommandChannelEndpointHandlerTest.java Wed Aug 23 13:43:11 2017 +0200 @@ -46,13 +46,6 @@ import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicInteger; -import com.redhat.thermostat.gateway.service.commands.channel.coders.typeadapters.MessageTypeAdapterFactory; -import com.redhat.thermostat.gateway.service.commands.channel.model.AgentRequest; -import com.redhat.thermostat.gateway.service.commands.channel.model.ClientRequest; -import com.redhat.thermostat.gateway.service.commands.channel.model.Message; -import com.redhat.thermostat.gateway.service.commands.channel.model.Message.MessageType; -import com.redhat.thermostat.gateway.service.commands.channel.model.WebSocketResponse; -import com.redhat.thermostat.gateway.service.commands.channel.model.WebSocketResponse.ResponseType; import org.eclipse.jetty.http.HttpHeader; import org.eclipse.jetty.websocket.api.Session; import org.eclipse.jetty.websocket.client.ClientUpgradeRequest; @@ -61,6 +54,13 @@ import com.google.gson.Gson; import com.google.gson.GsonBuilder; +import com.redhat.thermostat.gateway.service.commands.channel.coders.typeadapters.MessageTypeAdapterFactory; +import com.redhat.thermostat.gateway.service.commands.channel.model.AgentRequest; +import com.redhat.thermostat.gateway.service.commands.channel.model.ClientRequest; +import com.redhat.thermostat.gateway.service.commands.channel.model.Message; +import com.redhat.thermostat.gateway.service.commands.channel.model.Message.MessageType; +import com.redhat.thermostat.gateway.service.commands.channel.model.WebSocketResponse; +import com.redhat.thermostat.gateway.service.commands.channel.model.WebSocketResponse.ResponseType; public class CommandChannelEndpointHandlerTest extends AuthBasicCoreServerTest { @@ -84,7 +84,7 @@ clientRequest.setSequenceId(clientSequence); String agentId = "testAgent"; URI clientUri = new URI( - baseUrl + "actions/dump-heap/systems/foo/agents/" + agentId + baseUrl + "actions/dump_heap/systems/foo/agents/" + agentId + "/jvms/abc/sequence/" + clientSequence); URI agentUri = new URI(baseUrl + "systems/foo/agents/" + agentId); final CountDownLatch clientHasSentMessages = new CountDownLatch(1); @@ -148,7 +148,7 @@ String clientUser = "bar-client-user"; String agentId = "testAgent"; URI clientUri = new URI( - baseUrl + "actions/dump-heap/systems/foo/agents/" + agentId + baseUrl + "actions/dump_heap/systems/foo/agents/" + agentId + "/jvms/abc/sequence/" + sequenceId); final CountDownLatch clientHasSentMessages = new CountDownLatch(1); CmdChannelClientSocket clientSocket = new CmdChannelClientSocket(clientRequest, clientHasSentMessages); @@ -388,7 +388,7 @@ ClientRequest noMatter = new ClientRequest(clientSequence); String agentId = "testAgent"; URI clientUri = new URI( - baseUrl + "actions/dump-heap/systems/foo/agents/" + agentId + baseUrl + "actions/dump_heap/systems/foo/agents/" + agentId + "/jvms/abc/sequence/" + clientSequence); CmdChannelClientSocket clientSocket = new CmdChannelClientSocket( noMatter /* doesn't matter */);
--- a/services/jvm-gc/src/main/webapp/WEB-INF/web.xml Wed Aug 23 08:34:51 2017 -0400 +++ b/services/jvm-gc/src/main/webapp/WEB-INF/web.xml Wed Aug 23 13:43:11 2017 +0200 @@ -77,4 +77,12 @@ <listener> <listener-class>com.redhat.thermostat.gateway.common.mongodb.servlet.StorageConnectionSettingListener</listener-class> </listener> -</web-app> \ No newline at end of file + <!-- Allow viewing of API spec without authentication --> + <security-constraint> + <web-resource-collection> + <web-resource-name>Swagger API Spec File</web-resource-name> + <url-pattern>/0.0.2/doc/@com.redhat.thermostat.gateway.SERVICE_NAME@-swagger.yaml</url-pattern> + </web-resource-collection> + <!-- Explicitly no auth constraint for this file --> + </security-constraint> +</web-app>
--- a/services/jvm-memory/src/main/webapp/WEB-INF/web.xml Wed Aug 23 08:34:51 2017 -0400 +++ b/services/jvm-memory/src/main/webapp/WEB-INF/web.xml Wed Aug 23 13:43:11 2017 +0200 @@ -77,4 +77,12 @@ <listener> <listener-class>com.redhat.thermostat.gateway.common.mongodb.servlet.StorageConnectionSettingListener</listener-class> </listener> + <!-- Allow viewing of API spec without authentication --> + <security-constraint> + <web-resource-collection> + <web-resource-name>Swagger API Spec File</web-resource-name> + <url-pattern>/0.0.2/doc/@com.redhat.thermostat.gateway.SERVICE_NAME@-swagger.yaml</url-pattern> + </web-resource-collection> + <!-- Explicitly no auth constraint for this file --> + </security-constraint> </web-app>
--- a/services/jvms/src/main/webapp/WEB-INF/web.xml Wed Aug 23 08:34:51 2017 -0400 +++ b/services/jvms/src/main/webapp/WEB-INF/web.xml Wed Aug 23 13:43:11 2017 +0200 @@ -77,4 +77,12 @@ <listener> <listener-class>com.redhat.thermostat.gateway.common.mongodb.servlet.StorageConnectionSettingListener</listener-class> </listener> -</web-app> \ No newline at end of file + <!-- Allow viewing of API spec without authentication --> + <security-constraint> + <web-resource-collection> + <web-resource-name>Swagger API Spec File</web-resource-name> + <url-pattern>/0.0.1/doc/@com.redhat.thermostat.gateway.SERVICE_NAME@-swagger.yaml</url-pattern> + </web-resource-collection> + <!-- Explicitly no auth constraint for this file --> + </security-constraint> +</web-app>
--- a/services/system-cpu/src/main/webapp/WEB-INF/web.xml Wed Aug 23 08:34:51 2017 -0400 +++ b/services/system-cpu/src/main/webapp/WEB-INF/web.xml Wed Aug 23 13:43:11 2017 +0200 @@ -77,4 +77,12 @@ <listener> <listener-class>com.redhat.thermostat.gateway.common.mongodb.servlet.StorageConnectionSettingListener</listener-class> </listener> -</web-app> \ No newline at end of file + <!-- Allow viewing of API spec without authentication --> + <security-constraint> + <web-resource-collection> + <web-resource-name>Swagger API Spec File</web-resource-name> + <url-pattern>/0.0.1/doc/@com.redhat.thermostat.gateway.SERVICE_NAME@-swagger.yaml</url-pattern> + </web-resource-collection> + <!-- Explicitly no auth constraint for this file --> + </security-constraint> +</web-app>
--- a/services/system-memory/src/main/webapp/WEB-INF/web.xml Wed Aug 23 08:34:51 2017 -0400 +++ b/services/system-memory/src/main/webapp/WEB-INF/web.xml Wed Aug 23 13:43:11 2017 +0200 @@ -77,4 +77,12 @@ <listener> <listener-class>com.redhat.thermostat.gateway.common.mongodb.servlet.StorageConnectionSettingListener</listener-class> </listener> -</web-app> \ No newline at end of file + <!-- Allow viewing of API spec without authentication --> + <security-constraint> + <web-resource-collection> + <web-resource-name>Swagger API Spec File</web-resource-name> + <url-pattern>/0.0.1/doc/@com.redhat.thermostat.gateway.SERVICE_NAME@-swagger.yaml</url-pattern> + </web-resource-collection> + <!-- Explicitly no auth constraint for this file --> + </security-constraint> +</web-app>
--- a/services/system-network/src/main/webapp/WEB-INF/web.xml Wed Aug 23 08:34:51 2017 -0400 +++ b/services/system-network/src/main/webapp/WEB-INF/web.xml Wed Aug 23 13:43:11 2017 +0200 @@ -77,4 +77,12 @@ <listener> <listener-class>com.redhat.thermostat.gateway.common.mongodb.servlet.StorageConnectionSettingListener</listener-class> </listener> -</web-app> \ No newline at end of file + <!-- Allow viewing of API spec without authentication --> + <security-constraint> + <web-resource-collection> + <web-resource-name>Swagger API Spec File</web-resource-name> + <url-pattern>/0.0.1/doc/@com.redhat.thermostat.gateway.SERVICE_NAME@-swagger.yaml</url-pattern> + </web-resource-collection> + <!-- Explicitly no auth constraint for this file --> + </security-constraint> +</web-app>
--- a/services/systems/src/main/webapp/WEB-INF/web.xml Wed Aug 23 08:34:51 2017 -0400 +++ b/services/systems/src/main/webapp/WEB-INF/web.xml Wed Aug 23 13:43:11 2017 +0200 @@ -77,4 +77,12 @@ <listener> <listener-class>com.redhat.thermostat.gateway.common.mongodb.servlet.StorageConnectionSettingListener</listener-class> </listener> -</web-app> \ No newline at end of file + <!-- Allow viewing of API spec without authentication --> + <security-constraint> + <web-resource-collection> + <web-resource-name>Swagger API Spec File</web-resource-name> + <url-pattern>/0.0.1/doc/@com.redhat.thermostat.gateway.SERVICE_NAME@-swagger.yaml</url-pattern> + </web-resource-collection> + <!-- Explicitly no auth constraint for this file --> + </security-constraint> +</web-app>
--- a/tests/integration-tests/src/test/java/com/redhat/thermostat/gateway/tests/integration/IntegrationTest.java Wed Aug 23 08:34:51 2017 -0400 +++ b/tests/integration-tests/src/test/java/com/redhat/thermostat/gateway/tests/integration/IntegrationTest.java Wed Aug 23 13:43:11 2017 +0200 @@ -105,7 +105,8 @@ } AuthenticationStore authenticationStore = theclient.getAuthenticationStore(); URI uri = URI.create(baseUrl); - authenticationStore.addAuthentication(new BasicAuthentication(uri, "thermostat", "agent", "agent-pwd")); + String realmName = "Thermostat Realm"; // must match Basic login service's realm name. + authenticationStore.addAuthentication(new BasicAuthentication(uri, realmName, "agent", "agent-pwd")); theclient.start(); return theclient; }