mirror of
				https://github.com/gyurix1968/guacamole-client.git
				synced 2025-10-31 00:53:21 +00:00 
			
		
		
		
	Ticket #362: Authentication working.
This commit is contained in:
		| @@ -0,0 +1,69 @@ | ||||
| package org.glyptodon.guacamole.net.basic.rest; | ||||
|  | ||||
| /* | ||||
|  *  Guacamole - Clientless Remote Desktop | ||||
|  *  Copyright (C) 2010  Michael Jumper | ||||
|  * | ||||
|  *  This program is free software: you can redistribute it and/or modify | ||||
|  *  it under the terms of the GNU Affero General Public License as published by | ||||
|  *  the Free Software Foundation, either version 3 of the License, or | ||||
|  *  (at your option) any later version. | ||||
|  * | ||||
|  *  This program 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 Affero General Public License for more details. | ||||
|  * | ||||
|  *  You should have received a copy of the GNU Affero General Public License | ||||
|  *  along with this program.  If not, see <http://www.gnu.org/licenses/>. | ||||
|  */ | ||||
|  | ||||
| import com.google.inject.AbstractModule; | ||||
| import org.glyptodon.guacamole.GuacamoleException; | ||||
| import org.glyptodon.guacamole.net.auth.AuthenticationProvider; | ||||
| import org.glyptodon.guacamole.net.basic.properties.BasicGuacamoleProperties; | ||||
| import org.glyptodon.guacamole.net.basic.rest.auth.AuthTokenGenerator; | ||||
| import org.glyptodon.guacamole.net.basic.rest.auth.BasicTokenUserContextMap; | ||||
| import org.glyptodon.guacamole.net.basic.rest.auth.SecureRandomAuthTokenGenerator; | ||||
| import org.glyptodon.guacamole.net.basic.rest.auth.TokenUserContextMap; | ||||
| import org.glyptodon.guacamole.properties.GuacamoleProperties; | ||||
| import org.slf4j.Logger; | ||||
| import org.slf4j.LoggerFactory; | ||||
|  | ||||
| /** | ||||
|  * A Guice Module for setting up dependency injection for the  | ||||
|  * Guacamole REST API. | ||||
|  *  | ||||
|  * @author James Muehlner | ||||
|  */ | ||||
| public class RESTModule extends AbstractModule { | ||||
|  | ||||
|     /** | ||||
|      * Logger for this class. | ||||
|      */ | ||||
|     private static final Logger logger = LoggerFactory.getLogger(RESTModule.class); | ||||
|  | ||||
|     /** | ||||
|      * The AuthenticationProvider to use to authenticate all requests. | ||||
|      */ | ||||
|     private AuthenticationProvider authProvider; | ||||
|  | ||||
|     @Override | ||||
|     protected void configure() { | ||||
|  | ||||
|         // Get auth provider instance | ||||
|         try { | ||||
|             authProvider = GuacamoleProperties.getRequiredProperty(BasicGuacamoleProperties.AUTH_PROVIDER); | ||||
|         } | ||||
|         catch (GuacamoleException e) { | ||||
|             logger.error("Error getting authentication provider from properties.", e); | ||||
|             throw new RuntimeException(e); | ||||
|         } | ||||
|          | ||||
|         bind(AuthenticationProvider.class).toInstance(authProvider); | ||||
|         bind(TokenUserContextMap.class).toInstance(new BasicTokenUserContextMap()); | ||||
|          | ||||
|         bind(AuthTokenGenerator.class).to(SecureRandomAuthTokenGenerator.class); | ||||
|     } | ||||
|      | ||||
| } | ||||
| @@ -19,11 +19,8 @@ package org.glyptodon.guacamole.net.basic.rest; | ||||
|  */ | ||||
|  | ||||
| import com.google.inject.Guice; | ||||
| import com.google.inject.servlet.ServletModule; | ||||
| import com.sun.jersey.guice.spi.container.servlet.GuiceContainer; | ||||
| import javax.servlet.ServletContextEvent; | ||||
| import javax.servlet.ServletContextListener; | ||||
| import org.glyptodon.guacamole.net.basic.rest.connection.ConnectionService; | ||||
|  | ||||
| /** | ||||
|  * A ServletContextListenr to listen for initialization of the servlet context | ||||
| @@ -35,15 +32,10 @@ public class RESTServletContextListener implements ServletContextListener { | ||||
|  | ||||
|     @Override | ||||
|     public void contextInitialized(ServletContextEvent sce) { | ||||
|         Guice.createInjector(new ServletModule() { | ||||
|             @Override | ||||
|             protected void configureServlets() { | ||||
|                  | ||||
|                 bind(ConnectionService.class); | ||||
|                  | ||||
|                 serve("*").with(GuiceContainer.class); | ||||
|             } | ||||
|         }); | ||||
|         Guice.createInjector( | ||||
|             new RESTServletModule(),  | ||||
|             new RESTModule() | ||||
|         ); | ||||
|     } | ||||
|  | ||||
|     @Override | ||||
|   | ||||
| @@ -0,0 +1,42 @@ | ||||
| package org.glyptodon.guacamole.net.basic.rest; | ||||
|  | ||||
| /* | ||||
|  *  Guacamole - Clientless Remote Desktop | ||||
|  *  Copyright (C) 2010  Michael Jumper | ||||
|  * | ||||
|  *  This program is free software: you can redistribute it and/or modify | ||||
|  *  it under the terms of the GNU Affero General Public License as published by | ||||
|  *  the Free Software Foundation, either version 3 of the License, or | ||||
|  *  (at your option) any later version. | ||||
|  * | ||||
|  *  This program 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 Affero General Public License for more details. | ||||
|  * | ||||
|  *  You should have received a copy of the GNU Affero General Public License | ||||
|  *  along with this program.  If not, see <http://www.gnu.org/licenses/>. | ||||
|  */ | ||||
|  | ||||
| import com.google.inject.servlet.ServletModule; | ||||
| import com.sun.jersey.guice.spi.container.servlet.GuiceContainer; | ||||
| import org.glyptodon.guacamole.net.basic.rest.auth.LoginService; | ||||
| import org.glyptodon.guacamole.net.basic.rest.connection.ConnectionService; | ||||
|  | ||||
| /** | ||||
|  * A Guice Module to set up the servlet mappings for the Guacamole REST API. | ||||
|  *  | ||||
|  * @author James Muehlner | ||||
|  */ | ||||
| public class RESTServletModule extends ServletModule { | ||||
|      | ||||
|     @Override | ||||
|     protected void configureServlets() { | ||||
|  | ||||
|         bind(ConnectionService.class); | ||||
|         bind(LoginService.class); | ||||
|  | ||||
|         serve("*").with(GuiceContainer.class); | ||||
|     } | ||||
|      | ||||
| } | ||||
| @@ -0,0 +1,34 @@ | ||||
| package org.glyptodon.guacamole.net.basic.rest.auth; | ||||
|  | ||||
| /* | ||||
|  *  Guacamole - Clientless Remote Desktop | ||||
|  *  Copyright (C) 2010  Michael Jumper | ||||
|  * | ||||
|  *  This program is free software: you can redistribute it and/or modify | ||||
|  *  it under the terms of the GNU Affero General Public License as published by | ||||
|  *  the Free Software Foundation, either version 3 of the License, or | ||||
|  *  (at your option) any later version. | ||||
|  * | ||||
|  *  This program 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 Affero General Public License for more details. | ||||
|  * | ||||
|  *  You should have received a copy of the GNU Affero General Public License | ||||
|  *  along with this program.  If not, see <http://www.gnu.org/licenses/>. | ||||
|  */ | ||||
|  | ||||
| /** | ||||
|  * Generates an auth token for an authenticated user. | ||||
|  *  | ||||
|  * @author James Muehlner | ||||
|  */ | ||||
| public interface AuthTokenGenerator { | ||||
|      | ||||
|     /** | ||||
|      * Get a new auth token. | ||||
|      *  | ||||
|      * @return A new auth token. | ||||
|      */ | ||||
|     public String getToken(); | ||||
| } | ||||
| @@ -0,0 +1,30 @@ | ||||
| package org.glyptodon.guacamole.net.basic.rest.auth; | ||||
|  | ||||
| /* | ||||
|  *  Guacamole - Clientless Remote Desktop | ||||
|  *  Copyright (C) 2010  Michael Jumper | ||||
|  * | ||||
|  *  This program is free software: you can redistribute it and/or modify | ||||
|  *  it under the terms of the GNU Affero General Public License as published by | ||||
|  *  the Free Software Foundation, either version 3 of the License, or | ||||
|  *  (at your option) any later version. | ||||
|  * | ||||
|  *  This program 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 Affero General Public License for more details. | ||||
|  * | ||||
|  *  You should have received a copy of the GNU Affero General Public License | ||||
|  *  along with this program.  If not, see <http://www.gnu.org/licenses/>. | ||||
|  */ | ||||
|  | ||||
| import java.util.HashMap; | ||||
| import org.glyptodon.guacamole.net.auth.UserContext; | ||||
|  | ||||
| /** | ||||
|  * A Basic, HashMap-based implementation of the TokenUserContextMap. | ||||
|  *  | ||||
|  * @author James Muehlner | ||||
|  */ | ||||
| public class BasicTokenUserContextMap extends HashMap<String, UserContext>  | ||||
|         implements TokenUserContextMap {} | ||||
| @@ -0,0 +1,107 @@ | ||||
| package org.glyptodon.guacamole.net.basic.rest.auth; | ||||
|  | ||||
| import com.google.inject.Inject; | ||||
| import javax.ws.rs.POST; | ||||
| import javax.ws.rs.Path; | ||||
| import javax.ws.rs.QueryParam; | ||||
| import javax.ws.rs.WebApplicationException; | ||||
| import javax.ws.rs.core.Response; | ||||
| import org.glyptodon.guacamole.GuacamoleException; | ||||
| import org.glyptodon.guacamole.net.auth.AuthenticationProvider; | ||||
| import org.glyptodon.guacamole.net.auth.Credentials; | ||||
| import org.glyptodon.guacamole.net.auth.UserContext; | ||||
| import org.glyptodon.guacamole.net.basic.rest.RESTModule; | ||||
| import org.slf4j.Logger; | ||||
| import org.slf4j.LoggerFactory; | ||||
|  | ||||
| /* | ||||
|  *  Guacamole - Clientless Remote Desktop | ||||
|  *  Copyright (C) 2010  Michael Jumper | ||||
|  * | ||||
|  *  This program is free software: you can redistribute it and/or modify | ||||
|  *  it under the terms of the GNU Affero General Public License as published by | ||||
|  *  the Free Software Foundation, either version 3 of the License, or | ||||
|  *  (at your option) any later version. | ||||
|  * | ||||
|  *  This program 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 Affero General Public License for more details. | ||||
|  * | ||||
|  *  You should have received a copy of the GNU Affero General Public License | ||||
|  *  along with this program.  If not, see <http://www.gnu.org/licenses/>. | ||||
|  */ | ||||
|  | ||||
| /** | ||||
|  * A service for authenticating to the Guacamole REST API. Given valid | ||||
|  * credentials, the service will return an auth token. Invalid credentials will | ||||
|  * result in a permission error. | ||||
|  *  | ||||
|  * @author James Muehlner | ||||
|  */ | ||||
|  | ||||
|  | ||||
| @Path("/api/login") | ||||
| public class LoginService { | ||||
|      | ||||
|     /** | ||||
|      * The authentication provider used to authenticate this user. | ||||
|      */ | ||||
|     @Inject | ||||
|     private AuthenticationProvider authProvider; | ||||
|      | ||||
|     /** | ||||
|      * The map of auth tokens to users for the REST endpoints. | ||||
|      */ | ||||
|     @Inject | ||||
|     private TokenUserContextMap tokenUserMap; | ||||
|      | ||||
|     /** | ||||
|      * A generator for creating new auth tokens. | ||||
|      */ | ||||
|     @Inject | ||||
|     private AuthTokenGenerator authTokenGenerator; | ||||
|  | ||||
|     /** | ||||
|      * Logger for this class. | ||||
|      */ | ||||
|     private static final Logger logger = LoggerFactory.getLogger(LoginService.class); | ||||
|      | ||||
|     /** | ||||
|      * Authenticates a user, generates an auth token, associates that auth token | ||||
|      * with the user's UserContext for use by further requests. | ||||
|      *  | ||||
|      * @param username The username of the user who is to be authenticated. | ||||
|      * @param password The password of the user who is to be authenticated. | ||||
|      * @return The auth token for the newly logged-in user. | ||||
|      */ | ||||
|     @POST | ||||
|     @Path("/") | ||||
|     public String login(@QueryParam("username") String username, | ||||
|             @QueryParam("password") String password) { | ||||
|          | ||||
|         Credentials credentials = new Credentials(); | ||||
|         credentials.setUsername(username); | ||||
|         credentials.setPassword(password); | ||||
|          | ||||
|         UserContext userContext; | ||||
|          | ||||
|         try { | ||||
|             userContext = authProvider.getUserContext(credentials); | ||||
|         } catch(GuacamoleException e) { | ||||
|             logger.error("Exception caught while authenticating user.", e); | ||||
|             throw new WebApplicationException(e, Response.Status.INTERNAL_SERVER_ERROR); | ||||
|         } | ||||
|          | ||||
|         // authentication failed. | ||||
|         if(userContext == null) | ||||
|             throw new WebApplicationException(Response.Status.UNAUTHORIZED); | ||||
|          | ||||
|         String authToken = authTokenGenerator.getToken(); | ||||
|          | ||||
|         tokenUserMap.put(authToken, userContext); | ||||
|          | ||||
|         return authToken; | ||||
|     } | ||||
|      | ||||
| } | ||||
| @@ -0,0 +1,30 @@ | ||||
| /* | ||||
|  * To change this template, choose Tools | Templates | ||||
|  * and open the template in the editor. | ||||
|  */ | ||||
| package org.glyptodon.guacamole.net.basic.rest.auth; | ||||
|  | ||||
| import java.security.SecureRandom; | ||||
| import org.apache.commons.codec.binary.Hex; | ||||
|  | ||||
| /** | ||||
|  * An implementation of the AuthTokenGenerator based around SecureRandom. | ||||
|  *  | ||||
|  * @author James Muehlner | ||||
|  */ | ||||
| public class SecureRandomAuthTokenGenerator implements AuthTokenGenerator { | ||||
|  | ||||
|     /** | ||||
|      * Instance of SecureRandom for generating the auth token. | ||||
|      */ | ||||
|     private SecureRandom secureRandom = new SecureRandom(); | ||||
|  | ||||
|     @Override | ||||
|     public String getToken() { | ||||
|         byte[] bytes = new byte[32]; | ||||
|         secureRandom.nextBytes(bytes); | ||||
|          | ||||
|         return Hex.encodeHexString(bytes); | ||||
|     } | ||||
|      | ||||
| } | ||||
| @@ -0,0 +1,30 @@ | ||||
| package org.glyptodon.guacamole.net.basic.rest.auth; | ||||
|  | ||||
| /* | ||||
|  *  Guacamole - Clientless Remote Desktop | ||||
|  *  Copyright (C) 2010  Michael Jumper | ||||
|  * | ||||
|  *  This program is free software: you can redistribute it and/or modify | ||||
|  *  it under the terms of the GNU Affero General Public License as published by | ||||
|  *  the Free Software Foundation, either version 3 of the License, or | ||||
|  *  (at your option) any later version. | ||||
|  * | ||||
|  *  This program 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 Affero General Public License for more details. | ||||
|  * | ||||
|  *  You should have received a copy of the GNU Affero General Public License | ||||
|  *  along with this program.  If not, see <http://www.gnu.org/licenses/>. | ||||
|  */ | ||||
|  | ||||
| import java.util.Map; | ||||
| import org.glyptodon.guacamole.net.auth.UserContext; | ||||
|  | ||||
| /** | ||||
|  * Represents a mapping of auth token to user context for the REST  | ||||
|  * authentication system. | ||||
|  *  | ||||
|  * @author James Muehlner | ||||
|  */ | ||||
| public interface TokenUserContextMap extends Map<String, UserContext> {} | ||||
| @@ -1,11 +1,33 @@ | ||||
| /* | ||||
|  * To change this template, choose Tools | Templates | ||||
|  * and open the template in the editor. | ||||
|  */ | ||||
| package org.glyptodon.guacamole.net.basic.rest.connection; | ||||
|  | ||||
| /* | ||||
|  *  Guacamole - Clientless Remote Desktop | ||||
|  *  Copyright (C) 2010  Michael Jumper | ||||
|  * | ||||
|  *  This program is free software: you can redistribute it and/or modify | ||||
|  *  it under the terms of the GNU Affero General Public License as published by | ||||
|  *  the Free Software Foundation, either version 3 of the License, or | ||||
|  *  (at your option) any later version. | ||||
|  * | ||||
|  *  This program 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 Affero General Public License for more details. | ||||
|  * | ||||
|  *  You should have received a copy of the GNU Affero General Public License | ||||
|  *  along with this program.  If not, see <http://www.gnu.org/licenses/>. | ||||
|  */ | ||||
|  | ||||
| import com.google.inject.Inject; | ||||
| import javax.ws.rs.GET; | ||||
| import javax.ws.rs.Path; | ||||
| import javax.ws.rs.QueryParam; | ||||
| import javax.ws.rs.WebApplicationException; | ||||
| import javax.ws.rs.core.Response; | ||||
| import org.glyptodon.guacamole.GuacamoleException; | ||||
| import org.glyptodon.guacamole.GuacamoleSecurityException; | ||||
| import org.glyptodon.guacamole.net.auth.UserContext; | ||||
| import org.glyptodon.guacamole.net.basic.rest.auth.TokenUserContextMap; | ||||
|  | ||||
| /** | ||||
|  * A REST Service for handling connection CRUD operations. | ||||
| @@ -15,10 +37,29 @@ import javax.ws.rs.Path; | ||||
| @Path("/api/connection") | ||||
| public class ConnectionService { | ||||
|      | ||||
|     /** | ||||
|      * The map of auth tokens to users for the REST endpoints. | ||||
|      */ | ||||
|     @Inject | ||||
|     private TokenUserContextMap tokenUserMap; | ||||
|      | ||||
|     @Path("/") | ||||
|     @GET | ||||
|     public String getConnections() { | ||||
|         return "goo"; | ||||
|     public String getConnections(@QueryParam("token") String authToken) { | ||||
|         UserContext userContext = tokenUserMap.get(authToken); | ||||
|         | ||||
|         // authentication failed. | ||||
|         if(userContext == null) | ||||
|             throw new WebApplicationException(Response.Status.UNAUTHORIZED); | ||||
|          | ||||
|         try { | ||||
|             //TODO: Make this work for realzies | ||||
|             return userContext.getRootConnectionGroup().getConnectionDirectory().getIdentifiers().toString(); | ||||
|         } catch(GuacamoleSecurityException e) { | ||||
|             throw new WebApplicationException(e, Response.Status.UNAUTHORIZED); | ||||
|         } catch(GuacamoleException e) { | ||||
|             throw new WebApplicationException(e, Response.Status.INTERNAL_SERVER_ERROR); | ||||
|         } | ||||
|     }    | ||||
|      | ||||
| } | ||||
|   | ||||
		Reference in New Issue
	
	Block a user