diff --git a/src/main/java/org/olat/admin/user/imp/ImportStep00.java b/src/main/java/org/olat/admin/user/imp/ImportStep00.java
index f68ac727d16fa4e20757388a44cffd35344b5c5e..ac4438260513bb634717da63c0953e5ec82e8158 100644
--- a/src/main/java/org/olat/admin/user/imp/ImportStep00.java
+++ b/src/main/java/org/olat/admin/user/imp/ImportStep00.java
@@ -58,6 +58,7 @@ import org.olat.core.util.i18n.I18nManager;
 import org.olat.core.util.i18n.I18nModule;
 import org.olat.registration.RegistrationManager;
 import org.olat.registration.TemporaryKey;
+import org.olat.shibboleth.ShibbolethModule;
 import org.olat.user.UserManager;
 import org.olat.user.propertyhandlers.UserPropertyHandler;
 
@@ -197,7 +198,10 @@ class ImportStep00 extends BasicStep {
 					if (parts.length > columnId) {
 						pwd = parts[columnId].trim();
 						if (StringHelper.containsNonWhitespace(pwd)) {
-							if (!UserManager.getInstance().syntaxCheckOlatPassword(pwd)) {
+							if(pwd.startsWith(UserImportController.SHIBBOLETH_MARKER)
+									&& ShibbolethModule.isEnableShibbolethLogins()) {
+								//something to check?
+							} else if (!UserManager.getInstance().syntaxCheckOlatPassword(pwd)) {
 								textAreaElement.setErrorKey("error.pwd", new String[] { String.valueOf(i + 1), pwd });
 								importDataError = true;
 								break;
@@ -241,7 +245,7 @@ class ImportStep00 extends BasicStep {
 					idents.add(uIdentity);
 					updateIdents.add(uIdentity);
 					
-					importDataError = updateUserProperties(uIdentity, parts, i, columnId, tempEmailsInUse, importedEmails, true);
+					importDataError = updateUserProperties(uIdentity, parts, i, columnId, tempEmailsInUse, importedEmails);
 					if(importDataError) break;
 				} else {
 					// no identity/user yet, create
@@ -260,7 +264,7 @@ class ImportStep00 extends BasicStep {
 					ud.setName(login);
 					ud.setPassword(pwd);
 					ud.setLanguage(lang);
-					importDataError = updateUserProperties(ud, parts, i, columnId, tempEmailsInUse, importedEmails, false);
+					importDataError = updateUserProperties(ud, parts, i, columnId, tempEmailsInUse, importedEmails);
 					if(importDataError) break;
 					
 					idents.add(ud);
@@ -290,7 +294,7 @@ class ImportStep00 extends BasicStep {
 		}
 		
 		private boolean updateUserProperties(Identity ud, String[] parts, int i, int columnId,
-				Set<String> tempEmailsInUse, List<String> importedEmails, boolean update) {
+				Set<String> tempEmailsInUse, List<String> importedEmails) {
 			
 			boolean importDataError = false;
 			for (int j = 0; j < userPropertyHandlers.size(); j++) {
diff --git a/src/main/java/org/olat/admin/user/imp/UserImportController.java b/src/main/java/org/olat/admin/user/imp/UserImportController.java
index 8e69ff2a751645f9999917dfab89bd63701e472c..bae0dfd4a2791e5b8163b2a1f517ed97c70049ca 100644
--- a/src/main/java/org/olat/admin/user/imp/UserImportController.java
+++ b/src/main/java/org/olat/admin/user/imp/UserImportController.java
@@ -30,6 +30,7 @@ import java.util.Collection;
 import java.util.HashSet;
 import java.util.List;
 import java.util.Set;
+import java.util.concurrent.atomic.AtomicInteger;
 
 import org.olat.basesecurity.AuthHelper;
 import org.olat.basesecurity.Authentication;
@@ -56,6 +57,8 @@ import org.olat.core.util.mail.MailPackage;
 import org.olat.group.BusinessGroupService;
 import org.olat.group.model.BusinessGroupMembershipChange;
 import org.olat.login.auth.OLATAuthManager;
+import org.olat.shibboleth.ShibbolethDispatcher;
+import org.olat.shibboleth.ShibbolethModule;
 import org.olat.user.UserManager;
 import org.olat.user.propertyhandlers.UserPropertyHandler;
 
@@ -71,6 +74,8 @@ import org.olat.user.propertyhandlers.UserPropertyHandler;
  */
 public class UserImportController extends BasicController {
 
+	public static final String SHIBBOLETH_MARKER = "SHIBBOLETH::";
+
 	private List<UserPropertyHandler> userPropertyHandlers;
 	private static final String usageIdentifyer = UserImportController.class.getCanonicalName();
 	private boolean canCreateOLATPassword;
@@ -106,6 +111,7 @@ public class UserImportController extends BasicController {
 	 * @see org.olat.core.gui.control.DefaultController#event(org.olat.core.gui.UserRequest,
 	 *      org.olat.core.gui.control.Controller, org.olat.core.gui.control.Event)
 	 */
+	@Override
 	public void event(UserRequest ureq, Controller source, Event event) {
 		if (source==importStepsController){
 			if (event == Event.CANCELLED_EVENT) {
@@ -113,13 +119,25 @@ public class UserImportController extends BasicController {
 				removeAsListenerAndDispose(importStepsController);
 			} else if (event == Event.CHANGED_EVENT || event == Event.DONE_EVENT) {
 				getWindowControl().pop();
+				StepsRunContext ctxt = importStepsController.getRunContext();
+				ImportReport report = (ImportReport)ctxt.get("report");
 				removeAsListenerAndDispose(importStepsController);
-				showInfo("import.success");
+				if(report.isHasErrors()) {
+					StringBuilder errorMsg = new StringBuilder();
+					errorMsg.append("<ul>");
+					for(String error:report.getErrors()) {
+						errorMsg.append("<li>").append(error).append("</li>");
+					}
+					errorMsg.append("</ul>");
+					showError("import.errors", errorMsg.toString());
+				} else {
+					showInfo("import.success");
+				}
 			}
 		}
 	}
 
-	private Identity doCreateAndPersistIdentity(TransientIdentity singleUser) {
+	private Identity doCreateAndPersistIdentity(TransientIdentity singleUser, ImportReport report) {
 		// Create new user and identity and put user to users group
 		String login = singleUser.getName(); //pos 0 is used for existing/non-existing user flag
 		String pwd = singleUser.getPassword();
@@ -148,24 +166,52 @@ public class UserImportController extends BasicController {
 		newUser.getPreferences().setLanguage(lang);
 		newUser.getPreferences().setInformSessionTimeout(true);
 		// Save everything in database
-		Identity ident = AuthHelper.createAndPersistIdentityAndUserWithUserGroup(login, pwd, newUser);
+		Identity ident;
+		if(pwd.startsWith(SHIBBOLETH_MARKER) && ShibbolethModule.isEnableShibbolethLogins()) {
+			String uniqueID = pwd.substring(SHIBBOLETH_MARKER.length());
+			ident = AuthHelper.createAndPersistIdentityAndUserWithUserGroup(login, ShibbolethDispatcher.PROVIDER_SHIB, uniqueID, newUser);
+			report.incrementCreatedUser();
+			report.incrementUpdatedShibboletAuthentication();
+		} else {
+			ident = AuthHelper.createAndPersistIdentityAndUserWithUserGroup(login, pwd, newUser);
+			report.incrementCreatedUser();
+		}
 		return ident;
 	}
 	
-	private Identity doUpdateIdentity(UpdateIdentity userToUpdate, Boolean updateUsers, Boolean updatePassword) {
+	private Identity doUpdateIdentity(UpdateIdentity userToUpdate, Boolean updateUsers, Boolean updatePassword, ImportReport report) {
 		Identity identity;
 		if(updateUsers != null && updateUsers.booleanValue()) {
 			identity = userToUpdate.getIdentity(true);
-			um.updateUserFromIdentity(identity);
+			if(um.updateUserFromIdentity(identity)) {
+				report.incrementUpdatedUser();
+			}
 		} else {
 			identity = userToUpdate.getIdentity();
 		}
 		
 		String password = userToUpdate.getPassword();
-		if(StringHelper.containsNonWhitespace(password) && updatePassword != null && updatePassword.booleanValue()) {
-			Authentication auth = securityManager.findAuthentication(identity, "OLAT");
-			if(auth != null) {
-				olatAuthManager.changePassword(getIdentity(), identity, password);
+		if(StringHelper.containsNonWhitespace(password)) {
+			if(password.startsWith(SHIBBOLETH_MARKER) && ShibbolethModule.isEnableShibbolethLogins()) {
+				String uniqueID = password.substring(SHIBBOLETH_MARKER.length());
+				Authentication auth = securityManager.findAuthentication(identity, ShibbolethDispatcher.PROVIDER_SHIB);
+				if(auth == null) {
+					securityManager.createAndPersistAuthentication(identity, ShibbolethDispatcher.PROVIDER_SHIB, uniqueID, null, null);
+					report.incrementUpdatedShibboletAuthentication();
+				} else if(!uniqueID.equals(auth.getAuthusername())) {
+					//remove the old authentication
+					securityManager.deleteAuthentication(auth);
+					DBFactory.getInstance().commit();
+					//create the new one with the new authusername
+					securityManager.createAndPersistAuthentication(identity, ShibbolethDispatcher.PROVIDER_SHIB, uniqueID, null, null);
+					report.incrementUpdatedShibboletAuthentication();
+				}
+			} else if(updatePassword != null && updatePassword.booleanValue()) {
+				Authentication auth = securityManager.findAuthentication(identity, "OLAT");
+				if(auth != null) {
+					olatAuthManager.changePassword(getIdentity(), identity, password);
+					report.incrementUpdatedPassword();
+				}
 			}
 		}
 		return userToUpdate.getIdentity();
@@ -190,14 +236,15 @@ public class UserImportController extends BasicController {
 		StepRunnerCallback finish = new StepRunnerCallback() {
 			public Step execute(UserRequest ureq1, WindowControl wControl1, StepsRunContext runContext) {
 				// all information to do now is within the runContext saved
-				boolean hasChanges = false;
+				ImportReport report = new ImportReport();
+				runContext.put("report", report);
 				try {
 					if (runContext.containsKey("validImport") && ((Boolean) runContext.get("validImport")).booleanValue()) {
 						// create new users and persist
 						@SuppressWarnings("unchecked")
 						List<TransientIdentity> newIdents = (List<TransientIdentity>) runContext.get("newIdents");
 						for (TransientIdentity newIdent:newIdents) {
-							doCreateAndPersistIdentity(newIdent);
+							doCreateAndPersistIdentity(newIdent, report);
 						}
 
 						Boolean updateUsers = (Boolean)runContext.get("updateUsers");
@@ -205,7 +252,7 @@ public class UserImportController extends BasicController {
 						@SuppressWarnings("unchecked")
 						List<UpdateIdentity> updateIdents = (List<UpdateIdentity>) runContext.get("updateIdents");
 						for (UpdateIdentity updateIdent:updateIdents) {
-							doUpdateIdentity(updateIdent, updateUsers, updatePasswords);
+							doUpdateIdentity(updateIdent, updateUsers, updatePasswords, report);
 						}
 
 						@SuppressWarnings("unchecked")
@@ -213,22 +260,22 @@ public class UserImportController extends BasicController {
 						@SuppressWarnings("unchecked")
 						List<Long> partGroups = (List<Long>) runContext.get("partGroups");
 
-						if (ownGroups.size() > 0 || partGroups.size() > 0){
+						if ((ownGroups != null && ownGroups.size() > 0) || (partGroups != null && partGroups.size() > 0)) {
 							@SuppressWarnings("unchecked")
 							List<Identity> allIdents = (List<Identity>) runContext.get("idents");
 							Boolean sendMailObj = (Boolean)runContext.get("sendMail");
 							boolean sendmail = sendMailObj == null ? true : sendMailObj.booleanValue();
 							processGroupAdditionForAllIdents(allIdents, ownGroups, partGroups, sendmail);
 						}
-						hasChanges = true;
+						report.setHasChanges(true);
 					}
 				} catch (Exception any) {
-					// return new ErrorStep
+					logError("", any);
+					report.addError("Unexpected error, see log files or call your system administrator");
 				}
 				// signal correct completion and tell if changes were made or not.
-				return hasChanges ? StepsMainRunController.DONE_MODIFIED : StepsMainRunController.DONE_UNCHANGED;
+				return report.isHasChanges() ? StepsMainRunController.DONE_MODIFIED : StepsMainRunController.DONE_UNCHANGED;
 			}
-
 		};
 
 		importStepsController = new StepsMainRunController(ureq, getWindowControl(), start, finish, null,
@@ -281,4 +328,73 @@ public class UserImportController extends BasicController {
 		businessGroupService.updateMemberships(getIdentity(), changes, mailing);
 		DBFactory.getInstance().commit();
 	}
+	
+	public static class ImportReport {
+		
+		private boolean hasChanges = false;
+		private boolean hasErrors = false;
+		
+		private AtomicInteger updatedUser = new AtomicInteger(0);
+		private AtomicInteger createdUser = new AtomicInteger(0);
+		private AtomicInteger updatedPassword = new AtomicInteger(0);
+		private AtomicInteger updatedShibboletAuthentication = new AtomicInteger(0);
+		
+		private List<String> errors = new ArrayList<>();
+
+		public boolean isHasChanges() {
+			return hasChanges;
+		}
+
+		public void setHasChanges(boolean hasChanges) {
+			this.hasChanges = hasChanges;
+		}
+
+		public boolean isHasErrors() {
+			return hasErrors;
+		}
+
+		public void setHasErrors(boolean hasErrors) {
+			this.hasErrors = hasErrors;
+		}
+
+		public List<String> getErrors() {
+			return errors;
+		}
+
+		public void addError(String error) {
+			errors.add(error);
+		}
+
+		public int getNumOfUpdatedUser() {
+			return updatedUser.get();
+		}
+
+		public void incrementUpdatedUser() {
+			updatedUser.incrementAndGet();
+		}
+
+		public int getCreatedUser() {
+			return createdUser.get();
+		}
+
+		public void incrementCreatedUser() {
+			createdUser.incrementAndGet();
+		}
+
+		public int getUpdatedPassword() {
+			return updatedPassword.get();
+		}
+
+		public void incrementUpdatedPassword() {
+			updatedPassword.incrementAndGet();
+		}
+
+		public int getUpdatedShibboletAuthentication() {
+			return updatedShibboletAuthentication.get();
+		}
+
+		public void incrementUpdatedShibboletAuthentication() {
+			updatedShibboletAuthentication.incrementAndGet();
+		}
+	}
 }
\ No newline at end of file
diff --git a/src/main/java/org/olat/admin/user/imp/_i18n/LocalStrings_de.properties b/src/main/java/org/olat/admin/user/imp/_i18n/LocalStrings_de.properties
index 603b13f1f0580b9d8cd92c3809319b94857202be..10076212197875f9d55cfa72dd78860dd6c476c9 100644
--- a/src/main/java/org/olat/admin/user/imp/_i18n/LocalStrings_de.properties
+++ b/src/main/java/org/olat/admin/user/imp/_i18n/LocalStrings_de.properties
@@ -26,6 +26,7 @@ import.description2=<i>Datenbeispiele\:</i> Sie sehen in einer Beispielabbildung
 import.description3=<i>Dateneingabe\:</i> Sie kopieren die Zeilen aus der Excel-Datei
 import.description4=<i>Vorschau der Benutzerdaten\:</i> Sie sehen, welche Benutzer bereits im System sind und welche neu angelegt werden.
 import.example=Beispielabbildung
+import.errors=Die Benutzer wurden teilweise angelegt. Es gab Fehler während den Import Prozess: {0}
 import.start=Benutzerimport starten
 import.success=Die neuen Benutzer wurden erfolgreich angelegt.
 import.user.existing.alt=Dieser Benutzer existiert bereits, er wird nicht neu angelegt
diff --git a/src/main/java/org/olat/basesecurity/AuthHelper.java b/src/main/java/org/olat/basesecurity/AuthHelper.java
index bb23b752f518fc8333c9526bd91926c693305460..e1d3a30bcf2fa8c93300ca2038c2a8a80f07a10f 100644
--- a/src/main/java/org/olat/basesecurity/AuthHelper.java
+++ b/src/main/java/org/olat/basesecurity/AuthHelper.java
@@ -356,7 +356,7 @@ public class AuthHelper {
 	 * @param newUser unpersisted user
 	 * @return Identity
 	 */
-	public static Identity createAndPersistIdentityAndUser(String loginName, String pwd, User newUser) {
+	private static Identity createAndPersistIdentityAndUser(String loginName, String pwd, User newUser) {
 		Identity ident = null;
 		if (pwd == null) {
 			// when no password is used the provider must be set to null to not generate
@@ -380,7 +380,7 @@ public class AuthHelper {
 	 * @param newUser unpersisted users
 	 * @return Identity
 	 */
-	public static Identity createAndPersistIdentityAndUserWithUserGroup(String loginName, String pwd, User newUser) {
+	public static Identity createAndPersistIdentityAndUserWithUserGroup(String loginName, String pwd,  User newUser) {
 		Identity ident = createAndPersistIdentityAndUser(loginName, pwd, newUser);
 		// Add user to system users group
 		BaseSecurity securityManager = BaseSecurityManager.getInstance();
@@ -388,6 +388,25 @@ public class AuthHelper {
 		securityManager.addIdentityToSecurityGroup(ident, olatuserGroup);
 		return ident;
 	}
+	
+	/**
+	 * Persists the given user, creates an identity for it and adds the user to
+	 * the users system group, create an authentication for an external provider
+	 * 
+	 * @param loginName
+	 * @param provider
+	 * @param authusername
+	 * @param newUser
+	 * @return
+	 */
+	public static Identity createAndPersistIdentityAndUserWithUserGroup(String loginName, String provider, String authusername, User newUser) {
+		BaseSecurity securityManager = BaseSecurityManager.getInstance();
+		Identity ident = securityManager.createAndPersistIdentityAndUser(loginName, newUser, provider, authusername, null);
+		// Add user to system users group
+		SecurityGroup olatuserGroup = securityManager.findSecurityGroupByName(Constants.GROUP_OLATUSERS);
+		securityManager.addIdentityToSecurityGroup(ident, olatuserGroup);
+		return ident;
+	}
 
 	/**
 	 * This is a convenience method to log out. IMPORTANT: This method initiates a
diff --git a/src/main/java/org/olat/basesecurity/BaseSecurityManager.java b/src/main/java/org/olat/basesecurity/BaseSecurityManager.java
index fcf34ff99fd9f4d787c8074b5cdccd163779c5c4..5fa92fbe2695b245983dfb69abb344cf35cb17bc 100644
--- a/src/main/java/org/olat/basesecurity/BaseSecurityManager.java
+++ b/src/main/java/org/olat/basesecurity/BaseSecurityManager.java
@@ -1454,7 +1454,7 @@ public class BaseSecurityManager extends BasicManager implements BaseSecurity {
 			public Authentication execute() {
 				Authentication auth = findAuthentication(ident, provider);
 				if(auth == null) {
-					if(algorithm != null) {
+					if(algorithm != null && credentials != null) {
 						String salt = algorithm.isSalted() ? Encoder.getSalt() : null;
 						String hash = Encoder.encrypt(credentials, salt, algorithm);
 						auth = new AuthenticationImpl(ident, provider, authUserName, hash, salt, algorithm.name());
diff --git a/src/main/java/org/olat/core/gui/control/controller/BasicController.java b/src/main/java/org/olat/core/gui/control/controller/BasicController.java
index f4154ea01e726e6923c5b333a7e0cf8800d2cdf1..b1537eb6f8b89b7c0021ae8718e30154d6633f27 100644
--- a/src/main/java/org/olat/core/gui/control/controller/BasicController.java
+++ b/src/main/java/org/olat/core/gui/control/controller/BasicController.java
@@ -447,6 +447,22 @@ public abstract class BasicController extends DefaultController {
 		getWindowControl().setInfo(
 				getTranslator().translate(key, new String[] { arg }));
 	}
+	
+	/**
+	 * convenience method to inform the user. this will call
+	 * 
+	 * <pre>
+	 * getWindowControl().setInfo(getTranslator().translate(key, args));
+	 * </pre>
+	 * 
+	 * @param key
+	 *            the key to use (in the LocalStrings_curlanguage file of your
+	 *            controller)
+	 * @param args
+	 */
+	protected void showInfo(String key, String[] args) {
+		getWindowControl().setInfo(getTranslator().translate(key, args));
+	}
 
 	/**
 	 * convenience method to inform the user with a warning message. this will
diff --git a/src/main/java/org/olat/course/editor/EditorMainController.java b/src/main/java/org/olat/course/editor/EditorMainController.java
index 4923075311ae2fbf0e05db18db27675c60140be5..44e40225df2fbb8276504fe0cf92d5489928393b 100644
--- a/src/main/java/org/olat/course/editor/EditorMainController.java
+++ b/src/main/java/org/olat/course/editor/EditorMainController.java
@@ -816,7 +816,7 @@ public class EditorMainController extends MainLayoutBasicController implements G
 			menuTree.setSelectedNodeId(rootNodeIdent);
 			updateViewForSelectedNodeId(ureq, rootNodeIdent);
 			if(event == Event.CHANGED_EVENT){					
-				showInfo("pbl.success", null);
+				showInfo("pbl.success");
 				// do logging
 				ThreadLocalUserActivityLogger.log(CourseLoggingAction.COURSE_EDITOR_PUBLISHED, getClass());
 			}//else Event.DONE -> nothing changed / else Event.CANCELLED -> cancelled wizard	
diff --git a/src/main/java/org/olat/ims/qti/editor/QTIEditorMainController.java b/src/main/java/org/olat/ims/qti/editor/QTIEditorMainController.java
index f776a230966b7477c911c6e87e1316ccc0c9cae3..45cac0c532dba3d1cc54cbaaa13683e710b71265 100644
--- a/src/main/java/org/olat/ims/qti/editor/QTIEditorMainController.java
+++ b/src/main/java/org/olat/ims/qti/editor/QTIEditorMainController.java
@@ -282,7 +282,7 @@ public class QTIEditorMainController extends MainLayoutBasicController implement
 			if (qtiPackage.getQTIDocument() == null) {
 				notEditable = true;				
 			} else if (qtiPackage.isResumed()) {
-				showInfo("info.resumed", null);
+				showInfo("info.resumed");
 			}
 			//
 			init(ureq); // initialize the gui