[jboss-cvs] Picketlink SVN: r744 - in federation/trunk: picketlink-fed-core/src/main/java/org/picketlink/identity/federation/core/factories and 3 other directories.

jboss-cvs-commits at lists.jboss.org jboss-cvs-commits at lists.jboss.org
Mon Feb 7 22:52:00 EST 2011


Author: anil.saldhana at jboss.com
Date: 2011-02-07 22:51:59 -0500 (Mon, 07 Feb 2011)
New Revision: 744

Added:
   federation/trunk/picketlink-fed-core/src/main/java/org/picketlink/identity/federation/core/factories/JBossAuthCacheInvalidationFactory.java
   federation/trunk/picketlink-fed-core/src/main/java/org/picketlink/identity/federation/core/factories/SecurityActions.java
Modified:
   federation/trunk/picketlink-bindings-jboss/src/main/java/org/picketlink/identity/federation/bindings/jboss/auth/SAML2STSLoginModule.java
   federation/trunk/picketlink-bindings-jboss/src/main/java/org/picketlink/identity/federation/bindings/jboss/auth/SecurityActions.java
   federation/trunk/picketlink-fed-core/src/main/java/org/picketlink/identity/federation/core/saml/v2/util/AssertionUtil.java
   federation/trunk/picketlink-fed-core/src/main/java/org/picketlink/identity/federation/core/wstrust/auth/AbstractSTSLoginModule.java
   federation/trunk/picketlink-fed-core/src/main/java/org/picketlink/identity/federation/core/wstrust/plugins/saml/SAMLUtil.java
Log:
PLFED-132: register to expire the JBoss Auth Cache when saml principal expires

Modified: federation/trunk/picketlink-bindings-jboss/src/main/java/org/picketlink/identity/federation/bindings/jboss/auth/SAML2STSLoginModule.java
===================================================================
--- federation/trunk/picketlink-bindings-jboss/src/main/java/org/picketlink/identity/federation/bindings/jboss/auth/SAML2STSLoginModule.java	2011-02-07 23:17:31 UTC (rev 743)
+++ federation/trunk/picketlink-bindings-jboss/src/main/java/org/picketlink/identity/federation/bindings/jboss/auth/SAML2STSLoginModule.java	2011-02-08 03:51:59 UTC (rev 744)
@@ -32,11 +32,16 @@
 import javax.security.auth.callback.Callback;
 import javax.security.auth.callback.CallbackHandler;
 import javax.security.auth.login.LoginException;
+import javax.xml.datatype.XMLGregorianCalendar;
 
+import org.jboss.security.SecurityConstants;
 import org.jboss.security.auth.callback.ObjectCallback;
 import org.jboss.security.auth.spi.AbstractServerLoginModule;
 import org.picketlink.identity.federation.bindings.jboss.subject.PicketLinkGroup;
 import org.picketlink.identity.federation.bindings.jboss.subject.PicketLinkPrincipal;
+import org.picketlink.identity.federation.core.factories.JBossAuthCacheInvalidationFactory;
+import org.picketlink.identity.federation.core.factories.JBossAuthCacheInvalidationFactory.TimeCacheExpiry;
+import org.picketlink.identity.federation.core.saml.v2.util.AssertionUtil;
 import org.picketlink.identity.federation.core.wstrust.STSClient;
 import org.picketlink.identity.federation.core.wstrust.STSClientConfig.Builder;
 import org.picketlink.identity.federation.core.wstrust.SamlCredential;
@@ -59,11 +64,16 @@
  * and included in the {@code Group} returned by the {@code getRoleSets} method.
  * </p>
  * <p>
- * This module defines one module option:
+ * This module defines module options:
  * <li>
  *  <ul>configFile - this property identifies the properties file that will be used to establish communication with
  *  the external security token service.
  *  </ul>
+ *  <ul>cache.invalidation:  set it to true if you require invalidation of JBoss Auth Cache at SAML Principal expiration.
+ *  </ul>
+ *  <ul>jboss.security.security_domain: name of the security domain where this login module is configured. This is only required
+ *  if the cache.invalidation option is configured.
+ *  </ul>
  * </li>
  * An example of a {@code configFile} can be seen bellow:
  * <pre>
@@ -82,6 +92,7 @@
  * </p>
  * 
  * @author <a href="mailto:sguilhen at redhat.com">Stefan Guilhen</a>
+ * @author Anil.Saldhana at redhat.com
  */
 @SuppressWarnings("unchecked")
 public class SAML2STSLoginModule extends AbstractServerLoginModule
@@ -95,6 +106,10 @@
 
    protected AssertionType assertion;
 
+   protected boolean enableCacheInvalidation = false;
+   
+   protected String securityDomain = null;
+   
    /*
     * (non-Javadoc)
     * @see org.jboss.security.auth.spi.AbstractServerLoginModule#initialize(javax.security.auth.Subject, javax.security.auth.callback.CallbackHandler, java.util.Map, java.util.Map)
@@ -106,6 +121,16 @@
       super.initialize(subject, callbackHandler, sharedState, options);
       // check if the options contain the name of the STS configuration file.
       this.stsConfigurationFile = (String) options.get("configFile");
+      
+      String cacheInvalidation = (String) options.get( "cache.invalidation" );
+      if( cacheInvalidation != null && !cacheInvalidation.isEmpty() )
+      {
+         enableCacheInvalidation = Boolean.parseBoolean( cacheInvalidation );
+         securityDomain = (String) options.get( SecurityConstants.SECURITY_DOMAIN_OPTION );
+         if( securityDomain == null || securityDomain.isEmpty() )
+            throw new RuntimeException( "Please configure option:" + SecurityConstants.SECURITY_DOMAIN_OPTION );
+      }
+      
    }
 
    /*
@@ -191,17 +216,22 @@
             {
                NameIDType nameID = (NameIDType) baseID;
                this.principal = new PicketLinkPrincipal(nameID.getValue()); 
-            }
                
-            /*for (JAXBElement<?> element : subject.getContent())
-            {
-               if (element.getDeclaredType().equals(NameIDType.class))
+               //If the user has configured cache invalidation of subject based on saml token expiry
+               if( enableCacheInvalidation )
                {
-                  NameIDType nameID = (NameIDType) element.getValue();
-                  this.principal = new PicketLinkPrincipal(nameID.getValue());
-                  break;
+                  TimeCacheExpiry cacheExpiry = JBossAuthCacheInvalidationFactory.getCacheExpiry();
+                  XMLGregorianCalendar expiry = AssertionUtil.getExpiration( assertion );
+                  if( expiry != null )
+                  {
+                     cacheExpiry.register( securityDomain, expiry.toGregorianCalendar().getTime() , principal );
+                  } 
+                  else
+                  {
+                     log.warn( "SAML Assertion has been found to have no expiration: ID = " + assertion.getID() );
+                  }
                }
-            }*/
+            }
          }
       }
       catch (Exception e)

Modified: federation/trunk/picketlink-bindings-jboss/src/main/java/org/picketlink/identity/federation/bindings/jboss/auth/SecurityActions.java
===================================================================
--- federation/trunk/picketlink-bindings-jboss/src/main/java/org/picketlink/identity/federation/bindings/jboss/auth/SecurityActions.java	2011-02-07 23:17:31 UTC (rev 743)
+++ federation/trunk/picketlink-bindings-jboss/src/main/java/org/picketlink/identity/federation/bindings/jboss/auth/SecurityActions.java	2011-02-08 03:51:59 UTC (rev 744)
@@ -35,13 +35,12 @@
  * @version $Revision: 1 $
  */
 class SecurityActions
-{
-   @SuppressWarnings({"rawtypes", "unchecked"})
+{ 
    static SecurityContext createSecurityContext() throws PrivilegedActionException
    {
-      return (SecurityContext) AccessController.doPrivileged(new PrivilegedExceptionAction()
+      return AccessController.doPrivileged(new PrivilegedExceptionAction<SecurityContext>()
       {
-         public Object run() throws Exception
+         public SecurityContext run() throws Exception
          {
             return SecurityContextFactory.createSecurityContext("CLIENT");
          }

Added: federation/trunk/picketlink-fed-core/src/main/java/org/picketlink/identity/federation/core/factories/JBossAuthCacheInvalidationFactory.java
===================================================================
--- federation/trunk/picketlink-fed-core/src/main/java/org/picketlink/identity/federation/core/factories/JBossAuthCacheInvalidationFactory.java	                        (rev 0)
+++ federation/trunk/picketlink-fed-core/src/main/java/org/picketlink/identity/federation/core/factories/JBossAuthCacheInvalidationFactory.java	2011-02-08 03:51:59 UTC (rev 744)
@@ -0,0 +1,120 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2008, Red Hat Middleware LLC, and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors. 
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.picketlink.identity.federation.core.factories;
+
+import java.security.Principal;
+import java.util.Date;
+import java.util.Timer;
+import java.util.TimerTask;
+
+import javax.management.MBeanServer;
+import javax.management.ObjectName;
+
+/**
+ * <p>
+ * A factory that is used to obtain an expiration policy of type {@link TimeCacheExpiry}
+ * </p>
+ * <p>
+ * Primarily used to expire the SAML Principal in the JAAS Subject cached in the JBoss Auth Cache.
+ * </p>
+ * @author Anil.Saldhana at redhat.com
+ * @since Feb 7, 2011
+ */
+public class JBossAuthCacheInvalidationFactory
+{
+   /**
+    * Get an instance of {@link TimeCacheExpiry}
+    * @return
+    */
+   public static TimeCacheExpiry getCacheExpiry()
+   {
+      return ExpiringPrincipalCacheInvalidation.get();
+   }
+   
+   public interface TimeCacheExpiry
+   {
+      /**
+       * Register a Principal that has an expiry at {@link Date}
+       * @param securityDomain the security domain under which the principal may be cached in a subject
+       * @param expiry when to expire the principal and hence the subject
+       * @param principal the principal which needs to be expired
+       */
+      void register( String securityDomain, Date expiry, Principal principal );
+   }
+   
+   protected static class ExpiringPrincipalCacheInvalidation implements TimeCacheExpiry
+   {
+      protected static ExpiringPrincipalCacheInvalidation _instance = null;
+      
+      protected static String objectName = "jboss.security:service=JaasSecurityManager";
+      
+      protected static Timer timer = new Timer();
+      
+      protected ExpiringPrincipalCacheInvalidation()
+      { 
+      }
+      
+      protected static ExpiringPrincipalCacheInvalidation get()
+      {
+         if( _instance == null )
+            _instance = new ExpiringPrincipalCacheInvalidation();
+         return _instance;
+      }
+      
+      protected static void setObjectName( String oName )
+      {
+         objectName = oName;
+      }
+      
+      public void register( final String securityDomain, final Date expiry, final Principal principal )
+      { 
+         try
+         {  
+            timer.schedule( new TimerTask()
+            { 
+               @Override
+               public void run()
+               {
+                  try
+                  {
+                     ObjectName on = new ObjectName( objectName );
+                     MBeanServer server = SecurityActions.getJBossMBeanServer();
+                     Object[] obj = new Object[] { securityDomain, principal };
+                     String[] sig = new String[]{ "java.lang.String", "java.security.Principal" }; 
+                     
+                     //Flush the Authentication Cache
+                     server.invoke( on,"flushAuthenticationCache", obj, sig ); 
+                  }
+                  catch ( Exception e)
+                  {
+                     throw new RuntimeException( e );
+                  }
+               }
+            }, expiry );
+         }
+         catch ( Exception e )
+         {
+            throw new RuntimeException( e );
+         }      
+      } 
+   }
+}
\ No newline at end of file

Added: federation/trunk/picketlink-fed-core/src/main/java/org/picketlink/identity/federation/core/factories/SecurityActions.java
===================================================================
--- federation/trunk/picketlink-fed-core/src/main/java/org/picketlink/identity/federation/core/factories/SecurityActions.java	                        (rev 0)
+++ federation/trunk/picketlink-fed-core/src/main/java/org/picketlink/identity/federation/core/factories/SecurityActions.java	2011-02-08 03:51:59 UTC (rev 744)
@@ -0,0 +1,65 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2008, Red Hat Middleware LLC, and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors. 
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.picketlink.identity.federation.core.factories;
+
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+import java.security.PrivilegedActionException;
+import java.security.PrivilegedExceptionAction;
+
+import javax.management.MBeanServer;
+import javax.management.MBeanServerFactory;
+
+import org.jboss.security.SecurityContext;
+import org.jboss.security.SecurityContextFactory;
+
+/**
+ * Privileged blocks
+ * 
+ * @author <a href="mmoyses at redhat.com">Marcus Moyses</a>
+ * @version $Revision: 1 $
+ */
+class SecurityActions
+{ 
+   static SecurityContext createSecurityContext() throws PrivilegedActionException
+   {
+      return AccessController.doPrivileged(new PrivilegedExceptionAction<SecurityContext>()
+      {
+         public SecurityContext run() throws Exception
+         {
+            return SecurityContextFactory.createSecurityContext("CLIENT");
+         }
+      });
+   }
+   
+   static MBeanServer getJBossMBeanServer()
+   {
+      return AccessController.doPrivileged( new PrivilegedAction<MBeanServer>() 
+      { 
+         public MBeanServer run()
+         { 
+            return MBeanServerFactory.findMBeanServer( "jboss").get( 0 );
+         }
+      });
+      
+   }
+}
\ No newline at end of file


Property changes on: federation/trunk/picketlink-fed-core/src/main/java/org/picketlink/identity/federation/core/factories/SecurityActions.java
___________________________________________________________________
Name: svn:executable
   + *

Modified: federation/trunk/picketlink-fed-core/src/main/java/org/picketlink/identity/federation/core/saml/v2/util/AssertionUtil.java
===================================================================
--- federation/trunk/picketlink-fed-core/src/main/java/org/picketlink/identity/federation/core/saml/v2/util/AssertionUtil.java	2011-02-07 23:17:31 UTC (rev 743)
+++ federation/trunk/picketlink-fed-core/src/main/java/org/picketlink/identity/federation/core/saml/v2/util/AssertionUtil.java	2011-02-08 03:51:59 UTC (rev 744)
@@ -161,4 +161,21 @@
       //TODO: if conditions do not exist, assume the assertion to be everlasting?
       return false; 
    } 
+   
+   /**
+    * Extract the expiration time from an {@link AssertionType}
+    * @param assertion
+    * @return
+    */
+   public static XMLGregorianCalendar getExpiration( AssertionType assertion )
+   {
+      XMLGregorianCalendar expiry = null;
+      
+      ConditionsType conditionsType = assertion.getConditions();
+      if(conditionsType != null)
+      {
+         expiry = conditionsType.getNotOnOrAfter();
+      }
+      return expiry; 
+   }
 }
\ No newline at end of file

Modified: federation/trunk/picketlink-fed-core/src/main/java/org/picketlink/identity/federation/core/wstrust/auth/AbstractSTSLoginModule.java
===================================================================
--- federation/trunk/picketlink-fed-core/src/main/java/org/picketlink/identity/federation/core/wstrust/auth/AbstractSTSLoginModule.java	2011-02-07 23:17:31 UTC (rev 743)
+++ federation/trunk/picketlink-fed-core/src/main/java/org/picketlink/identity/federation/core/wstrust/auth/AbstractSTSLoginModule.java	2011-02-08 03:51:59 UTC (rev 744)
@@ -34,8 +34,10 @@
 import javax.security.auth.callback.UnsupportedCallbackException;
 import javax.security.auth.login.LoginException;
 import javax.security.auth.spi.LoginModule;
+import javax.xml.datatype.XMLGregorianCalendar;
 
 import org.apache.log4j.Logger;
+import org.jboss.security.SecurityConstants;
 import org.jboss.security.SecurityContext;
 import org.jboss.security.SimpleGroup;
 import org.jboss.security.SimplePrincipal;
@@ -45,12 +47,17 @@
 import org.jboss.security.mapping.MappingManager;
 import org.jboss.security.mapping.MappingType;
 import org.picketlink.identity.federation.core.exceptions.ParsingException;
+import org.picketlink.identity.federation.core.factories.JBossAuthCacheInvalidationFactory;
+import org.picketlink.identity.federation.core.factories.JBossAuthCacheInvalidationFactory.TimeCacheExpiry;
+import org.picketlink.identity.federation.core.saml.v2.util.AssertionUtil;
 import org.picketlink.identity.federation.core.wstrust.STSClient;
 import org.picketlink.identity.federation.core.wstrust.STSClientConfig;
 import org.picketlink.identity.federation.core.wstrust.STSClientConfig.Builder;
 import org.picketlink.identity.federation.core.wstrust.STSClientFactory;
 import org.picketlink.identity.federation.core.wstrust.SamlCredential;
 import org.picketlink.identity.federation.core.wstrust.WSTrustException;
+import org.picketlink.identity.federation.core.wstrust.plugins.saml.SAMLUtil;
+import org.picketlink.identity.federation.newmodel.saml.v2.assertion.AssertionType;
 import org.w3c.dom.Element;
 
 /**
@@ -143,7 +150,12 @@
  *                     from "Roles".
  * </p>
  * 
+ * <p>cache.invalidation:  set it to true if you require invalidation of JBoss Auth Cache at SAML Principal expiration.</p>
+ *  <p>jboss.security.security_domain: name of the security domain where this login module is configured. This is only required
+ *  if the cache.invalidation option is configured.</p>
+ * 
  * @author <a href="mailto:dbevenius at jboss.com">Daniel Bevenius</a>
+ * @author Anil.Saldhana at redhat.com
  */
 public abstract class AbstractSTSLoginModule implements LoginModule
 {
@@ -225,6 +237,10 @@
     * Name of the group principal. If unconfigured, will be "null"
     */
    protected String groupPrincipalName = null; 
+   
+   protected boolean enableCacheInvalidation = false;
+   
+   protected String securityDomain = null;
 
    /**
     * Initialized this login module. Simple stores the passed in fields and
@@ -261,6 +277,15 @@
       final String gpPrincipalName = (String) options.get( GROUP_PRINCIPAL_NAME );
       if( gpPrincipalName != null && gpPrincipalName.length() > 0 )
          groupPrincipalName = gpPrincipalName;
+      
+      String cacheInvalidation = (String) options.get( "cache.invalidation" );
+      if( cacheInvalidation != null && !cacheInvalidation.isEmpty() )
+      {
+         enableCacheInvalidation = Boolean.parseBoolean( cacheInvalidation );
+         securityDomain = (String) options.get( SecurityConstants.SECURITY_DOMAIN_OPTION );
+         if( securityDomain == null || securityDomain.isEmpty() )
+            throw new RuntimeException( "Please configure option:" + SecurityConstants.SECURITY_DOMAIN_OPTION );
+      }
    }
 
    /**
@@ -573,6 +598,30 @@
          principalMappingContext.performMapping(contextMap, null);
          Principal principal = principalMappingContext.getMappingResult().getMappedObject();
          subject.getPrincipals().add(principal);
+         
+         //If the user has configured cache invalidation of subject based on saml token expiry
+         if( enableCacheInvalidation )
+         {
+            TimeCacheExpiry cacheExpiry = JBossAuthCacheInvalidationFactory.getCacheExpiry();
+            AssertionType assertion = null;
+            try
+            {
+               assertion = SAMLUtil.fromElement( samlToken );
+            }
+            catch ( Exception e)
+            {
+               throw new RuntimeException( e );
+            } 
+            XMLGregorianCalendar expiry = AssertionUtil.getExpiration( assertion );
+            if( expiry != null )
+            {
+               cacheExpiry.register( securityDomain, expiry.toGregorianCalendar().getTime() , principal );
+            } 
+            else
+            {
+               log.warn( "SAML Assertion has been found to have no expiration: ID = " + assertion.getID() );
+            }
+         }
       }
 
       if (roleMappingContext != null)

Modified: federation/trunk/picketlink-fed-core/src/main/java/org/picketlink/identity/federation/core/wstrust/plugins/saml/SAMLUtil.java
===================================================================
--- federation/trunk/picketlink-fed-core/src/main/java/org/picketlink/identity/federation/core/wstrust/plugins/saml/SAMLUtil.java	2011-02-07 23:17:31 UTC (rev 743)
+++ federation/trunk/picketlink-fed-core/src/main/java/org/picketlink/identity/federation/core/wstrust/plugins/saml/SAMLUtil.java	2011-02-08 03:51:59 UTC (rev 744)
@@ -24,8 +24,6 @@
 import java.io.ByteArrayInputStream;
 import java.io.ByteArrayOutputStream;
 
-import javax.xml.bind.JAXBException;
-
 import org.picketlink.identity.federation.core.exceptions.ConfigurationException;
 import org.picketlink.identity.federation.core.exceptions.ParsingException;
 import org.picketlink.identity.federation.core.exceptions.ProcessingException;
@@ -100,12 +98,11 @@
     * @param assertionElement
     *           the {@code Element} that contains the marshaled SAMLV2.0 assertion.
     * @return a reference to the unmarshaled {@code AssertionType} instance.
-    * @throws JAXBException if an error occurs while unmarshalling the document.
     * @throws ConfigurationException 
     * @throws ProcessingException 
     * @throws ParsingException 
     */ 
-   public static AssertionType fromElement(Element assertionElement) throws JAXBException, ProcessingException, ConfigurationException, ParsingException
+   public static AssertionType fromElement(Element assertionElement) throws ProcessingException, ConfigurationException, ParsingException
    {
       String assertionAsString = DocumentUtil.getDOMElementAsString(assertionElement);
       



More information about the jboss-cvs-commits mailing list