Seam common module
by Shane Bryzak
We need some place to put utility classes that are shared across the
other modules, such as Strings, Base64, etc. For now, I've added a
common module which is currently very minimal (which we can add to as
required), however I'm not sure if this is the way we ultimately want to
go. I can't currently think of any alternative though - does anyone
else have an opinion on this? If we go down this route, then we will
probably be able to do away with the root /common directory and just
have modules/common instead. Actually the more I think about it, since
we are restructuring everything into modules anyway it doesn't make much
sense to have a root common directory at all.
15 years, 8 months
Procedure on how to start developping seam 3 with eclipse?
by Denis Forveille
Hi,
Is there yet somewhere a document or a procedure that would explain how to
setup the project(s) in eclipse for seam 3?
- what directoris in svn become projects in eclipse?
- how to setup the ".project", ".classpath" etc.. files in eclipse?
Also, can we yet commit things in seam 3 (eg to merge changes from branche
2.1)?
Thx
15 years, 8 months
Porting package for Seam
by Shane Bryzak
It seems that we need something like the webbeans porting package but
for Seam, since we need to be able to get a reference to the current
manager statically from non-bean classes. Any thoughts on this Pete?
15 years, 8 months
Re: [seam-commits] Seam SVN: r10542 - in modules/trunk: logging and 15 other directories.
by Pete Muir
Shane,
We've already developed the logging module for webbeans - see
org.jboss.webbeans:webbeans-logger and org.jboss.webbeans:webbeans-
logging
On 21 Apr 2009, at 10:38, seam-commits(a)lists.jboss.org wrote:
> Author: shane.bryzak(a)jboss.com
> Date: 2009-04-21 05:38:36 -0400 (Tue, 21 Apr 2009)
> New Revision: 10542
>
> Added:
> modules/trunk/logging/
> modules/trunk/logging/pom.xml
> modules/trunk/logging/src/
> modules/trunk/logging/src/main/
> modules/trunk/logging/src/main/java/
> modules/trunk/logging/src/main/java/org/
> modules/trunk/logging/src/main/java/org/jboss/
> modules/trunk/logging/src/main/java/org/jboss/seam/
> modules/trunk/logging/src/main/java/org/jboss/seam/log/
> modules/trunk/logging/src/main/java/org/jboss/seam/log/
> JDKProvider.java
> modules/trunk/logging/src/main/java/org/jboss/seam/log/Log.java
> modules/trunk/logging/src/main/java/org/jboss/seam/log/
> Log4JProvider.java
> modules/trunk/logging/src/main/java/org/jboss/seam/log/LogImpl.java
> modules/trunk/logging/src/main/java/org/jboss/seam/log/
> LogProvider.java
> modules/trunk/logging/src/main/java/org/jboss/seam/log/Logging.java
> modules/trunk/logging/target/
> modules/trunk/logging/target/classes/
> modules/trunk/logging/target/classes/org/
> modules/trunk/logging/target/classes/org/jboss/
> modules/trunk/logging/target/classes/org/jboss/seam/
> modules/trunk/logging/target/classes/org/jboss/seam/log/
> modules/trunk/parent/
> modules/trunk/parent/pom.xml
> Modified:
> modules/trunk/security/pom.xml
> modules/trunk/version-matrix/pom.xml
> Log:
> added logging module, parent pom, updated version-matrix pom
>
> Added: modules/trunk/logging/pom.xml
> ===================================================================
> --- modules/trunk/logging/pom.xml (rev 0)
> +++ modules/trunk/logging/pom.xml 2009-04-21 09:38:36 UTC (rev 10542)
> @@ -0,0 +1,22 @@
> +<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance
> " xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd
> ">
> + <parent>
> + <artifactId>seam-parent</artifactId>
> + <groupId>org.jboss.seam</groupId>
> + <version>3.0.0-SNAPSHOT</version>
> + </parent>
> +
> + <modelVersion>4.0.0</modelVersion>
> + <groupId>org.jboss.seam</groupId>
> + <artifactId>seam-logging</artifactId>
> + <version>3.0.0-SNAPSHOT</version>
> + <name>Seam Logging</name>
> + <dependencies>
> +
> + <dependency>
> + <groupId>log4j</groupId>
> + <artifactId>log4j</artifactId>
> + <optional>true</optional>
> + </dependency>
> +
> + </dependencies>
> +</project>
>
> Added: modules/trunk/logging/src/main/java/org/jboss/seam/log/
> JDKProvider.java
> ===================================================================
> --- modules/trunk/logging/src/main/java/org/jboss/seam/log/
> JDKProvider.java (rev 0)
> +++ modules/trunk/logging/src/main/java/org/jboss/seam/log/
> JDKProvider.java 2009-04-21 09:38:36 UTC (rev 10542)
> @@ -0,0 +1,140 @@
> +package org.jboss.seam.log;
> +
> +import java.util.logging.Level;
> +import java.util.logging.Logger;
> +
> +/**
> + *
> + * @author Gavin King
> + *
> + */
> +class JDKProvider implements LogProvider
> +{
> + private final Logger logger;
> + private final boolean isWrapped;
> +
> + JDKProvider(String category, boolean wrapped)
> + {
> + this.logger = Logger.getLogger(category);
> + this.isWrapped = wrapped;
> + }
> +
> + private void log(Level level, Object object, Throwable ex)
> + {
> +
> + if (logger.isLoggable(level))
> + {
> + Throwable dummyException = new Throwable();
> + StackTraceElement locations[] =
> dummyException.getStackTrace();
> + String className = "unknown";
> + String methodName = "unknown";
> + int depth = isWrapped ? 3 : 2;
> + if (locations != null && locations.length > depth)
> + {
> + StackTraceElement caller = locations[depth];
> + className = caller.getClassName();
> + methodName = caller.getMethodName();
> + }
> + if (ex == null)
> + {
> + logger.logp(level, className, methodName,
> String.valueOf(object));
> + }
> + else
> + {
> + logger.logp(level, className, methodName,
> String.valueOf(object), ex);
> + }
> + }
> +
> + }
> +
> + public void debug(Object object, Throwable t)
> + {
> + log(Level.FINE, object, t);
> + }
> +
> + public void debug(Object object)
> + {
> + log(Level.FINE, object, null);
> + }
> +
> + public void error(Object object, Throwable t)
> + {
> + log(Level.SEVERE, object, t);
> + }
> +
> + public void error(Object object)
> + {
> + log(Level.SEVERE, object, null);
> + }
> +
> + public void fatal(Object object, Throwable t)
> + {
> + log(Level.SEVERE, object, t);
> + }
> +
> + public void fatal(Object object)
> + {
> + log(Level.SEVERE, object, null);
> + }
> +
> + public void info(Object object, Throwable t)
> + {
> + log(Level.INFO, object, t);
> + }
> +
> + public void info(Object object)
> + {
> + log(Level.INFO, object, null);
> + }
> +
> + public boolean isDebugEnabled()
> + {
> + return logger.isLoggable(Level.FINE);
> + }
> +
> + public boolean isErrorEnabled()
> + {
> + return logger.isLoggable(Level.SEVERE);
> + }
> +
> + public boolean isFatalEnabled()
> + {
> + return logger.isLoggable(Level.SEVERE);
> + }
> +
> + public boolean isInfoEnabled()
> + {
> + return logger.isLoggable(Level.INFO);
> + }
> +
> + public boolean isTraceEnabled()
> + {
> + return logger.isLoggable(Level.FINER);
> + }
> +
> + public boolean isWarnEnabled()
> + {
> + return logger.isLoggable(Level.WARNING);
> + }
> +
> + public void trace(Object object, Throwable t)
> + {
> + log(Level.FINER, object, t);
> + }
> +
> + public void trace(Object object)
> + {
> + log(Level.FINER, object, null);
> + }
> +
> + public void warn(Object object, Throwable t)
> + {
> + log(Level.WARNING, object, t);
> + }
> +
> + public void warn(Object object)
> + {
> + log(Level.WARNING, object, null);
> + }
> +
> +}
>
> Added: modules/trunk/logging/src/main/java/org/jboss/seam/log/Log.java
> ===================================================================
> --- modules/trunk/logging/src/main/java/org/jboss/seam/log/
> Log.java (rev 0)
> +++ modules/trunk/logging/src/main/java/org/jboss/seam/log/Log.java
> 2009-04-21 09:38:36 UTC (rev 10542)
> @@ -0,0 +1,86 @@
> +package org.jboss.seam.log;
> +
> +/**
> + * <p>A <code>Log</code> object is used to log messages.
> + * They will be logged in any environment that has setup a logging
> service
> + * such as Log4J or the standard JDK logging facilities. In fact,
> this
> + * logging interface is very similar to the other facilities with the
> + * difference that logging methods also take any number of optional
> + * parameters beyond the message object for later interpolation
> + * into the message.</p>
> + *
> + * <p>The idea of using interpolation parameters is very important
> for
> + * performance reasons in production code. Normally developers write
> + * logging messages similar to this one:
> + * <pre>
> + * log.debug("Started processing of " + obj1 + " with action " +
> obj2);
> + * </pre>
> + * The problem that arises at runtime in production systems, is
> that DEBUG
> + * level logging may not be enabled. And even if this logging is
> going to
> + * be a no-op call, Java must still build the string dynamically
> that is the
> + * argument to the call. It is the building of this string that
> can be quite
> + * time consuming. The more complex the objects being concatenated
> are, the
> + * worse the time penalty incurred is. And this time is completely
> wasted
> + * since the string may never be used.</p>
> + *
> + * <p>Normally to combat the problem of making this call and
> building the
> + * string dynamically, the developer uses a conditional statement
> to invoke
> + * the call only if the corresponding logging level is enabled. So
> the above
> + * call may end up looking like:
> + * <pre>
> + * if (log.isDebugEnabled())
> + * {
> + * log.debug("Started processing of " + obj1 + " with action
> " + obj2);
> + * }
> + * </pre>
> + * Ideally, this structure should always be used to avoid the cost
> of building the
> + * dynamic string (concatenation) and making the unnecessary call.
> The only
> + * drawback to this is that code can become less readable. In some
> cases, there
> + * might be more code devoted to logging than the actual behavior
> required by a
> + * method.</p>
> + *
> + * <p>A cleaner way to do the logging is to use this interface
> where simple
> + * objects without any concatenation are passed as arguments.
> Albeit the call
> + * itself may still be a no-op when the logging level is not
> enabled, this is
> + * still much smaller than the concatenation process with dynamic
> strings. Each
> + * of the methods defined here will first check to see if the
> logging level is enabled,
> + * if that feature exists in the underlying logging system. If and
> only if that logging
> + * level is enabled, will the implementation proceed with
> concatenation of the strings
> + * and objects passed. So the above code using this interface
> becomes:
> + * <pre>
> + * log.debug("Started processing of {0} with action {1}, obj1,
> obj2);
> + * </pre>
> + * </p>
> + *
> + * <p>The interpolation of parameters into the message string are
> done using
> + * {@link java.text.MessageFormat}. See the documentation on that
> class for
> + * more ideas of interpolation possibilities. In the above code,
> <code>obj1</code>
> + * and <code>obj2</code> simply have their <code>toString()</code>
> methods invoked
> + * to produce a string which is then concatenated.</p>
> + *
> + * @author Gavin King
> + * @author David Allen
> + *
> + */
> +public interface Log
> +{
> + public boolean isDebugEnabled();
> + public boolean isErrorEnabled();
> + public boolean isFatalEnabled();
> + public boolean isInfoEnabled();
> + public boolean isTraceEnabled();
> + public boolean isWarnEnabled();
> + public void trace(Object object, Object... params);
> + public void trace(Object object, Throwable t, Object... params);
> + public void debug(Object object, Object... params);
> + public void debug(Object object, Throwable t, Object... params);
> + public void info(Object object, Object... params);
> + public void info(Object object, Throwable t, Object... params);
> + public void warn(Object object, Object... params);
> + public void warn(Object object, Throwable t, Object... params);
> + public void error(Object object, Object... params);
> + public void error(Object object, Throwable t, Object... params);
> + public void fatal(Object object, Object... params);
> + public void fatal(Object object, Throwable t, Object... params);
> +
> +}
> \ No newline at end of file
>
> Added: modules/trunk/logging/src/main/java/org/jboss/seam/log/
> Log4JProvider.java
> ===================================================================
> --- modules/trunk/logging/src/main/java/org/jboss/seam/log/
> Log4JProvider.java (rev 0)
> +++ modules/trunk/logging/src/main/java/org/jboss/seam/log/
> Log4JProvider.java 2009-04-21 09:38:36 UTC (rev 10542)
> @@ -0,0 +1,135 @@
> +package org.jboss.seam.log;
> +
> +import org.apache.log4j.Level;
> +import org.apache.log4j.Logger;
> +
> +/**
> + *
> + * @author Gavin King
> + *
> + */
> +final class Log4JProvider implements LogProvider
> +{
> + private final Logger logger;
> + private final boolean isWrapped;
> +
> + private static final String LOG_IMPL_FQCN =
> LogImpl.class.getName();
> + private static final String LOG_PROVIDER_FQCN =
> Log4JProvider.class.getName();
> +
> + private static final Level TRACE;
> + static
> + {
> + Object trace;
> + try
> + {
> + trace = Level.class.getDeclaredField("TRACE").get(null);
> + }
> + catch (Exception e)
> + {
> + trace = Level.DEBUG;
> + }
> + TRACE = (Level) trace;
> + }
> +
> + Log4JProvider(String category, boolean wrapped)
> + {
> + logger = Logger.getLogger(category);
> + isWrapped = wrapped;
> + }
> +
> + private String getFQCN()
> + {
> + return isWrapped ? LOG_IMPL_FQCN : LOG_PROVIDER_FQCN;
> + }
> +
> + public void debug(Object object)
> + {
> + logger.log(getFQCN(), Level.DEBUG, object, null);
> + }
> +
> + public void debug(Object object, Throwable t)
> + {
> + logger.log(getFQCN(), Level.DEBUG, object, t);
> + }
> +
> + public void error(Object object)
> + {
> + logger.log(getFQCN(), Level.ERROR, object, null);
> + }
> +
> + public void error(Object object, Throwable t)
> + {
> + logger.log(getFQCN(), Level.ERROR, object, t);
> + }
> +
> + public void fatal(Object object)
> + {
> + logger.log(getFQCN(), Level.FATAL, object, null);
> + }
> +
> + public void fatal(Object object, Throwable t)
> + {
> + logger.log(getFQCN(), Level.FATAL, object, t);
> + }
> +
> + public void info(Object object)
> + {
> + logger.log(getFQCN(), Level.INFO, object, null);
> + }
> +
> + public void info(Object object, Throwable t)
> + {
> + logger.log(getFQCN(), Level.INFO, object, t);
> + }
> +
> + public boolean isDebugEnabled()
> + {
> + return logger.isEnabledFor(Level.DEBUG);
> + }
> +
> + public boolean isErrorEnabled()
> + {
> + return logger.isEnabledFor(Level.ERROR);
> + }
> +
> + public boolean isFatalEnabled()
> + {
> + return logger.isEnabledFor(Level.FATAL);
> + }
> +
> + public boolean isInfoEnabled()
> + {
> + return logger.isEnabledFor(Level.INFO);
> + }
> +
> + public boolean isTraceEnabled()
> + {
> + return logger.isEnabledFor(TRACE);
> + }
> +
> + public boolean isWarnEnabled()
> + {
> + return logger.isEnabledFor(Level.WARN);
> + }
> +
> + public void trace(Object object)
> + {
> + logger.log(getFQCN(), TRACE, object, null);
> + }
> +
> + public void trace(Object object, Throwable t)
> + {
> + logger.log(getFQCN(), TRACE, object, t);
> + }
> +
> + public void warn(Object object)
> + {
> + logger.log(getFQCN(), Level.WARN, object, null);
> + }
> +
> + public void warn(Object object, Throwable t)
> + {
> + logger.log(getFQCN(), Level.WARN, object, t);
> + }
> +
> +}
>
> Added: modules/trunk/logging/src/main/java/org/jboss/seam/log/
> LogImpl.java
> ===================================================================
> --- modules/trunk/logging/src/main/java/org/jboss/seam/log/
> LogImpl.java (rev 0)
> +++ modules/trunk/logging/src/main/java/org/jboss/seam/log/
> LogImpl.java 2009-04-21 09:38:36 UTC (rev 10542)
> @@ -0,0 +1,184 @@
> +package org.jboss.seam.log;
> +
> +import java.io.Externalizable;
> +import java.io.IOException;
> +import java.io.ObjectInput;
> +import java.io.ObjectOutput;
> +import java.text.MessageFormat;
> +import java.util.Arrays;
> +
> +/**
> + *
> + * @author Gavin King
> + *
> + */
> +class LogImpl implements Log, Externalizable
> +{
> + private transient LogProvider log;
> + private String category;
> +
> + public LogImpl()
> + {
> + }
> +
> + LogImpl(String category)
> + {
> + this.category = category;
> + this.log = Logging.getLogProvider(category, true);
> + }
> +
> + public boolean isDebugEnabled()
> + {
> + return log.isDebugEnabled();
> + }
> +
> + public boolean isErrorEnabled()
> + {
> + return log.isErrorEnabled();
> + }
> +
> + public boolean isFatalEnabled()
> + {
> + return log.isFatalEnabled();
> + }
> +
> + public boolean isInfoEnabled()
> + {
> + return log.isInfoEnabled();
> + }
> +
> + public boolean isTraceEnabled()
> + {
> + return log.isTraceEnabled();
> + }
> +
> + public boolean isWarnEnabled()
> + {
> + return log.isWarnEnabled();
> + }
> +
> + public void trace(Object object, Object... params)
> + {
> + if (isTraceEnabled())
> + {
> + log.trace(interpolate(object, params));
> + }
> + }
> +
> + public void trace(Object object, Throwable t, Object... params)
> + {
> + if (isTraceEnabled())
> + {
> + log.trace(interpolate(object, params), t);
> + }
> + }
> +
> + public void debug(Object object, Object... params)
> + {
> + if (isDebugEnabled())
> + {
> + log.debug(interpolate(object, params));
> + }
> + }
> +
> + public void debug(Object object, Throwable t, Object... params)
> + {
> + if (isDebugEnabled())
> + {
> + log.debug(interpolate(object, params), t);
> + }
> + }
> +
> + public void info(Object object, Object... params)
> + {
> + if (isInfoEnabled())
> + {
> + log.info(interpolate(object, params));
> + }
> + }
> +
> + public void info(Object object, Throwable t, Object... params)
> + {
> + if (isInfoEnabled())
> + {
> + log.info(interpolate(object, params), t);
> + }
> + }
> +
> + public void warn(Object object, Object... params)
> + {
> + if (isWarnEnabled())
> + {
> + log.warn(interpolate(object, params));
> + }
> + }
> +
> + public void warn(Object object, Throwable t, Object... params)
> + {
> + if (isWarnEnabled())
> + {
> + log.warn(interpolate(object, params), t);
> + }
> + }
> +
> + public void error(Object object, Object... params)
> + {
> + if (isErrorEnabled())
> + {
> + log.error(interpolate(object, params));
> + }
> + }
> +
> + public void error(Object object, Throwable t, Object... params)
> + {
> + if (isErrorEnabled())
> + {
> + log.error(interpolate(object, params), t);
> + }
> + }
> +
> + public void fatal(Object object, Object... params)
> + {
> + if (isFatalEnabled())
> + {
> + log.fatal(interpolate(object, params));
> + }
> + }
> +
> + public void fatal(Object object, Throwable t, Object... params)
> + {
> + if (isFatalEnabled())
> + {
> + log.fatal(interpolate(object, params), t);
> + }
> + }
> +
> + private Object interpolate(Object message, Object... params)
> + {
> + Object interpolatedMessage = message;
> + if (params.length > 0)
> + {
> + for (int i = 0; i < params.length; i++)
> + {
> + if (params[i].getClass().isArray())
> + {
> + params[i] = Arrays.asList((Object[]) params[i]);
> + }
> + }
> + interpolatedMessage =
> MessageFormat.format(message.toString(), params);
> + }
> + return interpolatedMessage;
> + }
> +
> + public void readExternal(ObjectInput in) throws IOException,
> ClassNotFoundException
> + {
> + category = (String) in.readObject();
> + log = Logging.getLogProvider(category, true);
> + }
> +
> + public void writeExternal(ObjectOutput out) throws IOException
> + {
> + out.writeObject(category);
> + }
> +
> +}
>
> Added: modules/trunk/logging/src/main/java/org/jboss/seam/log/
> LogProvider.java
> ===================================================================
> --- modules/trunk/logging/src/main/java/org/jboss/seam/log/
> LogProvider.java (rev 0)
> +++ modules/trunk/logging/src/main/java/org/jboss/seam/log/
> LogProvider.java 2009-04-21 09:38:36 UTC (rev 10542)
> @@ -0,0 +1,28 @@
> +package org.jboss.seam.log;
> +
> +/**
> + *
> + * @author Gavin King
> + *
> + */
> +public interface LogProvider
> +{
> + public void trace(Object object);
> + public void trace(Object object, Throwable t);
> + public void debug(Object object);
> + public void debug(Object object, Throwable t);
> + public void info(Object object);
> + public void info(Object object, Throwable t);
> + public void warn(Object object);
> + public void warn(Object object, Throwable t);
> + public void error(Object object);
> + public void error(Object object, Throwable t);
> + public void fatal(Object object);
> + public void fatal(Object object, Throwable t);
> + public boolean isTraceEnabled();
> + public boolean isDebugEnabled();
> + public boolean isInfoEnabled();
> + public boolean isWarnEnabled();
> + public boolean isErrorEnabled();
> + public boolean isFatalEnabled();
> +}
>
> Added: modules/trunk/logging/src/main/java/org/jboss/seam/log/
> Logging.java
> ===================================================================
> --- modules/trunk/logging/src/main/java/org/jboss/seam/log/
> Logging.java (rev 0)
> +++ modules/trunk/logging/src/main/java/org/jboss/seam/log/
> Logging.java 2009-04-21 09:38:36 UTC (rev 10542)
> @@ -0,0 +1,47 @@
> +package org.jboss.seam.log;
> +
> +/**
> + *
> + * @author Gavin King
> + *
> + */
> +public class Logging
> +{
> + private static final boolean isLog4JAvailable;
> +
> + static
> + {
> + boolean available;
> + try
> + {
> + Class.forName("org.apache.log4j.Logger");
> + available = true;
> + }
> + catch (ClassNotFoundException cnfe)
> + {
> + available = false;
> + }
> + isLog4JAvailable = available;
> + }
> +
> + public static Log getLog(String category)
> + {
> + return new LogImpl(category);
> + }
> +
> + public static Log getLog(Class<?> clazz)
> + {
> + return new LogImpl(clazz.getName());
> + }
> +
> + static LogProvider getLogProvider(String category, boolean
> wrapped)
> + {
> + return isLog4JAvailable ? new Log4JProvider(category,
> wrapped) : new JDKProvider(category, wrapped);
> + }
> +
> + public static LogProvider getLogProvider(Class<?> clazz)
> + {
> + return getLogProvider(clazz.getName(), false);
> + }
> +
> +}
>
> Added: modules/trunk/parent/pom.xml
> ===================================================================
> --- modules/trunk/parent/pom.xml (rev 0)
> +++ modules/trunk/parent/pom.xml 2009-04-21 09:38:36 UTC (rev 10542)
> @@ -0,0 +1,206 @@
> +<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance
> " xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd
> ">
> + <modelVersion>4.0.0</modelVersion>
> + <groupId>org.jboss.seam</groupId>
> + <artifactId>seam-parent</artifactId>
> + <packaging>pom</packaging>
> + <version>3.0.0-SNAPSHOT</version>
> +
> + <parent>
> + <groupId>org.jboss.seam</groupId>
> + <artifactId>seam-version-matrix</artifactId>
> + <version>3.0.0-SNAPSHOT</version>
> + </parent>
> +
> + <name>JBoss Seam</name>
> + <url>http://www.seamframework.org</url>
> +
> + <description>
> + JBoss Seam, an Enterprise Java Framework
> + </description>
> +
> + <developers>
> + <developer>
> + <name>Pete Muir</name>
> + <roles>
> + <role>Project Lead</role>
> + </roles>
> + <email>pete.muir(a)jboss.org</email>
> + <organization>JBoss, a division of Red Hat</organization>
> + <url>http://in.relation.to/Bloggers/Pete</url>
> + </developer>
> +
> + <developer>
> + <name>Shane Bryzak</name>
> + <organization>JBoss, a division of Red Hat</organization>
> + </developer>
> +
> + <developer>
> + <name>Norman Richards</name>
> + <organization>JBoss, a division of Red Hat</organization>
> + </developer>
> +
> + <developer>
> + <name>Dan Allen</name>
> + <organization>JBoss, a division of Red Hat</organization>
> + </developer>
> + </developers>
> +
> + <build>
> + <plugins>
> + <plugin>
> + <groupId>org.apache.maven.plugins</groupId>
> + <artifactId>maven-source-plugin</artifactId>
> + <executions>
> + <execution>
> + <id>attach-sources</id>
> + <phase>verify</phase>
> + <goals>
> + <goal>jar</goal>
> + </goals>
> + </execution>
> + </executions>
> + </plugin>
> + <plugin>
> + <groupId>org.apache.maven.plugins</groupId>
> + <artifactId>maven-enforcer-plugin</artifactId>
> + </plugin>
> + <plugin>
> + <groupId>org.apache.maven.plugins</groupId>
> + <artifactId>maven-release-plugin</artifactId>
> + <version>2.0-beta-8</version>
> + <configuration>
> + <tagBase>https://svn.jboss.org/repos/webbeans/ri/tags</
> tagBase>
> + <autoVersionSubmodules>true</autoVersionSubmodules>
> + </configuration>
> + </plugin>
> + </plugins>
> + <defaultGoal>package</defaultGoal>
> +
> + <pluginManagement>
> + <plugins>
> + <plugin>
> + <groupId>org.apache.maven.plugins</groupId>
> + <artifactId>maven-compiler-plugin</artifactId>
> + <configuration>
> + <source>1.5</source>
> + <target>1.5</target>
> + </configuration>
> + </plugin>
> + <plugin>
> + <groupId>org.apache.maven.plugins</groupId>
> + <artifactId>maven-jar-plugin</artifactId>
> + <configuration>
> + <archive>
> + <manifest>
> + <addDefaultImplementationEntries>
> + true
> + </addDefaultImplementationEntries>
> + <addDefaultSpecificationEntries>
> + true
> + </addDefaultSpecificationEntries>
> + </manifest>
> + </archive>
> + </configuration>
> + </plugin>
> + <plugin>
> + <groupId>org.codehaus.mojo</groupId>
> + <artifactId>emma-maven-plugin</artifactId>
> + <configuration>
> + <forkMode>once</forkMode>
> + <metadataFile>../target/coverage.em</metadataFile>
> + <outputDirectory>${project.build.directory}/
> generated-classes</outputDirectory>
> + </configuration>
> + </plugin>
> + </plugins>
> + </pluginManagement>
> + </build>
> +
> + <profiles>
> + <profile>
> + <id>api-coverage</id>
> + <activation>
> + <property>
> + <name>apiCoverage</name>
> + </property>
> + </activation>
> + <build>
> + <plugins>
> + <plugin>
> + <groupId>org.apache.maven.plugins</groupId>
> + <artifactId>maven-surefire-plugin</artifactId>
> + <inherited>true</inherited>
> + <configuration>
> + <forkMode>once</forkMode>
> + </configuration>
> + </plugin>
> + </plugins>
> + </build>
> + <dependencies>
> + <dependency>
> + <groupId>emma</groupId>
> + <artifactId>emma</artifactId>
> + <version>2.0.5312</version>
> + <scope>test</scope>
> + </dependency>
> + </dependencies>
> + </profile>
> + </profiles>
> +
> + <ciManagement>
> + <system>Hudson</system>
> + <url />
> + </ciManagement>
> +
> + <issueManagement>
> + <system>JIRA</system>
> + <url>http://jira.jboss.org/browse/JBSEAM</url>
> + </issueManagement>
> +
> + <inceptionYear>2008</inceptionYear>
> +
> + <licenses>
> + <license>
> + <name>Lesser Gnu Public License, Version 2.1</name>
> + <url>http://www.gnu.org/licenses/lgpl-2.1.html</url>
> + </license>
> + </licenses>
> +
> + <scm>
> + <connection>scm:svn:http://anonsvn.jboss.org/repos/seam</
> connection>
> + <developerConnection>scm:svn:https://svn.jboss.org/repos/
> seam</developerConnection>
> + <url>http://fisheye.jboss.org/browse/Seam</url>
> + </scm>
> +
> + <distributionManagement>
> + <repository>
> + <!-- Copy the dist to the local checkout of the JBoss
> maven2 repo ${maven.repository.root} -->
> + <!-- It is anticipated that ${maven.repository.root} be
> set in user's settings.xml -->
> + <!-- todo : replace this with direct svn access once the
> svnkit providers are available -->
> + <id>repository.jboss.org</id>
> + <url>file://${maven.repository.root}</url>
> + </repository>
> + <snapshotRepository>
> + <id>snapshots.jboss.org</id>
> + <name>JBoss Snapshot Repository</name>
> + <url>dav:https://snapshots.jboss.org/maven2</url>
> + </snapshotRepository>
> + </distributionManagement>
> +
> + <reporting>
> + <plugins>
> + <plugin>
> + <groupId>org.codehaus.mojo</groupId>
> + <artifactId>cobertura-maven-plugin</artifactId>
> + <configuration>
> + <formats>
> + <format>html</format>
> + <format>xml</format>
> + </formats>
> + <instrumentation>
> + </instrumentation>
> + </configuration>
> + </plugin>
> + </plugins>
> + </reporting>
> +
> +</project>
>
> Modified: modules/trunk/security/pom.xml
> ===================================================================
> --- modules/trunk/security/pom.xml 2009-04-21 08:51:33 UTC (rev 10541)
> +++ modules/trunk/security/pom.xml 2009-04-21 09:38:36 UTC (rev 10542)
> @@ -1,8 +1,13 @@
> <project xmlns="http://maven.apache.org/POM/4.0.0"
> xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
> xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd
> ">
> - <modelVersion>4.0.0</modelVersion>
> -
> + <parent>
> + <artifactId>seam-parent</artifactId>
> + <groupId>org.jboss.seam</groupId>
> + <version>3.0.0-SNAPSHOT</version>
> + </parent>
> +
> + <modelVersion>4.0.0</modelVersion>
> <groupId>org.jboss.seam</groupId>
> <artifactId>seam-security</artifactId>
> <packaging>jar</packaging>
> @@ -13,7 +18,6 @@
> <dependency>
> <groupId>org.jboss.webbeans</groupId>
> <artifactId>jsr299-api</artifactId>
> - <version>1.0.0-SNAPSHOT</version>
> </dependency>
>
> </dependencies>
>
> Modified: modules/trunk/version-matrix/pom.xml
> ===================================================================
> --- modules/trunk/version-matrix/pom.xml 2009-04-21 08:51:33 UTC
> (rev 10541)
> +++ modules/trunk/version-matrix/pom.xml 2009-04-21 09:38:36 UTC
> (rev 10542)
> @@ -51,7 +51,6 @@
>
> <properties>
> <seam.version>3.0.0-SNAPSHOT</seam.version>
> - <webbeans.version>1.0.0-SNAPSHOT</webbeans.version>
> </properties>
>
> <dependencyManagement>
> @@ -141,31 +140,7 @@
> <artifactId>el-ri</artifactId>
> <version>1.2</version>
> </dependency>
> -
> - <dependency>
> - <groupId>org.jboss.webbeans</groupId>
> - <artifactId>jsr299-api</artifactId>
> - <version>${webbeans.version}</version>
> - </dependency>
>
> - <dependency>
> - <groupId>org.jboss.webbeans</groupId>
> - <artifactId>webbeans-core</artifactId>
> - <version>${webbeans.version}</version>
> - </dependency>
> -
> - <dependency>
> - <groupId>org.jboss.webbeans</groupId>
> - <artifactId>webbeans-spi</artifactId>
> - <version>${webbeans.version}</version>
> - </dependency>
> -
> - <dependency>
> - <groupId>org.jboss.webbeans</groupId>
> - <artifactId>webbeans-porting-package</artifactId>
> - <version>${webbeans.version}</version>
> - </dependency>
> -
> </dependencies>
> </dependencyManagement>
>
>
> _______________________________________________
> seam-commits mailing list
> seam-commits(a)lists.jboss.org
> https://lists.jboss.org/mailman/listinfo/seam-commits
--
Pete Muir
http://www.seamframework.org
http://in.relation.to/Bloggers/Pete
15 years, 8 months
SecurityInterceptor warning
by Christian Bauer
A change in 2.1 branch in the last 10 days or so had this effect on
wiki test run, It's probably Shane's change on SecurityInterceptor
r10137 related to https://jira.jboss.org/jira/browse/JBSEAM-4003:
[testng] WARN [org.jboss.seam.Component] Interceptor class
org.jboss.seam.security.SecurityInterceptor has different type than
within interceptor class org.jboss.seam.transaction.RollbackInterceptor
[testng] WARN [org.jboss.seam.Component] Interceptor class
org.jboss.seam.security.SecurityInterceptor has different type than
within interceptor class org.jboss.seam.transaction.RollbackInterceptor
[testng] WARN [org.jboss.seam.Component] Interceptor class
org.jboss.seam.security.SecurityInterceptor has different type than
within interceptor class org.jboss.seam.transaction.RollbackInterceptor
[testng] WARN [org.jboss.seam.Component] Interceptor class
org.jboss.seam.security.SecurityInterceptor has different type than
within interceptor class org.jboss.seam.transaction.RollbackInterceptor
[testng] WARN [org.jboss.seam.Component] Interceptor class
org.jboss.seam.security.SecurityInterceptor has different type than
within interceptor class org.jboss.seam.transaction.RollbackInterceptor
[testng] WARN [org.jboss.seam.Component] Interceptor class
org.jboss.seam.security.SecurityInterceptor has different type than
within interceptor class org.jboss.seam.transaction.RollbackInterceptor
[testng] WARN [org.jboss.seam.Component] Interceptor class
org.jboss.seam.security.SecurityInterceptor has different type than
within interceptor class org.jboss.seam.transaction.RollbackInterceptor
[testng] WARN [org.jboss.seam.Component] Interceptor class
org.jboss.seam.security.SecurityInterceptor has different type than
within interceptor class org.jboss.seam.transaction.RollbackInterceptor
[testng] WARN [org.jboss.seam.Component] Interceptor class
org.jboss.seam.security.SecurityInterceptor has different type than
within interceptor class org.jboss.seam.transaction.RollbackInterceptor
[testng] WARN [org.jboss.seam.Component] Interceptor class
org.jboss.seam.security.SecurityInterceptor has different type than
within interceptor class org.jboss.seam.transaction.RollbackInterceptor
[testng] WARN [org.jboss.seam.Component] Interceptor class
org.jboss.seam.security.SecurityInterceptor has different type than
within interceptor class org.jboss.seam.transaction.RollbackInterceptor
[testng] WARN [org.jboss.seam.Component] Interceptor class
org.jboss.seam.security.SecurityInterceptor has different type than
within interceptor class org.jboss.seam.transaction.RollbackInterceptor
[testng] WARN [org.jboss.seam.Component] Interceptor class
org.jboss.seam.security.SecurityInterceptor has different type than
within interceptor class org.jboss.seam.transaction.RollbackInterceptor
...
15 years, 8 months
Seam 2.1.2.CR1 initial release testing
by Jozef Hartinger
Hello,
I've finished Seam 2.1.2.CR1 initial release testing recently. Here are
my findings:
1.) Added libraries: (since 2.1.1.GA)
> ./lib/src/jboss-seam-wicket-ant-sources.jar
> ./lib/commons-codec.jar
> ./lib/emma.jar
these are dependencies of functional tests:
> ./src/test/ftest/lib/ant-launcher.jar
> ./src/test/ftest/lib/ant.jar
> ./src/test/ftest/lib/jboss-test-1.0.5.GA.jar
these are dependencies of RESTEasy, however not all of them are needed,
I'll revise
> ./lib/FastInfoset.jar
> ./lib/junit.jar
> ./lib/sjsxp.jar
> ./lib/resteasy-jaxb-provider.jar
2.) Removed libraries
< ./lib/gen/el-api.jar
3.) Upgraded library versions (Note that only those with version
specified in MANIFEST file are listed here)
< /lib,jsf-api.jar,1.2_09-b01-BETA1
> /lib,jsf-api.jar,1.2_12-b01-FCS
< /lib,jsf-impl.jar,1.2_09-b01-BETA1
> /lib,jsf-impl.jar,1.2_12-b01-FCS
< /lib,richfaces-api.jar,3.2.2.SR1
< /lib,richfaces-impl.jar,3.2.2.SR1
< /lib,richfaces-ui.jar,3.2.2.SR1
> /lib,richfaces-api.jar,3.3.0.GA
> /lib,richfaces-impl.jar,3.3.0.GA
> /lib,richfaces-ui.jar,3.3.0.GA
< /lib,wicket-datetime.jar,1.3.3
< /lib,wicket-extensions.jar,1.3.3
< /lib,wicket-ioc.jar,1.3.3
< /lib,wicket.jar,1.3.3
> /lib,wicket-datetime.jar,1.3-SNAPSHOT
> /lib,wicket-extensions.jar,1.3-SNAPSHOT
> /lib,wicket-ioc.jar,1.3-SNAPSHOT
> /lib,wicket.jar,1.3-SNAPSHOT
This is a PROBLEM I think as there should be no SNAPSHOTs among dependencies
4.) Other problems
* restbay's components.xml does not pass validation
--
Jozef Hartinger
Seam QA Engineer
Office phone: +420 532 294 130, ext 82-62 130
Mobile phone: +420 608 357 852
E-mail: jharting(a)redhat.com
15 years, 8 months
Re: [seam-dev] java.lang.IllegalStateException: No phase id bound to current thread (make sure you do not have two SeamPhaseListener instances installed))
by Max Rydahl Andersen
----- "Pete Muir" <pmuir(a)redhat.com> wrote:
> Replace JSF with an up to date version. JSF lives in server/default/
> deploy/jboss-web.deployer/jsf-libs/{jsf-api.jar, jsf-impl.jar}.
Thanks, I'll get that into our FQA.
> Or use JBoss 5.
Which won't work with hotdeployment - another thread ;)
/max
>
> On 7 Apr 2009, at 13:21, Max Rydahl Andersen wrote:
>
> >
> > ----- "Pete Muir" <pmuir(a)redhat.com> wrote:
> >
> >> On 7 Apr 2009, at 13:11, Max Rydahl Andersen wrote:
> >>
> >>>
> >>>> Sorry, it's only post JBoss AS 4.2.3 that JSF 1.2.10 was
> included,
> >>>> 4.2.3 has 1.2.09...
> >>>
> >>> You need to spoon feed me here - i'm still groggy from friday ;)
> >>>
> >>> This means Seam 2.1.1 won't work on any current community
> released
> >>
> >>> JBoss AS 4.2.x
> >>> if it uses meta-inf to declare dependencies ?
> >>
> >> Not ootb.
> >
> > Ok - any pointers to what community users can do to fix their AS
> > 4.2.3 installation
> > to work as well as JBoss EAP 4.3 ?
> >
> > /max
> >
> >>
> >>>
> >>>
> >>> /max
> >>>
> >>>>
> >>>> On 7 Apr 2009, at 12:44, Max Rydahl Andersen wrote:
> >>>>
> >>>>>
> >>>>> ----- "Pete Muir" <pmuir(a)redhat.com> wrote:
> >>>>>
> >>>>>> Here is the canonical JIRA https://jira.jboss.org/jira/browse/
> >>>>>> JBIDE-2190, and the answer is given by the OP - this was an
> >> issue
> >>>>
> >>>>>> with
> >>>>>>
> >>>>>> JSF < 1.2_10, the first version of JBoss AS that incorporates
> >> this
> >>>> is
> >>>>>>
> >>>>>> 4.2.3 or 5.
> >>>>>
> >>>>> He *is* using 4.2.3:
> >>>>>
> >>>>> "Deployed to JBoss AS 4.2.3.GA."
> >>>>>
> >>>>> Any other suggestions ? :)
> >>>>
> >>>> Upgrade JSF to 1.2.10 or later? Bug JBoss AS team for a release?
> >> Use
> >>>>
> >>>> JBoss 5?
> >>>>
> >>>>>
> >>>>>
> >>>>>> There is no Seam version that fixes this, as it's not a bug in
> >>>> Seam
> >>>>>> (nb Seam had a related problem, but we fixed that for 2.1.0).
> >>>>>>
> >>>>>> Really, I would recommend that you switch to not using
> >> MANIFEST.MF
> >>>>
> >>>>>> for
> >>>>>>
> >>>>>> defining the classpath of apps, but instead use lib/
> >> directories.
> >>>>>> https://jira.jboss.org/jira/browse/JBIDE-4136
> >>>>>
> >>>>> Using meta-inf is spec and should just work. Plus it is what
> all
> >>>>> IDE's supports and
> >>>>> it is not available for J2EE 1.4 apps.
> >>>>
> >>>> Right, but it's not recommended packaging for Seam apps.
> However,
> >> we
> >>>>
> >>>> are doing our best to support it - just you need to use newer
> >>>> versions
> >>>>
> >>>> of stuff...
> >>>>
> >>>>>
> >>>>>
> >>>>> I'm fighting hard with Eclipse to fix their broken lib support
> >> but
> >>>>
> >>>>> until
> >>>>> then my hands are tied in that direction.
> >>>>>
> >>>>> /max
> >>>>>
> >>>>>>
> >>>>>> On 7 Apr 2009, at 09:33, Max Rydahl Andersen wrote:
> >>>>>>
> >>>>>>> Hi guys,
> >>>>>>>
> >>>>>>> Please see
> >>>>>>
> >>>>
> >>
> http://www.jboss.org/index.html?module=bb&op=viewtopic&p=4223780#4223780
> >>>>>>>
> >>>>>>> We keep bumping into this "two listener instances installed"
> on
> >>>> Seam
> >>>>>>
> >>>>>>> 2.1.x.
> >>>>>>>
> >>>>>>> Remind me again why this happens on deployments that works
> >> great
> >>>> on
> >>>>>>
> >>>>>>> all previous versions of Seam ?
> >>>>>>>
> >>>>>>> Can I point users to Seam 2.1.2 builds that will fix this ?
> >>>>>>>
> >>>>>>> /max
> >>>>>>> _______________________________________________
> >>>>>>> seam-dev mailing list
> >>>>>>> seam-dev(a)lists.jboss.org
> >>>>>>> https://lists.jboss.org/mailman/listinfo/seam-dev
> >>>>>>
> >>>>>> --
> >>>>>> Pete Muir
> >>>>>> http://www.seamframework.org
> >>>>>> http://in.relation.to/Bloggers/Pete
> >>>>
> >>>> --
> >>>> Pete Muir
> >>>> http://www.seamframework.org
> >>>> http://in.relation.to/Bloggers/Pete
> >>
> >> --
> >> Pete Muir
> >> http://www.seamframework.org
> >> http://in.relation.to/Bloggers/Pete
>
> --
> Pete Muir
> http://www.seamframework.org
> http://in.relation.to/Bloggers/Pete
15 years, 8 months
seam 2.1.2.CR1 tag
by Norman Richards
I need to tag CR1 shortly. If anyone needs anything in CR1, let me
know now.
15 years, 8 months
JSF and CSRF
by Christian Bauer
On Mar 10, 2009, at 01:10 , Dan Allen wrote:
> I have opened an issue in Mojarra about the build during restore
> feature that was/is planned for JSF 2.0, also mentioning the problem
> with the insecurity javax.faces.ViewState token that is used in
> server-side state saving. Feel free to comment or follow.
>
> https://javaserverfaces.dev.java.net/issues/show_bug.cgi?id=1028
>
> I agree that the token is completely insecure and predictable. But
> the build during restore is even scarier because all tokens go right
> out the window...we just have a plain old HTML form that can post
> into a JSF application.
>
> I think the insecure token can be fixed in JSF 2.0 and the build
> during restore should only be enabled only in JSF 2.1 when we have a
> secure token than can accompany it. The idea, I think, is to allow
> the client to store a representation of the view, but not
> necessarily the *whole* serialized view, opening the door for the
> view to be rebuilt on the server if it got dumped. It's sort of a
> hybrid of client- and server-side state saving. Am I off base?
What follows is a longer analysis and some of my (probably/hopefully
wrong) conclusions are worrying. I'd welcome any replies and
corrections before I'll merge this with the other CSRF wiki pages. I
think we need a clear strategy here that everyone understands and
agrees on.
We have two contradicting objectives, we can't have it all
automagically.
1. You want forms on a webpage that are submitted via POST,
independent of any session state on the server. Typically these are
login or comment forms, or any view that users might keep open for a
long time until the session expires, and then trigger a POST request
that should be valid.
2. You don't want POST requests accepted by the server that execute an
action without any forgery protection. Otherwise you are vulnerable to
CSRF attacks. Common remedies are bound to the user's session in one
way or another. The best protection is offered by strong random tokens
in hidden form fields that are validated against the stored value in
the user's session. Weaker but still acceptable protection would be
duplicate sending of the session identifier - in the cookie by the
browser AND as a request parameter or hidden POST data. An attacker
would have to guess either the random token value or the session
identifier to forge a request.
JSF (and probably Seam) need to offer you tools so you can balance
these goals on a per-case basis.
First consider JSF 1.x:
You can globally configure client-side state saving. If you are saving
the view serialized on the client, and the server is configured to
accept this serialized state of a view without any further privilege
validation, your application is vulnerable to CSRF. So while you get
objective 1, it completely ignores objective 2. Worse, it's a global
switch that affects _all_ of your forms/views. Also, it doesn't matter
that the client state is saved in a "complex" hidden form value, an
attacker can forge that too. The server will accept it as long as it's
well-formed and can be deserialized.
To protect against tampering (!NOT! CSRF) the Sun JSF RI offers
encryption of the client-side state with a configurable global
password. See http://wiki.glassfish.java.net/Wiki.jsp?page=JavaServerFacesRI#section-Ja...
- The issue here is that the view state cyphertext in the hidden
form field also comes with at least part of the original plaintext,
making it easier to crack the global password, see last comment on https://javaserverfaces.dev.java.net/issues/show_bug.cgi?id=906
(I never really bothered with client-side state saving so the
following might be wrong.) I don't think client-side state saving can
be made secure against CSRF attacks without losing its main benefit.
Consider the following "replay" attack procedure:
- Attacker goes to vulnerable website and grabs the encrypted view
state of the hidden field in a comment form.
- Attacker goes to vulnerable website and posts a new comment, linking
to his own website.
- Victim goes to the vulnerable website and follows the link to the
attackers website.
- Victim clicks on a button on the attackers website.
- A forged POST request will be send to the vulnerable website, riding
the victims still active session.
- The forged POST request contained the valid encrypted view state
(decrypted with a global password), and the attackers data.
The only protection against this kind of attack would be a session
identifier included in the view state (or at least in the request
outside of the cookie), which means we don't get session independence
of the form/view! Another protection would be globally incremented
component identifiers, so that an old view state with "lower" values
than the current can not be replayed. This might be a way out but I'm
not sure at this point how secure it really is. After all, developers
can assign their own client component identifiers for e.g. JavaScript
access.
You can globally configure server-side state saving. The server will
throw a ViewExpiredException if a POST request arrives without a valid
(present in session) view identifier. This completely ignores
objective 1 but offers some protection against CSRF. Unfortunately,
the JSF RI generates a predictable view identifier. This needs to be
fixed, see https://javaserverfaces.dev.java.net/issues/show_bug.cgi?id=812
You can globally configure Facelets BUILD_BEFORE_RESTORE option for
server-side state saving. This, like client-side state saving, gets
you objective 1 but again on a global basis. Worse, the attacker
doesn't even have to forge the potentially complex serialized view
state, break the encryption, or mount a replay attack. Definitely not
recommended.
I don't consider page actions, @WebRemote or even REST request
processing here, the issues for these are similar.
So if my analysis is correct, JSF 1.x offers weak protection against
CSRF if you use server-side state saving, and nothing else.
For JSF 2.x this is what we need: A _non-global_ per-form switch to
define how the view state should be restored. These would be my
recommendations:
- Global client-side state saving should not be enabled by default.
Only if a POST request contains the session identifier (in the view
state data or as a hidden form field, NOT COOKIE) will client-side
state saving be secure against CSRF. Encryption alone does not
protect. Client-side state saving CAN NOT make POST requests
independent of the user's session and still offer CSRF protection. So,
client-side state saving should not be considered for security
reasons, but only to improve performance in certain scenarios (small
session state on server, free bandwidth on intranet, etc). There
should be no difference in behavior between client- and server-side
state saving when a session expires on the server.
- This should be the global default: Server-side state saving with a
mandatory strong token on all POST requests. Server-side state saving
should be protected with a per-request token which acts as a secondary
session- (or per-form) identifier that is not transmitted
automatically by the browser (hidden form field, not cookie). The
token value should be cryptographically strong to prevent brute force
attacks. The ViewExpiredException is thrown if the view can't be
restored from session state. If the JSF 2.x specification does not
have this default, Seam needs to offer it automatically on top of JSF,
to make it secure.
- The framework (JSF or Seam) has to offer, on a per-form or per-view
basis, the BUILD_BEFORE_RESTORE option. That way, when I have an
idempotent action or what I consider safe form on a page, I can make
it independent of the current user's session state. I'd typically do
this for the minority of my forms in a real web application, probably
the login form, the search form, and the comment form. Note that if my
analysis of client-side state saving is correct (session affinity),
this feature is completely independent of what is configured globally.
- Other request processing such as @WebRemote and ("stateful") REST
would have to be secured with a per-request token that is checked
against the token in the user's session. It's debatable whether this
should be the default or if I'd need to enable it for each method/
request path. It's probably OK to tell users that these requests
should be idempotent and if they want to delete their database with a
@WebRemote method, they should protect it properly. REST processing is
a different matter, here we have to deal with a potentially stateless
server tier, no user sessions. (This issue is apparently being ignored
by REST proponents. Rails also offers only a session-stored hidden
form field token.) Maybe it's good enough if we'd implement the weaker
CSRF protection for both @WebRemote and stateful REST: Not a per-form
random token, but an additional transmission of the session identifier
outside of a cookie (see next item).
- GET request processing of page actions should IF AT ALL POSSIBLE be
idempotent requests, however, Seam CAN offer double validation of the
session identifier (once in the cookie, again as an extra request
parameter). It would be better to tell users that page actions should
be "read-only" methods.
Dan, if you compare these recommendations to what is/will be in JSF
2.0 and the RI, I think the last three are missing and we need to
deliver them in Seam.
15 years, 8 months