api: add method to pass on api authenticators to cmd classes

Signed-off-by: Rohit Yadav <rohit.ya...@shapeblue.com>


Project: http://git-wip-us.apache.org/repos/asf/cloudstack/repo
Commit: http://git-wip-us.apache.org/repos/asf/cloudstack/commit/a7589411
Tree: http://git-wip-us.apache.org/repos/asf/cloudstack/tree/a7589411
Diff: http://git-wip-us.apache.org/repos/asf/cloudstack/diff/a7589411

Branch: refs/heads/saml2
Commit: a7589411533b003a7b9fe7bc4af40887d96b2b81
Parents: 41cb6cd
Author: Rohit Yadav <rohit.ya...@shapeblue.com>
Authored: Sun Aug 24 20:47:43 2014 +0200
Committer: Rohit Yadav <rohit.ya...@shapeblue.com>
Committed: Sun Aug 24 20:47:43 2014 +0200

----------------------------------------------------------------------
 .../cloudstack/api/auth/APIAuthenticator.java   |  4 +++
 .../command/SAML2LoginAPIAuthenticatorCmd.java  | 38 +++++++++++++++++---
 .../api/auth/APIAuthenticationManagerImpl.java  |  1 +
 .../auth/DefaultLoginAPIAuthenticatorCmd.java   |  6 ++++
 .../auth/DefaultLogoutAPIAuthenticatorCmd.java  |  6 ++++
 server/src/com/cloud/configuration/Config.java  |  2 +-
 6 files changed, 51 insertions(+), 6 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cloudstack/blob/a7589411/api/src/org/apache/cloudstack/api/auth/APIAuthenticator.java
----------------------------------------------------------------------
diff --git a/api/src/org/apache/cloudstack/api/auth/APIAuthenticator.java 
b/api/src/org/apache/cloudstack/api/auth/APIAuthenticator.java
index b008f00..67fa1d8 100644
--- a/api/src/org/apache/cloudstack/api/auth/APIAuthenticator.java
+++ b/api/src/org/apache/cloudstack/api/auth/APIAuthenticator.java
@@ -20,6 +20,7 @@ import org.apache.cloudstack.api.ServerApiException;
 
 import javax.servlet.http.HttpServletResponse;
 import javax.servlet.http.HttpSession;
+import java.util.List;
 import java.util.Map;
 
 /*
@@ -36,5 +37,8 @@ public interface APIAuthenticator {
     public String authenticate(String command, Map<String, Object[]> params,
                                HttpSession session, String remoteAddress, 
String responseType,
                                StringBuilder auditTrailSb, final 
HttpServletResponse resp) throws ServerApiException;
+
     public APIAuthenticationType getAPIType();
+
+    public void setAuthenticators(List<PluggableAPIAuthenticator> 
authenticators);
 }

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/a7589411/plugins/user-authenticators/saml2/src/org/apache/cloudstack/api/command/SAML2LoginAPIAuthenticatorCmd.java
----------------------------------------------------------------------
diff --git 
a/plugins/user-authenticators/saml2/src/org/apache/cloudstack/api/command/SAML2LoginAPIAuthenticatorCmd.java
 
b/plugins/user-authenticators/saml2/src/org/apache/cloudstack/api/command/SAML2LoginAPIAuthenticatorCmd.java
index ec3a4d2..88acfe1 100644
--- 
a/plugins/user-authenticators/saml2/src/org/apache/cloudstack/api/command/SAML2LoginAPIAuthenticatorCmd.java
+++ 
b/plugins/user-authenticators/saml2/src/org/apache/cloudstack/api/command/SAML2LoginAPIAuthenticatorCmd.java
@@ -32,6 +32,7 @@ import org.apache.cloudstack.api.Parameter;
 import org.apache.cloudstack.api.ServerApiException;
 import org.apache.cloudstack.api.auth.APIAuthenticationType;
 import org.apache.cloudstack.api.auth.APIAuthenticator;
+import org.apache.cloudstack.api.auth.PluggableAPIAuthenticator;
 import org.apache.cloudstack.api.response.LoginCmdResponse;
 import org.apache.cloudstack.context.CallContext;
 import org.apache.cloudstack.saml.SAML2AuthManager;
@@ -49,7 +50,10 @@ import org.opensaml.saml2.core.StatusCode;
 import org.opensaml.xml.ConfigurationException;
 import org.opensaml.xml.io.MarshallingException;
 import org.opensaml.xml.io.UnmarshallingException;
+import org.opensaml.xml.security.x509.BasicX509Credential;
 import org.opensaml.xml.signature.Signature;
+import org.opensaml.xml.signature.SignatureValidator;
+import org.opensaml.xml.validation.ValidationException;
 import org.xml.sax.SAXException;
 
 import javax.inject.Inject;
@@ -80,7 +84,7 @@ public class SAML2LoginAPIAuthenticatorCmd extends BaseCmd 
implements APIAuthent
     ApiServerService _apiServer;
     @Inject
     EntityManager _entityMgr;
-    @Inject
+
     SAML2AuthManager _samlAuthManager;
 
     /////////////////////////////////////////////////////
@@ -135,9 +139,10 @@ public class SAML2LoginAPIAuthenticatorCmd extends BaseCmd 
implements APIAuthent
     public Response processSAMLResponse(String responseMessage) {
         Response responseObject = null;
         try {
+            DefaultBootstrap.bootstrap();
             responseObject = SAMLUtils.decodeSAMLResponse(responseMessage);
 
-        } catch (ConfigurationException | ParserConfigurationException | 
SAXException | IOException | UnmarshallingException e) {
+        } catch (ConfigurationException | FactoryConfigurationError | 
ParserConfigurationException | SAXException | IOException | 
UnmarshallingException e) {
             s_logger.error("SAMLResponse processing error: " + e.getMessage());
         }
         return responseObject;
@@ -165,9 +170,20 @@ public class SAML2LoginAPIAuthenticatorCmd extends BaseCmd 
implements APIAuthent
                             params, responseType));
                 }
 
-                Signature sig = processedSAMLResponse.getSignature();
-                //SignatureValidator validator = new 
SignatureValidator(credential);
-                //validator.validate(sig);
+                if (_samlAuthManager.getIdpSigningKey() != null) {
+                    Signature sig = processedSAMLResponse.getSignature();
+                    BasicX509Credential credential = new BasicX509Credential();
+                    
credential.setEntityCertificate(_samlAuthManager.getIdpSigningKey());
+                    SignatureValidator validator = new 
SignatureValidator(credential);
+                    try {
+                        validator.validate(sig);
+                    } catch (ValidationException e) {
+                        s_logger.error("SAML Response's signature failed to be 
validated by IDP signing key:" + e.getMessage());
+                        throw new 
ServerApiException(ApiErrorCode.ACCOUNT_ERROR, 
_apiServer.getSerializedApiError(ApiErrorCode.ACCOUNT_ERROR.getHttpCode(),
+                                "SAML Response's signature failed to be 
validated by IDP signing key",
+                                params, responseType));
+                    }
+                }
 
                 String uniqueUserId = null;
                 String accountName = "admin"; //GET from config, try, fail
@@ -251,4 +267,16 @@ public class SAML2LoginAPIAuthenticatorCmd extends BaseCmd 
implements APIAuthent
     public APIAuthenticationType getAPIType() {
         return APIAuthenticationType.LOGIN_API;
     }
+
+    @Override
+    public void setAuthenticators(List<PluggableAPIAuthenticator> 
authenticators) {
+        for (PluggableAPIAuthenticator authManager: authenticators) {
+            if (authManager instanceof SAML2AuthManager) {
+                _samlAuthManager = (SAML2AuthManager) authManager;
+            }
+        }
+        if (_samlAuthManager == null) {
+            s_logger.error("No suitable Pluggable Authentication Manager found 
for SAML2 Login Cmd");
+        }
+    }
 }

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/a7589411/server/src/com/cloud/api/auth/APIAuthenticationManagerImpl.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/api/auth/APIAuthenticationManagerImpl.java 
b/server/src/com/cloud/api/auth/APIAuthenticationManagerImpl.java
index 790b6d9..24ccbeb 100644
--- a/server/src/com/cloud/api/auth/APIAuthenticationManagerImpl.java
+++ b/server/src/com/cloud/api/auth/APIAuthenticationManagerImpl.java
@@ -81,6 +81,7 @@ public class APIAuthenticationManagerImpl extends ManagerBase 
implements APIAuth
             try {
                 apiAuthenticator = (APIAuthenticator) 
s_authenticators.get(name).newInstance();
                 apiAuthenticator = ComponentContext.inject(apiAuthenticator);
+                apiAuthenticator.setAuthenticators(_apiAuthenticators);
             } catch (InstantiationException | IllegalAccessException e) {
                 if (s_logger.isDebugEnabled()) {
                     
s_logger.debug("APIAuthenticationManagerImpl::getAPIAuthenticator failed: " + 
e.getMessage());

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/a7589411/server/src/com/cloud/api/auth/DefaultLoginAPIAuthenticatorCmd.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/api/auth/DefaultLoginAPIAuthenticatorCmd.java 
b/server/src/com/cloud/api/auth/DefaultLoginAPIAuthenticatorCmd.java
index 2fb3f56..fa23abd 100644
--- a/server/src/com/cloud/api/auth/DefaultLoginAPIAuthenticatorCmd.java
+++ b/server/src/com/cloud/api/auth/DefaultLoginAPIAuthenticatorCmd.java
@@ -28,12 +28,14 @@ import org.apache.cloudstack.api.Parameter;
 import org.apache.cloudstack.api.ServerApiException;
 import org.apache.cloudstack.api.auth.APIAuthenticationType;
 import org.apache.cloudstack.api.auth.APIAuthenticator;
+import org.apache.cloudstack.api.auth.PluggableAPIAuthenticator;
 import org.apache.cloudstack.api.response.LoginCmdResponse;
 import org.apache.log4j.Logger;
 
 import javax.inject.Inject;
 import javax.servlet.http.HttpServletResponse;
 import javax.servlet.http.HttpSession;
+import java.util.List;
 import java.util.Map;
 
 @APICommand(name = "login", description = "Logs a user into the CloudStack. A 
successful login attempt will generate a JSESSIONID cookie value that can be 
passed in subsequent Query command calls until the \"logout\" command has been 
issued or the session has expired.", requestHasSensitiveInfo = true, 
responseObject = LoginCmdResponse.class, entityType = {})
@@ -172,4 +174,8 @@ public class DefaultLoginAPIAuthenticatorCmd extends 
BaseCmd implements APIAuthe
     public APIAuthenticationType getAPIType() {
         return APIAuthenticationType.LOGIN_API;
     }
+
+    @Override
+    public void setAuthenticators(List<PluggableAPIAuthenticator> 
authenticators) {
+    }
 }

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/a7589411/server/src/com/cloud/api/auth/DefaultLogoutAPIAuthenticatorCmd.java
----------------------------------------------------------------------
diff --git 
a/server/src/com/cloud/api/auth/DefaultLogoutAPIAuthenticatorCmd.java 
b/server/src/com/cloud/api/auth/DefaultLogoutAPIAuthenticatorCmd.java
index 999cefd..ee7936a 100644
--- a/server/src/com/cloud/api/auth/DefaultLogoutAPIAuthenticatorCmd.java
+++ b/server/src/com/cloud/api/auth/DefaultLogoutAPIAuthenticatorCmd.java
@@ -24,11 +24,13 @@ import org.apache.cloudstack.api.BaseCmd;
 import org.apache.cloudstack.api.ServerApiException;
 import org.apache.cloudstack.api.auth.APIAuthenticationType;
 import org.apache.cloudstack.api.auth.APIAuthenticator;
+import org.apache.cloudstack.api.auth.PluggableAPIAuthenticator;
 import org.apache.cloudstack.api.response.LogoutCmdResponse;
 import org.apache.log4j.Logger;
 
 import javax.servlet.http.HttpServletResponse;
 import javax.servlet.http.HttpSession;
+import java.util.List;
 import java.util.Map;
 
 @APICommand(name = "logout", description = "Logs out the user", responseObject 
= LogoutCmdResponse.class, entityType = {})
@@ -70,4 +72,8 @@ public class DefaultLogoutAPIAuthenticatorCmd extends BaseCmd 
implements APIAuth
     public APIAuthenticationType getAPIType() {
         return APIAuthenticationType.LOGOUT_API;
     }
+
+    @Override
+    public void setAuthenticators(List<PluggableAPIAuthenticator> 
authenticators) {
+    }
 }

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/a7589411/server/src/com/cloud/configuration/Config.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/configuration/Config.java 
b/server/src/com/cloud/configuration/Config.java
index b2fb85f..de4aaed 100755
--- a/server/src/com/cloud/configuration/Config.java
+++ b/server/src/com/cloud/configuration/Config.java
@@ -1384,7 +1384,7 @@ public enum Config {
             ManagementServer.class,
             String.class,
             "saml2.sp.id",
-            "Apache CloudStack",
+            "org.apache.cloudstack",
             "SAML2 Service Provider Identifier String",
             null),
     SAMLServiceProviderSingleSignOnURL(

Reply via email to