diff --git a/bin/account-manager-client.pl b/bin/account-manager-client.pl
index 79a2c3c06b86ee289f6362786bf016435a259892..8f98bfaa0c6227da24c9d64c3ca2a15ae5012b2f 100755
--- a/bin/account-manager-client.pl
+++ b/bin/account-manager-client.pl
@@ -134,7 +134,8 @@ if ($options{'add_test_account'}) {
          IdPAccountManager::Tools::do_log('error',"Failed to create token object");
          exit -1;
     }
-    unless ($authentication_token->set('email_address' => $options{'email_address'})) {
+    unless ($authentication_token->set('email_address' => $options{'email_address'},
+                                       'sp_entityid' => $options{'sp_entityid'})) {
         IdPAccountManager::Tools::do_log('error',"Failed to set token value");
         exit -1;
     }    
diff --git a/bin/account-manager-web.pl b/bin/account-manager-web.pl
index 5707ee989e3ecf13b2872f986b59cb2a01cd83f8..eaf7e61cf25f0f134e2ccb5c88d0bde0b50cbc26 100755
--- a/bin/account-manager-web.pl
+++ b/bin/account-manager-web.pl
@@ -17,6 +17,9 @@ use POSIX;
 
 use IdPAccountManager::TestAccount;
 use IdPAccountManager::SAMLMetadata;
+use IdPAccountManager::ServiceProvider;
+
+use IdPAccountManager::AuthenticationToken;
 
 ## Defining parameters format
 my $urn_or_url_regex = '(http(s?):\/\/|urn:)[^\\\$\*\"\'\`\^\|\<\>\n\s]+'; ## Format de type URL HTTP ou URN
@@ -31,6 +34,7 @@ my %format = (
 
 my %actions = ('select_sp' => {'title_en' => 'Select your Service Provider'    },
                'get_sp_list' => {'title_en' => 'Select your Service Provider'    },
+               'generate_token' => {'title_en' => 'Generate an authentication token'},
     );
 
 ## Gives writes for the group
@@ -210,17 +214,18 @@ sub respond {
   }
   
    ## Ignore some type of errors
-   #my @errors_admin;
-   #foreach my $id_error (@{$self->{'param_out'}{'errors'}}) {
-   #  unless ($id_error =~ /^(error_x)$/) {
-   #      push @errors_admin, $id_error;
-   #  }
-   #}
+   my @errors_admin;
+   foreach my $id_error (@{$self->{'param_out'}{'errors'}}) {
+     unless ($id_error =~ /^(error_x)$/) {
+         push @errors_admin, $id_error;
+     }
+   }
       
    ## Mail notification of admins about the error
-   &IdPAccountManager::Tools::mail_notice('template' => 'templates/mail/notification_generic_error.tt2.eml', 
- 		 'data' => $self->{'param_out'});
-
+   if (@errors_admin) {
+       &IdPAccountManager::Tools::mail_notice('template' => 'templates/mail/notification_generic_error.tt2.eml', 
+         		 'data' => $self->{'param_out'});
+   }
 }
 
 ## Return the list of known SPs
@@ -276,3 +281,55 @@ sub req_select_sp {
     
     return 1;
 }
+
+## Generate an authentication token to validate an email address
+## Sample call : dev-edugain.renater.fr/accountmanager?action=generate_token&style=nobanner&sp_entityid=https%3A%2F%2Fsourcesup.cru.fr%2Fshibboleth&email_address=support%40renater.fr
+sub req_generate_token {
+    my $self = shift;
+    &IdPAccountManager::Tools::do_log('info', "");
+    
+    unless ($self->{'param_in'}{'sp_entityid'}) {
+        push @{$self->{'param_out'}{'errors'}}, "missing_sp_entityid";
+	&IdPAccountManager::Tools::do_log('error', "Missing parameter sp_entityid");
+	return undef;
+    }
+
+    unless ($self->{'param_in'}{'email_address'}) {
+        push @{$self->{'param_out'}{'errors'}}, "email_address";
+	&IdPAccountManager::Tools::do_log('error', "Missing parameter email_address");
+	return undef;
+    }
+
+    my $authentication_token = new IdPAccountManager::AuthenticationToken();
+    unless (defined $authentication_token) {
+ 	push @{$self->{'param_out'}{'errors'}}, "internal";
+	&IdPAccountManager::Tools::do_log('error', "Failed to create authentication token");
+	return undef;
+    }
+    
+    unless ($authentication_token->set('email_address' => $self->{'param_in'}{'email_address'},
+                                       'sp_entityid' => $self->{'param_in'}{'sp_entityid'})) {
+ 	push @{$self->{'param_out'}{'errors'}}, "internal";
+	&IdPAccountManager::Tools::do_log('error', "Failed to update authentication token");
+	return undef;
+    }    
+    
+    unless ($authentication_token->save()) {
+ 	push @{$self->{'param_out'}{'errors'}}, "internal";
+	&IdPAccountManager::Tools::do_log('error', "Failed to save authentication token");
+	return undef;
+    }
+    
+    $self->{'param_out'}{'authentication_token'} = $authentication_token->get('token');
+    $self->{'param_out'}{'email_address'} = $self->{'param_in'}{'email_address'};
+    $self->{'param_out'}{'sp_entityid'} = $self->{'param_in'}{'sp_entityid'};
+    $self->{'param_out'}{'to'} = $self->{'param_in'}{'email_address'};    
+
+    ## Send the challenge email with the token
+    &IdPAccountManager::Tools::mail_notice('template' => 'templates/mail/send_authentication_token.tt2.eml', 
+         		 'data' => $self->{'param_out'});
+    
+    return 1;
+}
+
+
diff --git a/lib/IdPAccountManager/AuthenticationToken.pm b/lib/IdPAccountManager/AuthenticationToken.pm
index 3ebc1570d2e20461fdc24d429e44a41e6b668ba6..94ede6f36c78cd9fc34540e38ce4184e91553c02 100644
--- a/lib/IdPAccountManager/AuthenticationToken.pm
+++ b/lib/IdPAccountManager/AuthenticationToken.pm
@@ -92,8 +92,8 @@ sub print {
     my $self = shift;
     my $fd = shift || \*STDOUT;
     
-    printf $fd "AuthenticationToken ID=%s; token=%s; email_address=%s; creation_date=%s\n",
-            $self->get('id'), $self->get('token'), $self->get('email_address'),
+    printf $fd "AuthenticationToken ID=%s; token=%s; email_address=%s; sp_entityid=%s; creation_date=%s\n",
+            $self->get('id'), $self->get('token'), $self->get('email_address'), $self->get('sp_entityid'),
             &POSIX::strftime('%Y:%m:%d', localtime($self->get('creation_date')));
 
     return 1.
diff --git a/lib/IdPAccountManager/Tools.pm b/lib/IdPAccountManager/Tools.pm
index e0df349626c6ab14f28a7d5dc15da6f5c7894ff7..d00bfd7df087cd64aefeb372c2b22cd35d0af3b4 100644
--- a/lib/IdPAccountManager/Tools.pm
+++ b/lib/IdPAccountManager/Tools.pm
@@ -153,14 +153,10 @@ sub mail_notice {
   $mail_data->{'to'} = $notice_email;
   
   ## Protection to prevent notifications during test dev phases
-  ## Notify only adresses @renater.fr
+  ## Notify only admin_email
   if ($Conf::global{'no_mail_outside'}) {
-	foreach my $email (split /,/, $notice_email) {
-		unless ($email =~ /\@(cru|renater)\.fr$/) {
-			&do_log('error',"Notification to an external address skipped");
-			return undef;
-		}
-	}
+    &do_log('info',"no_mail_outside option set; notification for %s rerouted to admins ; ", $notice_email);
+    $notice_email = $Conf::global{'admin_email'};
   }
 
   &do_log('trace', '(template=%s, to=%s)', $in{'template'}, $mail_data->{'to'});
diff --git a/templates/mail/send_authentication_token.tt2.eml b/templates/mail/send_authentication_token.tt2.eml
new file mode 100644
index 0000000000000000000000000000000000000000..cfc11cd508ea1379a1633f4984e0e12970e76930
--- /dev/null
+++ b/templates/mail/send_authentication_token.tt2.eml
@@ -0,0 +1,13 @@
+From: [% conf.app_name %] <[% conf.notice_from %]>
+To: [% to %]
+Subject: [% conf.app_name %] - Test accounts request
+Content-type: text/plain; charset=UTF-8; format=flowed
+
+This is an email challenge automatically sent to you by [% conf.app_name %]. Somebody has requested creation of test accounts
+for the service provider with entityid [% sp_entityid %] declared in eduGAIN interfederation. You are listed as
+contact for this service provider in eduGAIN metadata.
+
+To complete test accounts activation you should copy and paste the validation token below in the [% conf.app_name %] web form.
+Validation token:  [% authentication_token %]
+
+
diff --git a/templates/web/content.tt2.html b/templates/web/content.tt2.html
index 7bf2612a16f9743a88c0896b68c7408e3c1bff85..5036c762897fbd0876eb9944764485266a9643c8 100644
--- a/templates/web/content.tt2.html
+++ b/templates/web/content.tt2.html
@@ -21,6 +21,13 @@
   An error occured
  [% END %]
  
+[% ELSIF action == 'generate_token' %]
+ [% TRY %]
+  [% PROCESS 'templates/web/generate_token.tt2.html' %]
+ [% CATCH %]
+  An error occured
+ [% END %]
+
 [% ELSE %]
 Error: unknown action
 
diff --git a/templates/web/generate_token.tt2.html b/templates/web/generate_token.tt2.html
new file mode 100644
index 0000000000000000000000000000000000000000..f2d8ae944ccd3e0b155d973ef4d2510fbe2fe905
--- /dev/null
+++ b/templates/web/generate_token.tt2.html
@@ -0,0 +1,17 @@
+<h3>Validate challenge</h3>
+
+<div>
+An email challenge including a validation token has been emailed to you at [% email_address %]. You need to copy and paste this token in the form below.</div>
+
+<fieldset>
+    <legend>Provide token</legend>
+   <label for="authentication_token">PLease provide the secret token here :</label>
+
+<input name="authentication_token" value="" id="authentication_token" type="text" class="required"/>
+
+<input type="hidden" name="sp_entityid" value="[% sp_entityid %]" id="sp_entityid"/>
+<input type="hidden" name="email_address" value="[% email_address %]" id="email_address"/>
+
+
+</fieldset>
+
diff --git a/templates/web/get_sp_list.tt2.html b/templates/web/get_sp_list.tt2.html
index 36be36fe29fc731a8e80e83bec4e15fb2fec6c04..1821ba8d2334fa467e59c06febbf299c6ca154a5 100644
--- a/templates/web/get_sp_list.tt2.html
+++ b/templates/web/get_sp_list.tt2.html
@@ -26,6 +26,19 @@ jQuery(document).ready(function($){
                 });
             }
 
+            // Trigger loading of the 'select_sp' with the selected SP entityid as parameter
+            // Result gets included in the next tab
+            if (currentIndex === 1 && newIndex === 2)
+            {
+                form.steps("remove", 2);
+                form.steps("insert", 2, {
+                    title: "Validate challenge",
+                    contentMode: "async",
+                    contentUrl: "https://dev-edugain.renater.fr/accountmanager?action=generate_token&style=nobanner&sp_entityid="+
+                        encodeURIComponent($('#sp_entityid').val())+"&email_address="+encodeURIComponent($('#email_address').val())
+                });
+            }
+
             // Allways allow previous action even if the current form is not valid!
             if (currentIndex > newIndex)
             {
diff --git a/templates/web/select_sp.tt2.html b/templates/web/select_sp.tt2.html
index 40488c3639996eb903537e5699f8f1303fa60de1..b28867fa125ecf921d134fd4de23398dd4e258cf 100644
--- a/templates/web/select_sp.tt2.html
+++ b/templates/web/select_sp.tt2.html
@@ -18,8 +18,11 @@ Before you can create test accounts at this Identity Provider, we need to ensure
 [% matches = contact.EmailAddress.match('^(mailto:)?(.*)$') %]
 [% SET email = matches.1%]
 
-<input name="email" value="[% email %]" id="[% email %]" type="radio"/>
-<label for="[% email %]">[% email %]</label>
+<input name="email_address" value="[% email %]" id="email_address" type="radio" class="required"/>
+<label for="email_address">[% email %]</label>
+
+<input type="hidden" name="sp_entityid" value="[% sp_metadata_as_hashref.entityid %]" id="sp_entityid"/>
+
 [% END %]
 
 [% ELSE %]