Index: main/plugin-core/plugin.xml
===================================================================
--- main/plugin-core/plugin.xml	(revision 26170)
+++ main/plugin-core/plugin.xml	(working copy)
@@ -31,6 +31,32 @@
 	 -->
 
     <config>
+    	<!-- Login security parameter -->
+    	<param id="runtime.login.security.level" type="string">
+            <!-- 
+                This parameter defines the security level of the login.
+             -->
+            <label i18n="true">PLUGINS_CORE_SECURITY_LEVEL_LOGIN_LABEL</label>
+            <description i18n="true">PLUGINS_CORE_SECURITY_LEVEL_LOGIN_DESCRIPTION</description>
+            <enumeration>
+            	<entry>
+            		<label i18n="true">PLUGINS_CORE_SECURITY_LEVEL_LOGIN_HIGH</label>
+        			<value>high</value>
+            	</entry>
+        		<entry>
+            		<label i18n="true">PLUGINS_CORE_SECURITY_LEVEL_LOGIN_LOW</label>
+            		<value>low</value>
+        		</entry>
+        	</enumeration>
+        	<validation>
+                <mandatory/>
+            </validation>
+            <default-value>2</default-value>
+            <category i18n="true">PLUGINS_CORE_SECURITY_LEVEL_LOGIN_CONFIG_CATEGORY</category>
+            <group i18n="true">PLUGINS_CORE_SECURITY_LEVEL_LOGIN_CONFIG_CATEGORY_GROUP</group>
+            <order>1</order>
+        </param>
+    
         <!-- Debug parameters -->
         <param id="runtime.debug.ui" type="boolean">
             <!-- 
@@ -1246,7 +1272,8 @@
         <!-- 
             The same as runtime.user.impl.jdbc.core but where users can be authentified through the API
             @see:plugin{feature/runtime.user.impl.jdbc.core}
-         -->
+         -->         
+         
         <extensions>
             <extension point="org.ametys.runtime.user.UsersManager"
                        id="org.ametys.runtime.plugins.core.user.CoreCredentialsAwareJdbc"
@@ -1984,6 +2011,10 @@
         	This features defines the form based credential provider. Data are sent to the provider through a
         	html form. If the option is enabled, user's data can be stored with a cookie.
          -->
+        <config>
+            <param-ref id="runtime.login.security.level"/>
+        </config>
+         
         <extensions>
             <extension point="org.ametys.runtime.authentication.CredentialsProvider"
                        id="org.ametys.runtime.plugins.core.authentication.FormBased"
@@ -1992,6 +2023,8 @@
             	<username-field>Username</username-field>
             	<password-field>Password</password-field>
             	<rememberMe-field>rememberMe</rememberMe-field>
+            	<captchaKey-field>captcha-key</captchaKey-field>
+            	<captchaAnswer-field>captcha</captchaAnswer-field>
             	<cookie>
             		<cookieEnabled>true</cookieEnabled>
             		<cookieLifeTime>604800</cookieLifeTime>
Index: main/plugin-core/src/org/ametys/runtime/plugins/core/authentication/FormBasedCredentialsProvider.java
===================================================================
--- main/plugin-core/src/org/ametys/runtime/plugins/core/authentication/FormBasedCredentialsProvider.java	(revision 26170)
+++ main/plugin-core/src/org/ametys/runtime/plugins/core/authentication/FormBasedCredentialsProvider.java	(working copy)
@@ -35,8 +35,10 @@
 import org.apache.cocoon.environment.http.HttpCookie;
 import org.apache.commons.lang.StringUtils;
 
+import org.ametys.cms.captcha.CaptchaHelper;
 import org.ametys.runtime.authentication.Credentials;
 import org.ametys.runtime.authentication.CredentialsProvider;
+import org.ametys.runtime.config.Config;
 import org.ametys.runtime.workspace.WorkspaceMatcher;
 
 /**
@@ -74,12 +76,23 @@
     /** Password value in case of info retrieved from cookie */
     public static final String AUTHENTICATION_BY_COOKIE = "authentication_by_cookie";
     
+    /** Low security level */
+    public static final String SECURITY_LEVEL_LOW = "low";
+    /** High security level */
+    public static final String SECURITY_LEVEL_HIGH = "high";
+    
     /** Name of the user name html field */
     protected String _usernameField;
 
     /** Name of the user password html field */
     protected String _passwordField;
     
+    /** Name of the captcha answer html field */
+    protected String _captchaField;
+
+    /** Name of the captcha key html field */
+    protected String _captchaKeyField;
+    
     /** Name of the "remember me" html field */
     protected String _rememberMeField;
 
@@ -180,29 +193,33 @@
         {
             getLogger().info("URL accepted : " + url);
         }
-        
+
         return accept;
     }
     
     public void allowed(Redirector redirector)
     {
-        Request request = ContextHelper.getRequest(_context);
-        
-        String value = getCookieValue(request, _cookieName);
-        if (value != null && !"".equals(value))
-        {
-            updateCookie(value, _cookieName, (int) _cookieLifetime, _context);
-        }
-        else
+        String level = Config.getInstance().getValueAsString("runtime.login.security.level");
+        if (level.equals(SECURITY_LEVEL_LOW))
         {
-            String login = request.getParameter(_usernameField);
-            String password = request.getParameter(_passwordField);
-            String rememberMe = request.getParameter(_rememberMeField);
-            if (rememberMe != null)
+            Request request = ContextHelper.getRequest(_context);
+           
+            String value = getCookieValue(request, _cookieName);
+            if (value != null && !"".equals(value))
+            {
+                updateCookie(value, _cookieName, (int) _cookieLifetime, _context);
+            }
+            else
             {
-                if (rememberMe.equalsIgnoreCase("true"))
+                String login = request.getParameter(_usernameField);
+                String password = request.getParameter(_passwordField);
+                String rememberMe = request.getParameter(_rememberMeField);
+                if (rememberMe != null)
                 {
-                    updateCookie(login + "/n" + password, _cookieName, (int) _cookieLifetime, _context);
+                    if (rememberMe.equalsIgnoreCase("true"))
+                    {
+                        updateCookie(login + "/n" + password, _cookieName, (int) _cookieLifetime, _context);
+                    }
                 }
             }
         }
@@ -217,7 +234,20 @@
 
         if (login != null && password != null)
         {
+            String level = Config.getInstance().getValueAsString("runtime.login.security.level");
+            if (level.equals(SECURITY_LEVEL_HIGH))
+            {
+                String answer = request.getParameter(_captchaField);
+                String captchaKey = request.getParameter(_captchaKeyField);
+                
+                if (captchaKey == null || !CaptchaHelper.checkAndInvalidate(captchaKey, answer)) 
+                {
+                    return null;
+                }
+            }
+            
             return new Credentials(login, password);
+            
         }
 
         String value = getCookieValue(request, _cookieName);
@@ -272,6 +302,8 @@
     {
         _usernameField = configuration.getChild("username-field").getValue("Username");
         _passwordField = configuration.getChild("password-field").getValue("Password");
+        _captchaField = configuration.getChild("captchaAnswer-field").getValue("captcha");
+        _captchaKeyField = configuration.getChild("captchaKey-field").getValue("captcha-key");
         _rememberMeField =  configuration.getChild("rememberMe-field").getValue("rememberMe");
         _cookieEnabled = configuration.getChild("cookie").getChild("cookieEnabled").getValueAsBoolean(true);
         _cookieLifetime = configuration.getChild("cookie").getChild("cookieLifeTime").getValueAsLong(604800);
Index: main/plugin-core/i18n/messages_fr.xml
===================================================================
--- main/plugin-core/i18n/messages_fr.xml	(revision 26170)
+++ main/plugin-core/i18n/messages_fr.xml	(working copy)
@@ -257,6 +257,13 @@
 
     <message key="PLUGINS_CORE_VALIDATOR_TEXT_MAXLENGTH">La valeur de ce champ est trop longue</message>
 
+	<!-- SECURITY LEVEL CORE -->
+	<message key="PLUGINS_CORE_SECURITY_LEVEL_LOGIN_LABEL">Niveau de sécurité</message>
+    <message key="PLUGINS_CORE_SECURITY_LEVEL_LOGIN_DESCRIPTION">Niveau de sécurité du formulaire de connexion</message>
+    <message key="PLUGINS_CORE_SECURITY_LEVEL_LOGIN_HIGH">Fort</message>
+    <message key="PLUGINS_CORE_SECURITY_LEVEL_LOGIN_LOW">Faible</message>
+    <message key="PLUGINS_CORE_SECURITY_LEVEL_LOGIN_CONFIG_CATEGORY">Connexion back-office</message>
+    <message key="PLUGINS_CORE_SECURITY_LEVEL_LOGIN_CONFIG_CATEGORY_GROUP">Formulaire de connexion</message>
 
     <!-- DATASOURCE CORE -->
     <message key="PLUGINS_CORE_DATASOURCE_CORE_CONFIG_JDBC_CATEGORY_DATASOURCE">Base de données</message>
Index: main/plugin-core/i18n/messages_en.xml
===================================================================
--- main/plugin-core/i18n/messages_en.xml	(revision 26170)
+++ main/plugin-core/i18n/messages_en.xml	(working copy)
@@ -257,6 +257,14 @@
     
     <message key="PLUGINS_CORE_VALIDATOR_TEXT_MAXLENGTH">The value of this field is too long</message>
 
+	<!-- SECURITY LEVEL CORE -->
+	<message key="PLUGINS_CORE_SECURITY_LEVEL_LOGIN_LABEL">Security level</message>
+    <message key="PLUGINS_CORE_SECURITY_LEVEL_LOGIN_DESCRIPTION">Security level of the autentification form</message>
+    <message key="PLUGINS_CORE_SECURITY_LEVEL_LOGIN_HIGH">High</message>
+    <message key="PLUGINS_CORE_SECURITY_LEVEL_LOGIN_LOW">Low</message>
+    <message key="PLUGINS_CORE_SECURITY_LEVEL_LOGIN_CONFIG_CATEGORY">Back-office connexion</message>
+    <message key="PLUGINS_CORE_SECURITY_LEVEL_LOGIN_CONFIG_CATEGORY_GROUP">Connexion form</message>
+
     <!-- DATASOURCE CORE -->
     <message key="PLUGINS_CORE_DATASOURCE_CORE_CONFIG_JDBC_CATEGORY_DATASOURCE">Database</message>
 
