Author: anil.saldhana(a)jboss.com
Date: 2011-09-26 12:11:45 -0400 (Mon, 26 Sep 2011)
New Revision: 1257
Added:
social/trunk/social/src/main/java/org/picketlink/social/auth/SecurityActions.java
Modified:
social/trunk/facebook/src/main/java/org/picketlink/social/facebook/FacebookAuthenticator.java
social/trunk/facebook/src/main/java/org/picketlink/social/facebook/SecurityActions.java
social/trunk/openid/src/main/java/org/picketlink/social/openid/auth/OpenIDConsumerAuthenticator.java
social/trunk/openid/src/main/java/org/picketlink/social/openid/auth/SecurityActions.java
social/trunk/social/src/main/java/org/picketlink/social/auth/ExternalAuthenticator.java
social/trunk/social/src/main/java/org/picketlink/social/reg/RegistrationValve.java
Log:
authenticator changes
Modified:
social/trunk/facebook/src/main/java/org/picketlink/social/facebook/FacebookAuthenticator.java
===================================================================
---
social/trunk/facebook/src/main/java/org/picketlink/social/facebook/FacebookAuthenticator.java 2011-09-24
04:27:47 UTC (rev 1256)
+++
social/trunk/facebook/src/main/java/org/picketlink/social/facebook/FacebookAuthenticator.java 2011-09-26
16:11:45 UTC (rev 1257)
@@ -22,10 +22,13 @@
package org.picketlink.social.facebook;
import java.io.IOException;
+import java.lang.reflect.Method;
import java.security.Principal;
import java.util.ArrayList;
import java.util.List;
import java.util.StringTokenizer;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
@@ -64,10 +67,13 @@
private enum STATES { AUTH, AUTHZ, FINISH};
protected FacebookProcessor processor;
+
+ //Incompatibilities in register() method across JBossWeb versions
+ private Method theSuperRegisterMethod = null;
public void setReturnURL(String returnURL)
{
- this.returnURL = returnURL;
+ this.returnURL = getSystemPropertyAsString(returnURL);
}
public void setClientID(String clientID)
@@ -106,8 +112,6 @@
this.saveRestoreRequest = saveRestoreRequest;
}
-
- @Override
public void start() throws LifecycleException
{
//Validate the input values
@@ -128,6 +132,25 @@
throw new IOException("Not of type Catalina response");
return authenticate((Request)request, (Response)response, loginConfig);
}
+
+ /**
+ * Authenticate the request
+ * @param request
+ * @param response
+ * @param config
+ * @return
+ * @throws IOException
+ * @throws {@link RuntimeException} when the response is not of type catalina response
object
+ */
+ public boolean authenticate(Request request, HttpServletResponse response, LoginConfig
config) throws IOException
+ {
+ if (response instanceof Response)
+ {
+ Response catalinaResponse = (Response) response;
+ return authenticate(request, catalinaResponse, config);
+ }
+ throw new RuntimeException("Wrong type of response:"+response);
+ }
public boolean authenticate(Request request, Response response, LoginConfig
loginConfig) throws IOException
{
@@ -175,11 +198,107 @@
{
this.restoreRequest(request, request.getSessionInternal());
}
- register(request, response, principal, Constants.FORM_METHOD, userName,
"");
+
+ registerWithAuthenticatorBase(request,response,principal,userName);
+
request.getSession().setAttribute("STATE", STATES.FINISH.name());
return true;
}
return false;
}
+
+
+
+ protected void registerWithAuthenticatorBase(Request request, Response response,
Principal principal, String userName)
+ {
+ try
+ {
+ register(request, response, principal, Constants.FORM_METHOD, userName,
"");
+ }
+ catch(NoSuchMethodError nse)
+ {
+ if(theSuperRegisterMethod == null)
+ {
+ Class<?>[] args = new Class[]
+ {Request.class, HttpServletResponse.class, Principal.class, String.class,
String.class, String.class};
+ Class<?> superClass = getClass().getSuperclass();
+ theSuperRegisterMethod = SecurityActions.getMethod(superClass,
"register", args);
+
+ }
+ if(theSuperRegisterMethod != null)
+ {
+ Object[] objectArgs = new Object[] {request, response.getResponse(),
+ principal, Constants.FORM_METHOD,
+ userName, FacebookProcessor.EMPTY_PASSWORD };
+ try
+ {
+ theSuperRegisterMethod.invoke(this, objectArgs);
+ }
+ catch (Exception e)
+ {
+ log.error("Unable to register:", e);
+ }
+ }
+ }
+ }
+
+ /**
+ * <p>
+ * Get the system property value if the string is of the format ${sysproperty}
+ * </p>
+ * <p>
+ * You can insert default value when the system property is not set, by
+ * separating it at the beginning with ::
+ * </p>
+ * <p>
+ * <b>Examples:</b>
+ * </p>
+ *
+ * <p>
+ * ${idp} should resolve to a value if the system property "idp" is set.
+ * </p>
+ * <p>
+ * ${idp::http://localhost:8080} will resolve to
http://localhost:8080 if the system
property "idp" is not set.
+ * </p>
+ * @param str
+ * @return
+ */
+ protected String getSystemPropertyAsString(String str)
+ {
+ if (str == null)
+ throw new IllegalArgumentException("str is null");
+ if (str.contains("${"))
+ {
+ Pattern pattern = Pattern.compile("\\$\\{([^}]+)}");
+ Matcher matcher = pattern.matcher(str);
+
+ StringBuffer buffer = new StringBuffer();
+ String sysPropertyValue = null;
+
+ while (matcher.find())
+ {
+ String subString = matcher.group(1);
+ String defaultValue = "";
+
+ //Look for default value
+ if (subString.contains("::"))
+ {
+ int index = subString.indexOf("::");
+ defaultValue = subString.substring(index + 2);
+ subString = subString.substring(0, index);
+ }
+ sysPropertyValue = SecurityActions.getSystemProperty(subString,
defaultValue);
+ if (sysPropertyValue.isEmpty())
+ {
+ throw new IllegalArgumentException(matcher.group(1) + " is missing in
system properties");
+ }
+ matcher.appendReplacement(buffer, sysPropertyValue);
+ }
+
+ matcher.appendTail(buffer);
+ str = buffer.toString();
+ }
+ return str;
+ }
}
\ No newline at end of file
Modified:
social/trunk/facebook/src/main/java/org/picketlink/social/facebook/SecurityActions.java
===================================================================
---
social/trunk/facebook/src/main/java/org/picketlink/social/facebook/SecurityActions.java 2011-09-24
04:27:47 UTC (rev 1256)
+++
social/trunk/facebook/src/main/java/org/picketlink/social/facebook/SecurityActions.java 2011-09-26
16:11:45 UTC (rev 1257)
@@ -21,6 +21,7 @@
*/
package org.picketlink.social.facebook;
+import java.lang.reflect.Method;
import java.security.AccessController;
import java.security.PrivilegedAction;
@@ -89,5 +90,47 @@
}
});
}
-
+
+ /**
+ * Get the system property
+ * @param key
+ * @param defaultValue
+ * @return
+ */
+ static String getSystemProperty(final String key, final String defaultValue)
+ {
+ return AccessController.doPrivileged(new PrivilegedAction<String>()
+ {
+ public String run()
+ {
+ return System.getProperty(key, defaultValue);
+ }
+ });
+ }
+
+ /**
+ * Use reflection to get the {@link Method} on a {@link Class} with the
+ * given parameter types
+ * @param clazz
+ * @param methodName
+ * @param parameterTypes
+ * @return
+ */
+ static Method getMethod(final Class<?> clazz, final String methodName, final
Class<?>[] parameterTypes)
+ {
+ return AccessController.doPrivileged(new PrivilegedAction<Method>()
+ {
+ public Method run()
+ {
+ try
+ {
+ return clazz.getDeclaredMethod(methodName, parameterTypes);
+ }
+ catch (Exception e)
+ {
+ return null;
+ }
+ }
+ });
+ }
}
\ No newline at end of file
Modified:
social/trunk/openid/src/main/java/org/picketlink/social/openid/auth/OpenIDConsumerAuthenticator.java
===================================================================
---
social/trunk/openid/src/main/java/org/picketlink/social/openid/auth/OpenIDConsumerAuthenticator.java 2011-09-24
04:27:47 UTC (rev 1256)
+++
social/trunk/openid/src/main/java/org/picketlink/social/openid/auth/OpenIDConsumerAuthenticator.java 2011-09-26
16:11:45 UTC (rev 1257)
@@ -22,6 +22,7 @@
package org.picketlink.social.openid.auth;
import java.io.IOException;
+import java.lang.reflect.Method;
import java.security.Principal;
import java.util.ArrayList;
import java.util.List;
@@ -68,10 +69,13 @@
protected boolean saveRestoreRequest = true;
protected OpenIDProcessor processor = null;
+
+ //Incompatibilities in register() method across JBossWeb versions
+ private Method theSuperRegisterMethod = null;
public void setReturnURL(String returnURL)
{
- this.returnURL = returnURL;
+ this.returnURL = StringUtil.getSystemPropertyAsString(returnURL);
}
public void setRequiredAttributes(String requiredAttributes)
@@ -104,7 +108,7 @@
roles.add(token);
}
}
-
+
public boolean authenticate(HttpServletRequest request, HttpServletResponse response,
LoginConfig loginConfig) throws IOException
{
if(request instanceof Request == false)
@@ -114,6 +118,25 @@
return authenticate((Request)request, (Response)response, loginConfig);
}
+ /**
+ * Authenticate the request
+ * @param request
+ * @param response
+ * @param config
+ * @return
+ * @throws IOException
+ * @throws {@link RuntimeException} when the response is not of type catalina response
object
+ */
+ public boolean authenticate(Request request, HttpServletResponse response, LoginConfig
config) throws IOException
+ {
+ if (response instanceof Response)
+ {
+ Response catalinaResponse = (Response) response;
+ return authenticate(request, catalinaResponse, config);
+ }
+ throw new RuntimeException("Wrong type of response:"+response);
+ }
+
public boolean authenticate(Request request, Response response, LoginConfig
loginConfig) throws IOException
{
if(processor == null)
@@ -174,9 +197,45 @@
if(trace)
log.trace("Logged in as:" + principal);
- register(request, response, principal, Constants.FORM_METHOD, principalName,
"");
+
+ registerWithAuthenticatorBase(request,response,principal,principalName);
+
+ request.getSession().setAttribute("STATE", STATES.FINISH.name());
return true;
}
return false;
}
+
+ protected void registerWithAuthenticatorBase(Request request, Response response,
Principal principal, String userName)
+ {
+ try
+ {
+ register(request, response, principal, Constants.FORM_METHOD, userName,
"");
+ }
+ catch(NoSuchMethodError nse)
+ {
+ if(theSuperRegisterMethod == null)
+ {
+ Class<?>[] args = new Class[]
+ {Request.class, HttpServletResponse.class, Principal.class, String.class,
String.class, String.class};
+ Class<?> superClass = getClass().getSuperclass();
+ theSuperRegisterMethod = SecurityActions.getMethod(superClass,
"register", args);
+
+ }
+ if(theSuperRegisterMethod != null)
+ {
+ Object[] objectArgs = new Object[] {request, response.getResponse(),
+ principal, Constants.FORM_METHOD,
+ userName, OpenIDProcessor.EMPTY_PASSWORD };
+ try
+ {
+ theSuperRegisterMethod.invoke(this, objectArgs);
+ }
+ catch (Exception e)
+ {
+ log.error("Unable to register:", e);
+ }
+ }
+ }
+ }
}
\ No newline at end of file
Modified:
social/trunk/openid/src/main/java/org/picketlink/social/openid/auth/SecurityActions.java
===================================================================
---
social/trunk/openid/src/main/java/org/picketlink/social/openid/auth/SecurityActions.java 2011-09-24
04:27:47 UTC (rev 1256)
+++
social/trunk/openid/src/main/java/org/picketlink/social/openid/auth/SecurityActions.java 2011-09-26
16:11:45 UTC (rev 1257)
@@ -21,6 +21,7 @@
*/
package org.picketlink.social.openid.auth;
+import java.lang.reflect.Method;
import java.security.AccessController;
import java.security.PrivilegedAction;
@@ -89,5 +90,32 @@
}
});
}
+
+ /**
+ * Use reflection to get the {@link Method} on a {@link Class} with the
+ * given parameter types
+ * @param clazz
+ * @param methodName
+ * @param parameterTypes
+ * @return
+ */
+ static Method getMethod(final Class<?> clazz, final String methodName, final
Class<?>[] parameterTypes)
+ {
+ return AccessController.doPrivileged(new PrivilegedAction<Method>()
+ {
+ public Method run()
+ {
+ try
+ {
+ return clazz.getDeclaredMethod(methodName, parameterTypes);
+ }
+ catch (Exception e)
+ {
+ return null;
+ }
+ }
+ });
+ }
+
}
\ No newline at end of file
Modified:
social/trunk/social/src/main/java/org/picketlink/social/auth/ExternalAuthenticator.java
===================================================================
---
social/trunk/social/src/main/java/org/picketlink/social/auth/ExternalAuthenticator.java 2011-09-24
04:27:47 UTC (rev 1256)
+++
social/trunk/social/src/main/java/org/picketlink/social/auth/ExternalAuthenticator.java 2011-09-26
16:11:45 UTC (rev 1257)
@@ -22,6 +22,7 @@
package org.picketlink.social.auth;
import java.io.IOException;
+import java.lang.reflect.Method;
import java.security.Principal;
import java.util.ArrayList;
import java.util.List;
@@ -38,6 +39,7 @@
import org.apache.catalina.connector.Response;
import org.apache.catalina.deploy.LoginConfig;
import org.apache.log4j.Logger;
+import org.picketlink.identity.federation.core.util.StringUtil;
import org.picketlink.social.facebook.FacebookProcessor;
import org.picketlink.social.openid.auth.OpenIDConsumerAuthenticator;
import org.picketlink.social.openid.auth.OpenIDProcessor;
@@ -76,6 +78,9 @@
protected boolean saveRestoreRequest = true;
private enum STATES { AUTH, AUTHZ, FINISH};
+
+ //Incompatibilities in register() method across JBossWeb versions
+ private Method theSuperRegisterMethod = null;
/**
* A comma separated string that represents the roles the web app
@@ -86,7 +91,7 @@
{
if(roleStr == null)
throw new RuntimeException("Role String is null in configuration");
- StringTokenizer st = new StringTokenizer(roleStr, ",");
+ StringTokenizer st = new
StringTokenizer(StringUtil.getSystemPropertyAsString(roleStr), ",");
while(st.hasMoreElements())
{
roles.add(st.nextToken());
@@ -100,21 +105,40 @@
protected List<String> roles = new ArrayList<String>();
+ /**
+ * Set the url where the 3rd party authentication service will redirect after
authentication
+ * @param returnURL
+ */
public void setReturnURL(String returnURL)
{
- this.returnURL = returnURL;
+ this.returnURL = StringUtil.getSystemPropertyAsString(returnURL);
}
+
+ /**
+ * Set the client id for facebook
+ * @param clientID
+ */
public void setClientID(String clientID)
{
- this.clientID = clientID;
+ this.clientID = StringUtil.getSystemPropertyAsString(clientID);
}
+
+ /**
+ * Set the client secret for facebook
+ * @param clientSecret
+ */
public void setClientSecret(String clientSecret)
{
- this.clientSecret = clientSecret;
+ this.clientSecret = StringUtil.getSystemPropertyAsString(clientSecret);
}
+
+ /**
+ * Set the scope for facebook (Default: email)
+ * @param facebookScope
+ */
public void setFacebookScope(String facebookScope)
{
- this.facebookScope = facebookScope;
+ this.facebookScope = StringUtil.getSystemPropertyAsString(facebookScope);
}
public boolean authenticate(HttpServletRequest request, HttpServletResponse response,
LoginConfig loginConfig) throws IOException
@@ -125,6 +149,25 @@
throw new IOException("Not of type Catalina response");
return authenticate((Request)request, (Response)response, loginConfig);
}
+
+ /**
+ * Authenticate the request
+ * @param request
+ * @param response
+ * @param config
+ * @return
+ * @throws IOException
+ * @throws {@link RuntimeException} when the response is not of type catalina response
object
+ */
+ public boolean authenticate(Request request, HttpServletResponse response, LoginConfig
config) throws IOException
+ {
+ if (response instanceof Response)
+ {
+ Response catalinaResponse = (Response) response;
+ return authenticate(request, catalinaResponse, config);
+ }
+ throw new RuntimeException("Wrong type of response:"+response);
+ }
public boolean authenticate(Request request, Response response, LoginConfig
loginConfig) throws IOException
{
@@ -204,7 +247,8 @@
{
this.restoreRequest(request, request.getSessionInternal());
}
- register(request, response, principal, Constants.FORM_METHOD, userName,
"");
+ registerWithAuthenticatorBase(request,response,principal,userName);
+
request.getSession().setAttribute("STATE", STATES.FINISH.name());
return true;
@@ -267,9 +311,42 @@
if(trace)
log.trace("Logged in as:" + principal);
- register(request, response, principal, Constants.FORM_METHOD, principalName,
"");
+ registerWithAuthenticatorBase(request,response,principal,principalName);
return true;
}
return false;
}
+
+ protected void registerWithAuthenticatorBase(Request request, Response response,
Principal principal, String userName)
+ {
+ try
+ {
+ register(request, response, principal, Constants.FORM_METHOD, userName,
"");
+ }
+ catch(NoSuchMethodError nse)
+ {
+ if(theSuperRegisterMethod == null)
+ {
+ Class<?>[] args = new Class[]
+ {Request.class, HttpServletResponse.class, Principal.class, String.class,
String.class, String.class};
+ Class<?> superClass = getClass().getSuperclass();
+ theSuperRegisterMethod = SecurityActions.getMethod(superClass,
"register", args);
+
+ }
+ if(theSuperRegisterMethod != null)
+ {
+ Object[] objectArgs = new Object[] {request, response.getResponse(),
+ principal, Constants.FORM_METHOD,
+ userName, FacebookProcessor.EMPTY_PASSWORD };
+ try
+ {
+ theSuperRegisterMethod.invoke(this, objectArgs);
+ }
+ catch (Exception e)
+ {
+ log.error("Unable to register:", e);
+ }
+ }
+ }
+ }
}
\ No newline at end of file
Added: social/trunk/social/src/main/java/org/picketlink/social/auth/SecurityActions.java
===================================================================
--- social/trunk/social/src/main/java/org/picketlink/social/auth/SecurityActions.java
(rev 0)
+++
social/trunk/social/src/main/java/org/picketlink/social/auth/SecurityActions.java 2011-09-26
16:11:45 UTC (rev 1257)
@@ -0,0 +1,60 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2011, 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.social.auth;
+
+import java.lang.reflect.Method;
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+
+/**
+ * Privileged Blocks
+ * @author Anil Saldhana
+ * @since Sep 26, 2011
+ */
+class SecurityActions
+{
+ /**
+ * Use reflection to get the {@link Method} on a {@link Class} with the
+ * given parameter types
+ * @param clazz
+ * @param methodName
+ * @param parameterTypes
+ * @return
+ */
+ static Method getMethod(final Class<?> clazz, final String methodName, final
Class<?>[] parameterTypes)
+ {
+ return AccessController.doPrivileged(new PrivilegedAction<Method>()
+ {
+ public Method run()
+ {
+ try
+ {
+ return clazz.getDeclaredMethod(methodName, parameterTypes);
+ }
+ catch (Exception e)
+ {
+ return null;
+ }
+ }
+ });
+ }
+}
\ No newline at end of file
Modified:
social/trunk/social/src/main/java/org/picketlink/social/reg/RegistrationValve.java
===================================================================
---
social/trunk/social/src/main/java/org/picketlink/social/reg/RegistrationValve.java 2011-09-24
04:27:47 UTC (rev 1256)
+++
social/trunk/social/src/main/java/org/picketlink/social/reg/RegistrationValve.java 2011-09-26
16:11:45 UTC (rev 1257)
@@ -55,38 +55,38 @@
throw new IOException("Not of type Catalina response");
invoke((Request)request, (Response)response);
}
-
+
public void invoke(Request request, Response response) throws IOException,
ServletException
{
HttpSession session = request.getSession();
Principal principal = (Principal) session.getAttribute("PRINCIPAL");
- if(principal == null)
- throw new ServletException("User is not authenticated using the social
authenticator");
- UserRegistration user = null;
- if(principal instanceof OpenIdPrincipal)
+ if(principal != null)
{
- user = processOpenIDPrincipal((OpenIdPrincipal) principal);
+ UserRegistration user = null;
+ if(principal instanceof OpenIdPrincipal)
+ {
+ user = processOpenIDPrincipal((OpenIdPrincipal) principal);
+ }
+ else if(principal instanceof FacebookPrincipal)
+ {
+ user = processFacebookPrincipal((FacebookPrincipal) principal);
+ }
+ else
+ throw new ServletException("Unknown principal type:" + principal);
+ if(user != null)
+ {
+ session.setAttribute("user", user);
+ }
}
- else if(principal instanceof FacebookPrincipal)
- {
- user = processFacebookPrincipal((FacebookPrincipal) principal);
- }
- else
- throw new ServletException("Unknown principal type:" + principal);
- if(user != null)
- {
- session.setAttribute("user", user);
- }
-
getNext().invoke(request, response);
}
-
+
private UserRegistration processOpenIDPrincipal(OpenIdPrincipal openIDPrincipal)
{
UserRegistration user = new UserRegistration();
Map<String,List<String>> attributes = openIDPrincipal.getAttributes();
user.setIdentifier(openIDPrincipal.getIdentifier());
-
+
if(attributes != null)
{
List<String> values = attributes.get("ax_firstName");
@@ -114,7 +114,7 @@
}
return user;
}
-
+
private UserRegistration processFacebookPrincipal(FacebookPrincipal
facebookPrincipal)
{
UserRegistration user = new UserRegistration();