Ravi Nori has uploaded a new change for review.

Change subject: aaa: Encrypt password returned to user, add support for Login 
On Behalf
......................................................................

aaa: Encrypt password returned to user, add support for Login On Behalf

Will be merged to first patch

Change-Id: I1422774b0fbf52a59299f521ad92c6d576f7a1b2
Bug-Url: https://bugzilla.redhat.com/1092744
Signed-off-by: Ravi Nori <rn...@redhat.com>
---
M 
backend/manager/modules/enginesso/src/main/java/org/ovirt/engine/core/sso/servlets/OAuthTokenInfo.java
M 
backend/manager/modules/enginesso/src/main/java/org/ovirt/engine/core/sso/servlets/OAuthTokenServlet.java
M 
backend/manager/modules/enginesso/src/main/java/org/ovirt/engine/core/sso/utils/SSOUtils.java
3 files changed, 93 insertions(+), 26 deletions(-)


  git pull ssh://gerrit.ovirt.org:29418/ovirt-engine refs/changes/91/42291/1

diff --git 
a/backend/manager/modules/enginesso/src/main/java/org/ovirt/engine/core/sso/servlets/OAuthTokenInfo.java
 
b/backend/manager/modules/enginesso/src/main/java/org/ovirt/engine/core/sso/servlets/OAuthTokenInfo.java
index 26b4a93..d849e9e 100644
--- 
a/backend/manager/modules/enginesso/src/main/java/org/ovirt/engine/core/sso/servlets/OAuthTokenInfo.java
+++ 
b/backend/manager/modules/enginesso/src/main/java/org/ovirt/engine/core/sso/servlets/OAuthTokenInfo.java
@@ -1,8 +1,6 @@
 package org.ovirt.engine.core.sso.servlets;
 
 import org.apache.commons.lang.StringUtils;
-import org.ovirt.engine.api.extensions.ExtMap;
-import org.ovirt.engine.api.extensions.aaa.Authz;
 import org.ovirt.engine.core.sso.utils.OAuthException;
 import org.ovirt.engine.core.sso.utils.SSOUtils;
 import org.slf4j.Logger;
@@ -39,7 +37,7 @@
             }
             String password = null;
             if 
(SSOUtils.scopeAsList(scope).contains("ovirt-auth-password-access")) {
-                password = (String) sessionData.get(SSOUtils.PASSWORD);
+                password = SSOUtils.encrypt(request.getServletContext(), 
(String) sessionData.get(SSOUtils.PASSWORD));
             }
             SSOUtils.sendJsonData(response, 
SSOUtils.scopeAsList(scope).contains("ovirt-auth-validate") ?
                     Collections.<String, Object>emptyMap() :
@@ -63,11 +61,10 @@
         Map<String, Object> ovirt = new HashMap<>();
 
         ovirt.put("version", SSOUtils.SSO_VERSION);
-        ExtMap principalRecord = (ExtMap) 
sessionData.get(SSOUtils.SSO_PRINCIPAL_RECORD_ATTR_NAME);
 
-        ovirt.put("principal_id", 
principalRecord.<String>get(Authz.PrincipalRecord.ID));
-        ovirt.put("email", 
principalRecord.<String>get(Authz.PrincipalRecord.EMAIL));
-        ovirt.put("group_ids", 
principalRecord.get(Authz.PrincipalRecord.GROUPS, 
Collections.<ExtMap>emptyList()));
+        ovirt.put("principal_id", 
sessionData.get(SSOUtils.SSO_PRINCIPAL_ID_ATTR_NAME));
+        ovirt.put("email", sessionData.get(SSOUtils.SSO_EMAIL_ATTR_NAME));
+        ovirt.put("group_ids", 
sessionData.get(SSOUtils.SSO_GROUP_IDS_ATTR_NAME));
         if (StringUtils.isNotEmpty(password)) {
             ovirt.put("password", password);
         }
diff --git 
a/backend/manager/modules/enginesso/src/main/java/org/ovirt/engine/core/sso/servlets/OAuthTokenServlet.java
 
b/backend/manager/modules/enginesso/src/main/java/org/ovirt/engine/core/sso/servlets/OAuthTokenServlet.java
index 517dbb2..f4f5eca 100644
--- 
a/backend/manager/modules/enginesso/src/main/java/org/ovirt/engine/core/sso/servlets/OAuthTokenServlet.java
+++ 
b/backend/manager/modules/enginesso/src/main/java/org/ovirt/engine/core/sso/servlets/OAuthTokenServlet.java
@@ -40,7 +40,7 @@
                     issueTokenForAuthCode(request, response, 
clientIdAndSecret[0]);
                     break;
                 case "password":
-                    issueTokenForPasswd(request, response);
+                    handlePasswordGrantType(request, response, scope);
                     break;
                 case "urn:ovirt:params:oauth:grant-type:http":
                     String redirectUri = SSOUtils.getRequestParameter(request, 
SSOUtils.REDIRECT_URI, SSOUtils.REDIRECT_URI);
@@ -75,6 +75,27 @@
         SSOUtils.sendJsonData(response, buildResponse(sessionData));
     }
 
+    private void handlePasswordGrantType(HttpServletRequest request, 
HttpServletResponse response, String scope) throws Exception {
+        if (SSOUtils.scopeAsList(scope).contains("ovirt-auth-on-behalf")) {
+            issueTokenForLoginOnBehalf(request, response);
+        } else {
+            issueTokenForPasswd(request, response);
+        }
+    }
+
+    private static void issueTokenForLoginOnBehalf(HttpServletRequest request, 
HttpServletResponse response) throws Exception {
+        log.debug("Entered issueTokenForLoginOnBehalf");
+        Map<String, Object> payload = 
SSOUtils.readJson(SSOUtils.getRequestParameter(request, "payload", null));
+        payload.put(SSOUtils.VALID_TO, "" + Integer.MAX_VALUE);
+        String token = SSOUtils.persistAuthInfoInContextWithToken(request, 
false, null, payload);
+        Map<String, Object> sessionData = 
SSOUtils.getSessionData(request.getServletContext(), token);
+        if (sessionData == null) {
+            throw new OAuthException(SSOUtils.ERR_CODE_INVALID_GRANT, "The 
provided authorization grant for the username and password has expired");
+        }
+        log.debug("Sending json response");
+        SSOUtils.sendJsonData(response, buildResponse(sessionData));
+    }
+
     private static void issueTokenForPasswd(HttpServletRequest request, 
HttpServletResponse response) throws Exception {
         log.debug("Entered issueTokenForPasswd");
         Credentials credentials = null;
@@ -82,11 +103,11 @@
             credentials = 
SSOUtils.translateUser(SSOUtils.getRequestParameter(request, "username", 
"username"),
                     SSOUtils.getRequestParameter(request, "password", 
"password"),
                     (SSOConfig) 
request.getServletContext().getAttribute(SSOUtils.SSO_CONFIG));
-            String code = null;
+            String token = null;
             if (credentials != null && credentials.isValid()) {
-                code = AuthenticationUtils.handleCredentials(request, false, 
credentials);
+                token = AuthenticationUtils.handleCredentials(request, false, 
credentials);
             }
-            Map<String, Object> sessionData = 
SSOUtils.getSessionData(request.getServletContext(), code);
+            Map<String, Object> sessionData = 
SSOUtils.getSessionData(request.getServletContext(), token);
             if (sessionData == null) {
                 throw new OAuthException(SSOUtils.ERR_CODE_INVALID_GRANT, "The 
provided authorization grant for the username and password has expired");
             }
diff --git 
a/backend/manager/modules/enginesso/src/main/java/org/ovirt/engine/core/sso/utils/SSOUtils.java
 
b/backend/manager/modules/enginesso/src/main/java/org/ovirt/engine/core/sso/utils/SSOUtils.java
index 07c4398..2576d46 100644
--- 
a/backend/manager/modules/enginesso/src/main/java/org/ovirt/engine/core/sso/utils/SSOUtils.java
+++ 
b/backend/manager/modules/enginesso/src/main/java/org/ovirt/engine/core/sso/utils/SSOUtils.java
@@ -4,7 +4,6 @@
 import org.apache.commons.lang.StringUtils;
 import org.codehaus.jackson.map.ObjectMapper;
 import org.codehaus.jackson.map.DeserializationConfig.Feature;
-import org.ovirt.engine.api.extensions.Base;
 import org.ovirt.engine.api.extensions.ExtMap;
 import org.ovirt.engine.api.extensions.aaa.Authn;
 import org.ovirt.engine.api.extensions.aaa.Authz;
@@ -12,16 +11,24 @@
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
+import javax.crypto.Cipher;
 import javax.servlet.ServletContext;
 import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpServletResponse;
 import javax.servlet.http.HttpSession;
+import java.io.File;
+import java.io.FileInputStream;
 import java.io.IOException;
+import java.io.InputStream;
 import java.io.OutputStream;
 import java.nio.charset.Charset;
+import java.security.GeneralSecurityException;
 import java.security.NoSuchAlgorithmException;
 import java.security.SecureRandom;
+import java.security.cert.Certificate;
+import java.security.cert.CertificateFactory;
 import java.util.Arrays;
+import java.util.Collections;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
@@ -30,10 +37,10 @@
 
     public static final String LOGIN_MSG = "loginMsg";
     public static final String PARAMS_MAP = "paramsMap";
-    public static final String SSO_AUTHZ_ATTR_NAME = "AUTHZ_NAME";
-    public static final String SSO_PROFILE_ATTR_NAME = "PROFILE_NAME";
-    public static final String SSO_PRINCIPAL_RECORD_ATTR_NAME = 
"PRINCIPAL_RECORD";
-    public static final String SSO_AUTH_RECORD_ATTR_NAME = "AUTH_RECORD";
+    public static final String SSO_PROFILE_ATTR_NAME = "profile";
+    public static final String SSO_PRINCIPAL_ID_ATTR_NAME = "principal_id";
+    public static final String SSO_EMAIL_ATTR_NAME = "email";
+    public static final String SSO_GROUP_IDS_ATTR_NAME = "group_ids";
     public static final String SSO_VERSION = "0";
     public static final String SSO_CONFIG = "config";
     public static final String SSO_SESSION_DATA = "session_data";
@@ -94,7 +101,7 @@
 
     public static boolean isUserAuthenticated(HttpSession session) {
         Map<String, Object> sessionData = getSessionData(session);
-        return sessionData == null ? false : 
sessionData.get(SSO_PRINCIPAL_RECORD_ATTR_NAME) != null;
+        return sessionData == null ? false : 
sessionData.get(SSO_PRINCIPAL_ID_ATTR_NAME) != null;
     }
 
     public static void redirectToModule(HttpServletRequest request,
@@ -194,6 +201,13 @@
                 
.enableDefaultTyping(ObjectMapper.DefaultTyping.OBJECT_AND_NON_CONCRETE);
         mapper.getSerializationConfig().addMixInAnnotations(ExtMap.class, 
JsonExtMapMixIn.class);
         return mapper.writeValueAsString(obj);
+    }
+
+    public static Map<String, Object> readJson(String payload) throws 
IOException {
+        ObjectMapper mapper = new 
ObjectMapper().configure(Feature.FAIL_ON_UNKNOWN_PROPERTIES, false)
+                
.enableDefaultTyping(ObjectMapper.DefaultTyping.OBJECT_AND_NON_CONCRETE);
+        mapper.getDeserializationConfig().addMixInAnnotations(ExtMap.class, 
JsonExtMapMixIn.class);
+        return mapper.readValue(payload.getBytes(), HashMap.class);
     }
 
     public static String getParameter(HttpServletRequest request, String 
paramName) {
@@ -338,6 +352,23 @@
                                                            ExtensionProxy 
authz,
                                                            ExtMap authRecord,
                                                            ExtMap 
principalRecord) {
+        String validTo = authRecord.get(Authn.AuthRecord.VALID_TO);
+        String principal = 
principalRecord.get(Authz.PrincipalRecord.PRINCIPAL);
+
+        Map<String, Object> payload = new HashMap<>();
+        payload.put(USER_ID, principal != null ? principal : 
principalRecord.<String>get(Authz.PrincipalRecord.NAME));
+        payload.put(SSO_PRINCIPAL_ID_ATTR_NAME, 
principalRecord.get(Authz.PrincipalRecord.ID));
+        payload.put(SSO_EMAIL_ATTR_NAME, 
principalRecord.<String>get(Authz.PrincipalRecord.EMAIL));
+        payload.put(SSO_GROUP_IDS_ATTR_NAME, 
principalRecord.get(Authz.PrincipalRecord.GROUPS, 
Collections.<ExtMap>emptyList()));
+        payload.put(VALID_TO, StringUtils.isEmpty(validTo) ? "" + 
Integer.MAX_VALUE : validTo);
+        payload.put(SSO_PROFILE_ATTR_NAME, profileName);
+        return persistAuthInfoInContextWithToken(request, isInteractive, 
password, payload);
+    }
+
+    public static String persistAuthInfoInContextWithToken(HttpServletRequest 
request,
+                                                           boolean 
isInteractive,
+                                                           String password,
+                                                           Map<String, Object> 
payload) {
         Map<String, Object> sessionData = new HashMap<>();
         String authCode = generateAuthorizationToken();
         String accessToken = generateAuthorizationToken();
@@ -347,18 +378,16 @@
             sessionData.put(SSO_SESSION, session);
         }
 
-        String principal = 
principalRecord.get(Authz.PrincipalRecord.PRINCIPAL);
         String clientId = getClientId(request);
-        String authzName = 
authz.getContext().get(Base.ContextKeys.INSTANCE_NAME);
 
         // Info for token registry
         sessionData.put(CLIENT_ID, clientId);
         sessionData.put(ACTIVE, true);
         sessionData.put(AUTHORIZATION_CODE, authCode);
         sessionData.put(ACCESS_TOKEN, accessToken);
-        String validTo = authRecord.get(Authn.AuthRecord.VALID_TO);
-        sessionData.put(VALID_TO, StringUtils.isEmpty(validTo) ? ""+ 
Integer.MAX_VALUE : validTo);
-        sessionData.put(USER_ID, principal != null ? principal : 
principalRecord.<String>get(Authz.PrincipalRecord.NAME));
+
+        sessionData.put(VALID_TO, payload.get(VALID_TO));
+        sessionData.put(USER_ID, payload.get(USER_ID));
         sessionData.put(SCOPE, getParameter(request, SCOPE));
         if (StringUtils.isNotEmpty(password)) {
             sessionData.put(PASSWORD, password);
@@ -366,10 +395,10 @@
         sessionData.put(REDIRECT_URI, getParameter(request, REDIRECT_URI));
 
         // info for token payload
-        sessionData.put(SSO_PROFILE_ATTR_NAME, profileName);
-        sessionData.put(SSO_AUTHZ_ATTR_NAME, authzName);
-        sessionData.put(SSO_AUTH_RECORD_ATTR_NAME, authRecord);
-        sessionData.put(SSO_PRINCIPAL_RECORD_ATTR_NAME, principalRecord);
+        sessionData.put(SSO_PROFILE_ATTR_NAME, 
payload.get(SSO_PROFILE_ATTR_NAME));
+        sessionData.put(SSO_PRINCIPAL_ID_ATTR_NAME, 
payload.get(SSO_PRINCIPAL_ID_ATTR_NAME));
+        sessionData.put(SSO_EMAIL_ATTR_NAME, payload.get(SSO_EMAIL_ATTR_NAME));
+        sessionData.put(SSO_GROUP_IDS_ATTR_NAME, 
payload.get(SSO_GROUP_IDS_ATTR_NAME));
 
         sessionData.put(TOKEN_LAST_ACCESS, System.nanoTime());
         ((Map<String, Map>) 
request.getServletContext().getAttribute(SSO_SESSION_DATA)).put(accessToken, 
sessionData);
@@ -445,4 +474,24 @@
     public static List<String> scopeAsList(String scope) {
         return Arrays.asList(scope.trim().split("\\s *"));
     }
+
+    public static String encrypt(ServletContext ctx, String rawText)
+            throws IOException, GeneralSecurityException {
+
+        SSOConfig ssoConfig = (SSOConfig) ctx.getAttribute(SSO_CONFIG);
+        String certPath = 
ssoConfig.getSsoLocalConfig().getProperty("SSO_PKI_ENGINE_CERT", true);
+        if (StringUtils.isEmpty(certPath)) {
+            certPath = 
ssoConfig.getSsoLocalConfig().getProperty("ENGINE_PKI_ENGINE_CERT");
+        }
+
+        Certificate cert;
+        try (InputStream in = new FileInputStream(new File(certPath))) {
+            cert = 
CertificateFactory.getInstance("X.509").generateCertificate(in);
+        }
+
+        Cipher cipher = Cipher.getInstance("RSA");
+        cipher.init(Cipher.ENCRYPT_MODE, cert.getPublicKey());
+
+        return 
Base64.encodeBase64String(cipher.doFinal(rawText.getBytes("UTF-8")));
+    }
 }


-- 
To view, visit https://gerrit.ovirt.org/42291
To unsubscribe, visit https://gerrit.ovirt.org/settings

Gerrit-MessageType: newchange
Gerrit-Change-Id: I1422774b0fbf52a59299f521ad92c6d576f7a1b2
Gerrit-PatchSet: 1
Gerrit-Project: ovirt-engine
Gerrit-Branch: master
Gerrit-Owner: Ravi Nori <rn...@redhat.com>
_______________________________________________
Engine-patches mailing list
Engine-patches@ovirt.org
http://lists.ovirt.org/mailman/listinfo/engine-patches

Reply via email to