portals-jetspeed-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From a..@apache.org
Subject svn commit: r418604 - in /portals/jetspeed-2/trunk: components/portal/src/java/org/apache/jetspeed/security/impl/ components/security/src/java/org/apache/jetspeed/security/spi/ components/security/src/java/org/apache/jetspeed/security/spi/impl/ jetspee...
Date Sun, 02 Jul 2006 15:10:19 GMT
Author: ate
Date: Sun Jul  2 08:10:18 2006
New Revision: 418604

URL: http://svn.apache.org/viewvc?rev=418604&view=rev
Log:
JS2-550: A new Two-way password encoding service allowing decoding of encoded passwords
This set of changes provides a further enhancement providing a way to lazy upgrade from one
encoding scheme to another.
Furthermore, a few improvements in handling of InternalCredential timestamp properties.
See: http://issues.apache.org/jira/browse/JS2-550#action_12418846

Added:
    portals/jetspeed-2/trunk/components/security/src/java/org/apache/jetspeed/security/spi/AlgorithmUpgradeCredentialPasswordEncoder.java
    portals/jetspeed-2/trunk/components/security/src/java/org/apache/jetspeed/security/spi/impl/AlgorithmUpgradePBEPasswordService.java
    portals/jetspeed-2/trunk/jetspeed-api/src/java/org/apache/jetspeed/security/AlgorithmUpgradePasswordEncodingService.java
Modified:
    portals/jetspeed-2/trunk/components/portal/src/java/org/apache/jetspeed/security/impl/PasswordCredentialValveImpl.java
    portals/jetspeed-2/trunk/components/security/src/java/org/apache/jetspeed/security/spi/impl/DefaultCredentialHandler.java
    portals/jetspeed-2/trunk/src/webapp/WEB-INF/assembly/security-spi-atn.xml

Modified: portals/jetspeed-2/trunk/components/portal/src/java/org/apache/jetspeed/security/impl/PasswordCredentialValveImpl.java
URL: http://svn.apache.org/viewvc/portals/jetspeed-2/trunk/components/portal/src/java/org/apache/jetspeed/security/impl/PasswordCredentialValveImpl.java?rev=418604&r1=418603&r2=418604&view=diff
==============================================================================
--- portals/jetspeed-2/trunk/components/portal/src/java/org/apache/jetspeed/security/impl/PasswordCredentialValveImpl.java
(original)
+++ portals/jetspeed-2/trunk/components/portal/src/java/org/apache/jetspeed/security/impl/PasswordCredentialValveImpl.java
Sun Jul  2 08:10:18 2006
@@ -102,6 +102,7 @@
                     {
                         request.setSessionAttribute(CHECKED_KEY,Boolean.TRUE);
                         if ( pwdCredential.getPreviousAuthenticationDate() != null &&

+                                pwdCredential.getLastAuthenticationDate() != null &&
                                 pwdCredential.getExpirationDate() != null )
                         {
                             long expirationTime = pwdCredential.getExpirationDate().getTime();

Added: portals/jetspeed-2/trunk/components/security/src/java/org/apache/jetspeed/security/spi/AlgorithmUpgradeCredentialPasswordEncoder.java
URL: http://svn.apache.org/viewvc/portals/jetspeed-2/trunk/components/security/src/java/org/apache/jetspeed/security/spi/AlgorithmUpgradeCredentialPasswordEncoder.java?rev=418604&view=auto
==============================================================================
--- portals/jetspeed-2/trunk/components/security/src/java/org/apache/jetspeed/security/spi/AlgorithmUpgradeCredentialPasswordEncoder.java
(added)
+++ portals/jetspeed-2/trunk/components/security/src/java/org/apache/jetspeed/security/spi/AlgorithmUpgradeCredentialPasswordEncoder.java
Sun Jul  2 08:10:18 2006
@@ -0,0 +1,42 @@
+/* Copyright 2004 Apache Software Foundation
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+*     http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+package org.apache.jetspeed.security.spi;
+
+import org.apache.jetspeed.security.PasswordCredential;
+import org.apache.jetspeed.security.SecurityException;
+import org.apache.jetspeed.security.om.InternalCredential;
+
+/**
+ * <p>
+ * AlgorithmUpgradeCredentialPasswordEncoder which is provided with the InternalCredential
as well
+ * to allow for migrating between two different encoding schemes.
+ * </p>
+ * <p>
+ * The extended encode method is *only* called in the context of validating an existing (old)
password,
+ * and not used for creating or updating to a new password directl!
+ * </p>
+ * <p>
+ * After successfull authentication, the recodeIfNeeded method will be called allowing to
migrate to the new encryption scheme.
+ * </p>
+ * 
+ * @author <a href="mailto:ate@douma.nu">Ate Douma</a>
+ * @version $Id$
+ */
+public interface AlgorithmUpgradeCredentialPasswordEncoder extends CredentialPasswordEncoder
+{
+    String encode(String userName, String clearTextPassword, InternalCredential credential)
throws SecurityException;
+    void recodeIfNeeded(String userName, String clearTextPassword, InternalCredential credential)
throws SecurityException;
+    boolean usesOldEncodingAlgorithm(PasswordCredential credential);
+}

Added: portals/jetspeed-2/trunk/components/security/src/java/org/apache/jetspeed/security/spi/impl/AlgorithmUpgradePBEPasswordService.java
URL: http://svn.apache.org/viewvc/portals/jetspeed-2/trunk/components/security/src/java/org/apache/jetspeed/security/spi/impl/AlgorithmUpgradePBEPasswordService.java?rev=418604&view=auto
==============================================================================
--- portals/jetspeed-2/trunk/components/security/src/java/org/apache/jetspeed/security/spi/impl/AlgorithmUpgradePBEPasswordService.java
(added)
+++ portals/jetspeed-2/trunk/components/security/src/java/org/apache/jetspeed/security/spi/impl/AlgorithmUpgradePBEPasswordService.java
Sun Jul  2 08:10:18 2006
@@ -0,0 +1,112 @@
+/* Copyright 2004 Apache Software Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.jetspeed.security.spi.impl;
+
+import java.security.NoSuchAlgorithmException;
+import java.security.spec.InvalidKeySpecException;
+import java.sql.Timestamp;
+import java.text.ParseException;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+
+import org.apache.jetspeed.security.AlgorithmUpgradePasswordEncodingService;
+import org.apache.jetspeed.security.PasswordCredential;
+import org.apache.jetspeed.security.SecurityException;
+import org.apache.jetspeed.security.om.InternalCredential;
+import org.apache.jetspeed.security.spi.AlgorithmUpgradeCredentialPasswordEncoder;
+import org.apache.jetspeed.security.spi.CredentialPasswordEncoder;
+
+/**
+ * <p>
+ * MessageDigestToPBEPasswordUpgradeService allows for migrating from a MessageDigestCredentialPasswordEncoder
+ * to the PBEPasswordService
+ * </p>
+ * 
+ * @author <a href="mailto:ate@douma.nu">Ate Douma</a>
+ * @version $Id:$
+ */
+public class AlgorithmUpgradePBEPasswordService extends PBEPasswordService implements AlgorithmUpgradeCredentialPasswordEncoder,
AlgorithmUpgradePasswordEncodingService
+{
+    private CredentialPasswordEncoder oldEncoder;
+    private Timestamp startPBEPasswordEncoding;
+    
+    public AlgorithmUpgradePBEPasswordService(String pbePassword, CredentialPasswordEncoder
oldEncoder, String startPBEPasswordEncoding) throws InvalidKeySpecException,
+            NoSuchAlgorithmException, ParseException
+    {
+        super(pbePassword);
+        this.oldEncoder = oldEncoder;
+        SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
+        this.startPBEPasswordEncoding = new Timestamp(df.parse(startPBEPasswordEncoding).getTime());
+    }
+    
+    /* (non-Javadoc)
+     * @see org.apache.jetspeed.security.AlgorithmUpgradePasswordEncodingService#usesOldEncodingAlgorithm(org.apache.jetspeed.security.PasswordCredential)
+     */
+    public boolean usesOldEncodingAlgorithm(PasswordCredential credential)
+    {
+        return usesOldEncodingAlgorithm(credential.isEnabled(), credential.getLastAuthenticationDate(),
credential.getPreviousAuthenticationDate());
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.jetspeed.security.spi.AlgorithmUpgradeCredentialPasswordEncoder#encode(java.lang.String,
java.lang.String, org.apache.jetspeed.security.om.InternalCredential)
+     */
+    public String encode(String userName, String clearTextPassword, InternalCredential credential)
throws SecurityException
+    {
+        if ( usesOldEncodingAlgorithm(credential.isEnabled(), credential.getLastAuthenticationDate(),
credential.getPreviousAuthenticationDate()))
+        {
+            return oldEncoder.encode(userName, clearTextPassword);
+        }
+        else
+        {
+            return encode(userName, clearTextPassword);
+        }
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.jetspeed.security.spi.AlgorithmUpgradeCredentialPasswordEncoder#recodeIfNeeded(java.lang.String,
java.lang.String, org.apache.jetspeed.security.om.InternalCredential)
+     */
+    public void recodeIfNeeded(String userName, String clearTextPassword, InternalCredential
credential) throws SecurityException
+    {
+        if ( usesOldEncodingAlgorithm(credential.isEnabled(), credential.getLastAuthenticationDate(),
credential.getPreviousAuthenticationDate()))
+        {
+            credential.setValue(encode(userName, clearTextPassword));
+        }
+    }
+    
+    private boolean usesOldEncodingAlgorithm(boolean encoded, Timestamp lastAuthDate, Timestamp
prevAuthDate )
+    {
+        if ( encoded )
+        {
+            if ( lastAuthDate != null )
+            {
+                return lastAuthDate.before(startPBEPasswordEncoding);
+            }
+            else if ( prevAuthDate != null )
+            {
+                // password was created, but the user is not authenticated yet
+                return prevAuthDate.before(startPBEPasswordEncoding);
+            }
+            else
+            {
+                // not yet upgraded encoded password
+                return true;
+            }
+        }
+        else
+        {
+            return false;
+        }
+    }
+}

Modified: portals/jetspeed-2/trunk/components/security/src/java/org/apache/jetspeed/security/spi/impl/DefaultCredentialHandler.java
URL: http://svn.apache.org/viewvc/portals/jetspeed-2/trunk/components/security/src/java/org/apache/jetspeed/security/spi/impl/DefaultCredentialHandler.java?rev=418604&r1=418603&r2=418604&view=diff
==============================================================================
--- portals/jetspeed-2/trunk/components/security/src/java/org/apache/jetspeed/security/spi/impl/DefaultCredentialHandler.java
(original)
+++ portals/jetspeed-2/trunk/components/security/src/java/org/apache/jetspeed/security/spi/impl/DefaultCredentialHandler.java
Sun Jul  2 08:10:18 2006
@@ -32,6 +32,7 @@
 import org.apache.jetspeed.security.om.InternalUserPrincipal;
 import org.apache.jetspeed.security.om.impl.InternalCredentialImpl;
 import org.apache.jetspeed.security.spi.CredentialHandler;
+import org.apache.jetspeed.security.spi.AlgorithmUpgradeCredentialPasswordEncoder;
 import org.apache.jetspeed.security.spi.InternalPasswordCredentialInterceptor;
 import org.apache.jetspeed.security.spi.PasswordCredentialProvider;
 import org.apache.jetspeed.security.spi.SecurityAccess;
@@ -157,7 +158,14 @@
                     credential.isEncoded() && 
                     pcProvider.getEncoder() != null )
             {
-                oldPassword = pcProvider.getEncoder().encode(userName, oldPassword);
+                if ( pcProvider.getEncoder() instanceof AlgorithmUpgradeCredentialPasswordEncoder
)
+                {
+                    oldPassword = ((AlgorithmUpgradeCredentialPasswordEncoder)pcProvider.getEncoder()).encode(userName,oldPassword,
credential);
+                }
+                else
+                {
+                    oldPassword = pcProvider.getEncoder().encode(userName,oldPassword);
+                }
             }
         }
         
@@ -219,6 +227,7 @@
                 ipcInterceptor.beforeSetPassword(internalUser, credentials, userName, credential,
newPassword, oldPassword != null );
             }
         }
+        
         if (!create)
         {
             credential.setValue(newPassword);
@@ -226,7 +235,27 @@
             credential.setUpdateRequired(false);
         }
                 
-        internalUser.setModifiedDate(new Timestamp(new Date().getTime()));
+        long time = new Date().getTime();
+        
+        if ( oldPassword == null )
+        {
+            // non-user (admin) modified the password
+            
+            // set current time in previous auth date, and clear last authentication date
+            // !!! While this might be a bit strange logic, it is *required* for the AlgorithmUpgradePBEPasswordEncodingService
+            // to be able to distinguise password changes from other changes
+            credential.setPreviousAuthenticationDate(new Timestamp(new Date().getTime()));
+            credential.setLastAuthenticationDate(null);
+        }
+        else
+        {
+            // authenticated password change (by user itself)
+            credential.setPreviousAuthenticationDate(credential.getLastAuthenticationDate());
+            credential.setLastAuthenticationDate(new Timestamp(time));
+        }
+        
+        credential.setModifiedDate(new Timestamp(time));
+        internalUser.setModifiedDate(new Timestamp(time));
         internalUser.setCredentials(credentials);
         // Set the user with the new credentials.
         securityAccess.setInternalUserPrincipal(internalUser, false);
@@ -244,9 +273,11 @@
             InternalCredential credential = getPasswordCredential(internalUser, userName
);
             if ( credential != null && !credential.isExpired() && credential.isEnabled()
!= enabled )
             {
+                long time = new Date().getTime();
                 credential.setEnabled(enabled);
                 credential.setAuthenticationFailures(0);
-                internalUser.setModifiedDate(new Timestamp(new Date().getTime()));
+                credential.setModifiedDate(new Timestamp(time));
+                internalUser.setModifiedDate(new Timestamp(time));
                 securityAccess.setInternalUserPrincipal(internalUser, false);
             }
         }
@@ -280,6 +311,7 @@
                 // The current InternalPasswordCredentialStateHandlingInterceptor.afterLoad()
                 // logic will only set it (back) to true if both prev and last auth. date
is null
                 credential.setPreviousAuthenticationDate(new Timestamp(time));
+                credential.setModifiedDate(new Timestamp(time));
                 internalUser.setModifiedDate(new Timestamp(time));
                 securityAccess.setInternalUserPrincipal(internalUser, false);
             }
@@ -335,12 +367,20 @@
             InternalCredential credential = getPasswordCredential(internalUser, userName
);
             if ( credential != null && credential.isEnabled() && !credential.isExpired())
             {
+                String encodedPassword = password;
                 if ( pcProvider.getEncoder() != null && credential.isEncoded())
                 {
-                    password = pcProvider.getEncoder().encode(userName,password);
+                    if ( pcProvider.getEncoder() instanceof AlgorithmUpgradeCredentialPasswordEncoder
)
+                    {
+                        encodedPassword = ((AlgorithmUpgradeCredentialPasswordEncoder)pcProvider.getEncoder()).encode(userName,password,
credential);
+                    }
+                    else
+                    {
+                        encodedPassword = pcProvider.getEncoder().encode(userName,password);
+                    }
                 }
 
-                authenticated = credential.getValue().equals(password);
+                authenticated = credential.getValue().equals(encodedPassword);
                 boolean update = false;
 
                 if ( ipcInterceptor != null )
@@ -351,17 +391,26 @@
                         authenticated = false;
                     }
                 }
+                long time = new Date().getTime();
+                
                 if ( authenticated )
                 {
                     credential.setAuthenticationFailures(0);
+
+                    if ( pcProvider.getEncoder() != null && pcProvider.getEncoder()
instanceof AlgorithmUpgradeCredentialPasswordEncoder)
+                    {
+                        ((AlgorithmUpgradeCredentialPasswordEncoder)pcProvider.getEncoder()).recodeIfNeeded(userName,password,credential);
+                    }
+                    
                     credential.setPreviousAuthenticationDate(credential.getLastAuthenticationDate());
-                    credential.setLastAuthenticationDate(new Timestamp(System.currentTimeMillis()));
+                    credential.setLastAuthenticationDate(new Timestamp(time));
                     update = true;
                 }
                 
                 if ( update )
                 {
-                    internalUser.setModifiedDate(new Timestamp(System.currentTimeMillis()));
+                    credential.setModifiedDate(new Timestamp(time));
+                    internalUser.setModifiedDate(new Timestamp(time));
                     securityAccess.setInternalUserPrincipal(internalUser, false);
                 }
             }

Added: portals/jetspeed-2/trunk/jetspeed-api/src/java/org/apache/jetspeed/security/AlgorithmUpgradePasswordEncodingService.java
URL: http://svn.apache.org/viewvc/portals/jetspeed-2/trunk/jetspeed-api/src/java/org/apache/jetspeed/security/AlgorithmUpgradePasswordEncodingService.java?rev=418604&view=auto
==============================================================================
--- portals/jetspeed-2/trunk/jetspeed-api/src/java/org/apache/jetspeed/security/AlgorithmUpgradePasswordEncodingService.java
(added)
+++ portals/jetspeed-2/trunk/jetspeed-api/src/java/org/apache/jetspeed/security/AlgorithmUpgradePasswordEncodingService.java
Sun Jul  2 08:10:18 2006
@@ -0,0 +1,30 @@
+/* Copyright 2004 Apache Software Foundation
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+*     http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+package org.apache.jetspeed.security;
+
+/**
+ * <p>
+ * AlgorithmUpgradePasswordEncodingService allows checking a specific PasswordCredential
if it uses the provided Encoding Algorithm.
+ * </p>
+ * <p>
+ * This service can be used for gradually migrating from a one-way encoding to a two-way
encoding algoritmn.
+ * </p>
+ * @author <a href="mailto:ate@douma.nu">Ate Douma</a>
+ * @version $Id$
+ */
+public interface AlgorithmUpgradePasswordEncodingService extends PasswordEncodingService
+{
+    boolean usesOldEncodingAlgorithm(PasswordCredential passwordCredential);
+}

Modified: portals/jetspeed-2/trunk/src/webapp/WEB-INF/assembly/security-spi-atn.xml
URL: http://svn.apache.org/viewvc/portals/jetspeed-2/trunk/src/webapp/WEB-INF/assembly/security-spi-atn.xml?rev=418604&r1=418603&r2=418604&view=diff
==============================================================================
--- portals/jetspeed-2/trunk/src/webapp/WEB-INF/assembly/security-spi-atn.xml (original)
+++ portals/jetspeed-2/trunk/src/webapp/WEB-INF/assembly/security-spi-atn.xml Sun Jul  2 08:10:18
2006
@@ -47,6 +47,32 @@
   </bean>       
 -->
 
+ <!-- A Two-way encoding password service which also implements CredentialPasswordEncoder
+       Furthermore, this extension of the PBEPasswordService supports lazy upgrading from
an old CredentialPasswordEncoder
+       like the default provided MessageDigestCredentialPasswordEncoder
+  ->
+  <bean id="org.apache.jetspeed.security.PasswordEncodingService"
+        name="org.apache.jetspeed.security.spi.CredentialPasswordEncoder"
+        class="org.apache.jetspeed.security.spi.impl.AlgorithmUpgradePBEPasswordService">
+    <constructor-arg index="0">
+      <!- secret PBE key password ->
+      <value>********</value>
+    </constructor-arg>
+    <constructor-arg index="1">
+      <!- old MessageDigestCredentialPasswordEncoder to be upgrading from, using SHA-1
->
+      <bean class="org.apache.jetspeed.security.spi.impl.MessageDigestCredentialPasswordEncoder">
+       <constructor-arg index="0"><value>SHA-1</value></constructor-arg>
      
+      </bean>       
+    </constructor-arg>
+    <constructor-arg index="2">
+      <!- startPBEPasswordEncodingService: date before which old encoded passwords need
to be recoded (on authentication)
+           (SimpleDateFormat) format: yyyy-MM-dd HH:mm:ss
+      ->
+      <value>2006-07-02 15:00:00</value>
+    </constructor-arg>
+  </bean>
+-->
+
   <!-- allow multiple InternalPasswordCredentialInterceptors to be used for DefaultCredentialHandler
--> 
   <bean id="org.apache.jetspeed.security.spi.InternalPasswordCredentialInterceptor"
        class="org.apache.jetspeed.security.spi.impl.InternalPasswordCredentialInterceptorsProxy">



---------------------------------------------------------------------
To unsubscribe, e-mail: jetspeed-dev-unsubscribe@portals.apache.org
For additional commands, e-mail: jetspeed-dev-help@portals.apache.org


Mime
View raw message