[picketlink-commits] Picketlink SVN: r1220 - in federation/trunk: picketlink-bindings-jboss/src/main/java/org/picketlink/identity/federation/bindings/jboss/subject and 1 other directory.

picketlink-commits at lists.jboss.org picketlink-commits at lists.jboss.org
Tue Sep 13 16:10:48 EDT 2011


Author: anil.saldhana at jboss.com
Date: 2011-09-13 16:10:47 -0400 (Tue, 13 Sep 2011)
New Revision: 1220

Added:
   federation/trunk/picketlink-bindings-jboss/src/main/java/org/picketlink/identity/federation/bindings/jboss/subject/PicketLinkJBossSubjectInteraction.java
   federation/trunk/picketlink-bindings/src/main/java/org/picketlink/identity/federation/bindings/tomcat/SubjectSecurityInteraction.java
Modified:
   federation/trunk/picketlink-bindings/src/main/java/org/picketlink/identity/federation/bindings/tomcat/PicketLinkAuthenticator.java
Log:
PLFED-229: PicketLink Authenticator has issues due to custom username that does not change

Modified: federation/trunk/picketlink-bindings/src/main/java/org/picketlink/identity/federation/bindings/tomcat/PicketLinkAuthenticator.java
===================================================================
--- federation/trunk/picketlink-bindings/src/main/java/org/picketlink/identity/federation/bindings/tomcat/PicketLinkAuthenticator.java	2011-09-13 04:14:10 UTC (rev 1219)
+++ federation/trunk/picketlink-bindings/src/main/java/org/picketlink/identity/federation/bindings/tomcat/PicketLinkAuthenticator.java	2011-09-13 20:10:47 UTC (rev 1220)
@@ -23,9 +23,17 @@
 
 import java.io.IOException;
 import java.security.Principal;
+import java.util.Set;
+import java.util.UUID;
 
+import javax.security.auth.Subject;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
 import org.apache.catalina.Realm;
-import org.apache.catalina.authenticator.AuthenticatorBase;
+import org.apache.catalina.Session;
+import org.apache.catalina.authenticator.Constants;
+import org.apache.catalina.authenticator.FormAuthenticator;
 import org.apache.catalina.connector.Request;
 import org.apache.catalina.connector.Response;
 import org.apache.catalina.deploy.LoginConfig;
@@ -40,27 +48,29 @@
  * @author Anil.Saldhana at redhat.com
  * @since Apr 11, 2011
  */
-public class PicketLinkAuthenticator extends AuthenticatorBase
+public class PicketLinkAuthenticator extends FormAuthenticator
 {
    protected static Logger log = Logger.getLogger(PicketLinkAuthenticator.class);
 
    protected boolean trace = log.isTraceEnabled();
 
    /**
-    * The {@link Realm} requires an user name
+    * This is the auth method used in the register method
     */
-   protected String userName = "custom-authenticator-user";
+   protected String authMethod = "SECURITY_DOMAIN";
 
    /**
-    * The {@link Realm} requires a password
+    * The authenticator may not be aware of the user name until after
+    * the underlying security exercise is complete. The Subject
+    * will have the proper user name. Hence we may need to perform
+    * an additional authentication now with the user name we have obtained.
     */
-   protected String password = "custom-authenticator-password";
+   protected boolean needSubjectPrincipalSubstitution = true;
 
-   /**
-    * This is the auth method used in the register method
-    */
-   protected String authMethod = "SECURITY_DOMAIN";
+   protected SubjectSecurityInteraction subjectInteraction = null;
 
+   protected String subjectInteractionClassName = "org.picketlink.identity.federation.bindings.jboss.subject.PicketLinkJBossSubjectInteraction";
+
    public PicketLinkAuthenticator()
    {
       if (trace)
@@ -70,44 +80,102 @@
    }
 
    /**
-    * Set the user name via WEB-INF/context.xml (JBoss AS)
-    * @param defaultUserName
+    * Set the auth method via WEB-INF/context.xml (JBoss AS)
+    * @param authMethod
     */
-   public void setUserName(String defaultUserName)
+   public void setAuthMethod(String authMethod)
    {
-      this.userName = defaultUserName;
+      this.authMethod = authMethod;
    }
 
-   /**
-    * Set the password via WEB-INF/context.xml (JBoss AS)
-    * @param defaultPassword
-    */
-   public void setPassword(String defaultPassword)
+   public void setNeedSubjectPrincipalSubstitution(String needSubjectPrincipalSubstitutionVal)
    {
-      this.password = defaultPassword;
+      this.needSubjectPrincipalSubstitution = Boolean.valueOf(needSubjectPrincipalSubstitutionVal);
    }
 
    /**
-    * Set the auth method via WEB-INF/context.xml (JBoss AS)
-    * @param authMethod
+    * Set this if you want to override the default {@link SubjectSecurityInteraction}
+    * @param subjectRetrieverClassName
     */
-   public void setAuthMethod(String authMethod)
+   public void setSubjectInteractionClassName(String subjectRetrieverClassName)
    {
-      this.authMethod = authMethod;
+      this.subjectInteractionClassName = subjectRetrieverClassName;
    }
 
    @Override
-   protected boolean authenticate(Request request, Response response, LoginConfig loginConfig) throws IOException
+   public boolean authenticate(Request request, Response response, LoginConfig loginConfig) throws IOException
    {
+      log.trace("Authenticating user");
+
+      Principal principal = request.getUserPrincipal();
+      if (principal != null)
+      {
+         if (trace)
+            log.trace("Already authenticated '" + principal.getName() + "'");
+         return true;
+      }
+
+      Session session = request.getSessionInternal(true);
+      String userName = UUID.randomUUID().toString();
+      String password = userName;
       Realm realm = context.getRealm();
 
-      Principal principal = realm.authenticate(this.userName, this.password);
+      principal = realm.authenticate(userName, password);
+      Principal originalPrincipal = principal;
 
       if (principal != null)
       {
-         register(request, response, principal, this.authMethod, null, null);
+         if (needSubjectPrincipalSubstitution)
+         {
+            principal = getSubjectPrincipal();
+            if (principal == null)
+               throw new RuntimeException("Principal from subject is null");
+            principal = realm.authenticate(principal.getName(), password);
+         }
+         session.setNote(Constants.SESS_USERNAME_NOTE, principal.getName());
+         session.setNote(Constants.SESS_PASSWORD_NOTE, password);
+         request.setUserPrincipal(principal);
+         register(request, response, principal, this.authMethod, principal.getName(), password);
+         if (originalPrincipal != null && needSubjectPrincipalSubstitution)
+         {
+            subjectInteraction.cleanup(originalPrincipal);
+         }
+         return true;
       }
 
-      return true;
+      return false;
    }
+
+   public boolean authenticate(HttpServletRequest request, HttpServletResponse response, LoginConfig loginConfig)
+         throws IOException
+   {
+      return authenticate((Request) request, (Response) response, loginConfig);
+   }
+
+   protected Principal getSubjectPrincipal()
+   {
+      if (subjectInteraction == null)
+      {
+         Class<?> clazz = SecurityActions.loadClass(getClass(), subjectInteractionClassName);
+         try
+         {
+            subjectInteraction = (SubjectSecurityInteraction) clazz.newInstance();
+         }
+         catch (Exception e)
+         {
+            throw new RuntimeException(e);
+         }
+      }
+
+      Subject subject = subjectInteraction.get();
+      if (subject != null)
+      {
+         Set<Principal> principals = subject.getPrincipals();
+         if (!principals.isEmpty())
+         {
+            return subject.getPrincipals().iterator().next();
+         }
+      }
+      return null;
+   }
 }
\ No newline at end of file

Added: federation/trunk/picketlink-bindings/src/main/java/org/picketlink/identity/federation/bindings/tomcat/SubjectSecurityInteraction.java
===================================================================
--- federation/trunk/picketlink-bindings/src/main/java/org/picketlink/identity/federation/bindings/tomcat/SubjectSecurityInteraction.java	                        (rev 0)
+++ federation/trunk/picketlink-bindings/src/main/java/org/picketlink/identity/federation/bindings/tomcat/SubjectSecurityInteraction.java	2011-09-13 20:10:47 UTC (rev 1220)
@@ -0,0 +1,48 @@
+/*
+ * 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.bindings.tomcat;
+
+import java.security.Principal;
+
+import javax.security.auth.Subject;
+
+/**
+ * Interface to retrieve a subject
+ * @author Anil.Saldhana at redhat.com
+ * @since Sep 13, 2011
+ */
+public interface SubjectSecurityInteraction
+{
+   /**
+    * Obtain a subject based on implementation
+    * @return
+    */
+   Subject get();
+
+   /**
+    * Clean up the {@link Principal} from
+    * the security cache
+    * @param principal
+    * @return
+    */
+   boolean cleanup(Principal principal);
+}
\ No newline at end of file

Added: federation/trunk/picketlink-bindings-jboss/src/main/java/org/picketlink/identity/federation/bindings/jboss/subject/PicketLinkJBossSubjectInteraction.java
===================================================================
--- federation/trunk/picketlink-bindings-jboss/src/main/java/org/picketlink/identity/federation/bindings/jboss/subject/PicketLinkJBossSubjectInteraction.java	                        (rev 0)
+++ federation/trunk/picketlink-bindings-jboss/src/main/java/org/picketlink/identity/federation/bindings/jboss/subject/PicketLinkJBossSubjectInteraction.java	2011-09-13 20:10:47 UTC (rev 1220)
@@ -0,0 +1,106 @@
+/*
+ * 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.bindings.jboss.subject;
+
+import java.security.Principal;
+import java.util.Calendar;
+
+import javax.naming.InitialContext;
+import javax.naming.NamingException;
+import javax.security.auth.Subject;
+import javax.security.jacc.PolicyContext;
+import javax.security.jacc.PolicyContextException;
+
+import org.jboss.logging.Logger;
+import org.jboss.security.SimplePrincipal;
+import org.jboss.security.SubjectSecurityManager;
+import org.picketlink.identity.federation.bindings.tomcat.SubjectSecurityInteraction;
+import org.picketlink.identity.federation.core.factories.JBossAuthCacheInvalidationFactory;
+import org.picketlink.identity.federation.core.factories.JBossAuthCacheInvalidationFactory.TimeCacheExpiry;
+
+/**
+ * An implementation of {@link SubjectSecurityInteraction} for JBoss AS
+ * @author Anil.Saldhana at redhat.com
+ * @since Sep 13, 2011
+ */
+public class PicketLinkJBossSubjectInteraction implements SubjectSecurityInteraction
+{
+   protected static Logger log = Logger.getLogger(PicketLinkJBossSubjectInteraction.class);
+
+   protected boolean trace = log.isTraceEnabled();
+
+   /**
+    * @see org.picketlink.identity.federation.bindings.tomcat.SubjectSecurityInteraction#cleanup(java.security.Principal)
+    */
+   public boolean cleanup(Principal principal)
+   {
+      try
+      {
+         String securityDomain = getSecurityDomain();
+         if (trace)
+         {
+            log.trace("Determined Security Domain=" + securityDomain);
+         }
+         TimeCacheExpiry cacheExpiry = JBossAuthCacheInvalidationFactory.getCacheExpiry();
+         Calendar calendar = Calendar.getInstance();
+         calendar.add(Calendar.SECOND, 10);//Add 25 seconds
+         if (trace)
+         {
+            log.trace("Will expire from cache in 10 seconds, principal=" + principal);
+         }
+         cacheExpiry.register(securityDomain, calendar.getTime(), principal);
+         //Additional expiry of simple principal
+         cacheExpiry.register(securityDomain, calendar.getTime(), new SimplePrincipal(principal.getName()));
+      }
+      catch (NamingException e)
+      {
+         throw new RuntimeException(e);
+      }
+
+      return false;
+   }
+
+   /**
+    * @see org.picketlink.identity.federation.bindings.tomcat.SubjectSecurityInteraction#get()
+    */
+   public Subject get()
+   {
+      try
+      {
+         return (Subject) PolicyContext.getContext("javax.security.auth.Subject.container");
+      }
+      catch (PolicyContextException e)
+      {
+         throw new RuntimeException(e);
+      }
+   }
+
+   private String getSecurityDomain() throws NamingException
+   {
+      //Get the SecurityManagerService from JNDI
+      InitialContext ctx = new InitialContext();
+      SubjectSecurityManager ssm = (SubjectSecurityManager) ctx.lookup("java:comp/env/security/securityMgr");
+      if (ssm == null)
+         throw new RuntimeException("Unable to get the subject security manager");
+      return ssm.getSecurityDomain();
+   }
+}
\ No newline at end of file



More information about the picketlink-commits mailing list