From 42a5389dbe8d271cad8f76129218fb77e634a4bb Mon Sep 17 00:00:00 2001
From: srosse <none@none>
Date: Wed, 14 Jan 2015 11:00:02 +0100
Subject: [PATCH] OO-1362: make the guest login, links for guests and
 invitation login configurable in the administration GUI

---
 .../org/olat/_spring/extensionContext.xml     |  39 +--
 .../admin/_i18n/LocalStrings_de.properties    |   2 +
 .../admin/_i18n/LocalStrings_en.properties    |   2 +
 .../user/UsermanagerUserSearchController.java |   4 +-
 .../basesecurity/BaseSecurityManager.java     |  11 +-
 .../_spring/baseSecurityContext.xml           |  40 +--
 .../webdav/manager/WebDAVAuthManager.java     |   8 +-
 .../org/olat/course/editor/PublishStep01.java |  10 +-
 .../dispatcher/AuthenticatedDispatcher.java   |   2 +-
 .../org/olat/dispatcher/RESTDispatcher.java   |   6 +-
 .../org/olat/ldap/_spring/ldapContext.xml     |   4 +-
 .../ldap/ui/LDAPAuthenticationController.java |  12 +-
 .../login/AfterLoginInterceptionManager.java  |  42 +--
 .../org/olat/login/LoginAdminController.java  |  78 ++++++
 .../login/LoginAuthprovidersController.java   |  16 +-
 src/main/java/org/olat/login/LoginModule.java | 263 +++++++++++-------
 .../login/OLATAuthenticationController.java   |  18 +-
 .../login/_i18n/LocalStrings_de.properties    |   9 +
 .../login/_i18n/LocalStrings_en.properties    |   8 +
 .../org/olat/login/_spring/loginContext.xml   | 152 ++++------
 .../org/olat/login/auth/OLATAuthManager.java  |  12 +-
 .../ui/structel/EPShareListController.java    |  25 +-
 .../_spring/registrationContext.xml           |   4 +-
 ...RepositoryEntryAccessColumnDescriptor.java |   3 +-
 .../repository/ui/RepositoryTableModel.java   |   6 +-
 .../repository/ui/author/AccessRenderer.java  |   3 +-
 .../AuthoringEntryPublishController.java      |  13 +-
 .../catalog/CatalogNodeManagerController.java |   9 +-
 .../repository/ui/catalog/_content/node.html  |  31 ++-
 .../RepositoryEntryDetailsController.java     |   7 +-
 .../shibboleth/ShibbolethMigrationForm.java   |   6 +-
 .../user/_spring/additionalUserContext.xml    |  37 ---
 .../org/olat/user/_spring/userContext.xml     |   1 -
 .../resources/serviceconfig/olat.properties   |   8 +-
 .../basesecurity/BaseSecurityManagerTest.java |   6 +-
 35 files changed, 526 insertions(+), 371 deletions(-)
 create mode 100644 src/main/java/org/olat/login/LoginAdminController.java
 delete mode 100644 src/main/java/org/olat/user/_spring/additionalUserContext.xml

diff --git a/src/main/java/org/olat/_spring/extensionContext.xml b/src/main/java/org/olat/_spring/extensionContext.xml
index 3597db88e10..738b84aedd5 100644
--- a/src/main/java/org/olat/_spring/extensionContext.xml
+++ b/src/main/java/org/olat/_spring/extensionContext.xml
@@ -34,6 +34,21 @@
 		</property>
 	</bean>
 	
+	<!-- The Module parent node -->
+	<bean class="org.olat.core.extensions.action.GenericActionExtension"  init-method="initExtensionPoints">
+		<property name="order" value="7300" />
+		<property name="navigationKey" value="loginandsecurity" />
+		<property name="nodeIdentifierIfParent" value="loginAndSecurityParent" />
+		<property name="translationPackage" value="org.olat.admin" />
+		<property name="i18nActionKey" value="menu.login" />
+		<property name="i18nDescriptionKey" value="menu.login.alt" />
+		<property name="extensionPoints">
+			<list>
+				<value>org.olat.admin.SystemAdminMainController</value>
+			</list>
+		</property>
+	</bean>
+	
 	<bean class="org.olat.core.extensions.action.GenericActionExtension"  init-method="initExtensionPoints">
 			<property name="order" value="7110" />
 			<property name="actionController">	
@@ -363,7 +378,7 @@
 	</bean>
 	<!-- Security admin. panel -->
 	<bean class="org.olat.core.extensions.action.GenericActionExtension" init-method="initExtensionPoints">
-		<property name="order" value="7205" />
+		<property name="order" value="8805" />
 		<property name="actionController">	
 			<bean class="org.olat.core.gui.control.creator.AutoCreator" scope="prototype">
 				<property name="className" value="org.olat.admin.security.SecurityAdminController"/>
@@ -373,7 +388,7 @@
 		<property name="i18nActionKey" value="admin.menu.title"/>
 		<property name="i18nDescriptionKey" value="admin.menu.title.alt"/>
 		<property name="translationPackage" value="org.olat.admin.security"/>
-		<property name="parentTreeNodeIdentifier" value="sysconfigParent" /> 
+		<property name="parentTreeNodeIdentifier" value="loginAndSecurityParent" /> 
 		<property name="extensionPoints">
 			<list>	
 				<value>org.olat.admin.SystemAdminMainController</value>		
@@ -540,21 +555,6 @@
 			<property name="parentTreeNodeIdentifier" value="sysAdminMenueNodeCustomizing" />
 		</bean>	
 		
-<!-- SYSADMIN maintenance parent node
-		<bean class="org.olat.core.extensions.action.GenericActionExtension" init-method="initExtensionPoints">
-			<property name="order" value="7300" />
-			<property name="nodeIdentifierIfParent" value="sysAdminMenueNodeMaintenance" />
-			<property name="navigationKey" value="sysadmin" />
-			<property name="i18nActionKey" value="menu.parent.maintenance"/>
-			<property name="i18nDescriptionKey" value="menu.parent.maintenance.alt"/>
-			<property name="translationPackage" value="org.olat.admin"/>
-			<property name="extensionPoints">
-				<list>	
-					<value>org.olat.admin.SystemAdminMainController</value>		
-				</list>
-			</property>
-		</bean>		-->
-		
 		<!--  statistics -->
 		<bean class="org.olat.core.extensions.action.GenericActionExtension" init-method="initExtensionPoints">
 			<property name="order" value="7301" />
@@ -573,8 +573,9 @@
 					<value>org.olat.admin.SystemAdminMainController</value>		
 				</list>
 			</property>
-		</bean>	
-	<!--  search admin ("volltextsuche")   -->
+		</bean>
+		
+		<!--  search admin ("volltextsuche")   -->
 		<bean class="org.olat.core.extensions.action.GenericActionExtension" init-method="initExtensionPoints">
 			<property name="order" value="7302" />
 			<property name="actionController">	
diff --git a/src/main/java/org/olat/admin/_i18n/LocalStrings_de.properties b/src/main/java/org/olat/admin/_i18n/LocalStrings_de.properties
index 9ffa66c73f6..24f8e1962a6 100644
--- a/src/main/java/org/olat/admin/_i18n/LocalStrings_de.properties
+++ b/src/main/java/org/olat/admin/_i18n/LocalStrings_de.properties
@@ -64,6 +64,8 @@ menu.layout=Darstellung
 menu.layout.alt=Darstellung systemweit \u00E4ndern
 menu.lock=Locks
 menu.lock.alt=Locks
+menu.login=Login
+menu.login.alt=Login und Sicherheits
 menu.logondeniedgroup=Gesperrte Benutzer
 menu.logondeniedgroup.alt=Benutzer, die sich nicht in OpenOLAT einloggen d\u00FCrfen
 menu.module=Modules
diff --git a/src/main/java/org/olat/admin/_i18n/LocalStrings_en.properties b/src/main/java/org/olat/admin/_i18n/LocalStrings_en.properties
index 77027a009b7..ad6ea7a56b4 100644
--- a/src/main/java/org/olat/admin/_i18n/LocalStrings_en.properties
+++ b/src/main/java/org/olat/admin/_i18n/LocalStrings_en.properties
@@ -64,6 +64,8 @@ menu.layout=Layout
 menu.layout.alt=Modify layout within the entire system
 menu.lock=Locks
 menu.lock.alt=Locks
+menu.login=Login
+menu.login.alt=Login and security
 menu.logondeniedgroup=Blocked users
 menu.logondeniedgroup.alt=Users not allowed to log in into OpenOLAT
 menu.menuaccess=Access and rights
diff --git a/src/main/java/org/olat/admin/user/UsermanagerUserSearchController.java b/src/main/java/org/olat/admin/user/UsermanagerUserSearchController.java
index df256f1118b..3d77275ea45 100644
--- a/src/main/java/org/olat/admin/user/UsermanagerUserSearchController.java
+++ b/src/main/java/org/olat/admin/user/UsermanagerUserSearchController.java
@@ -647,6 +647,8 @@ class UsermanagerUserSearchForm extends FormBasicController {
 	private Map <String,FormItem>items;
 	private final boolean isAdministrativeUser;
 	
+	@Autowired
+	private LoginModule loginModule;
 	@Autowired
 	private OAuthLoginModule oauthLoginModule;
 	
@@ -701,7 +703,7 @@ class UsermanagerUserSearchForm extends FormBasicController {
 		List <String>authKeyList = new ArrayList<String>();
 		List <String>authValueList = new ArrayList<String>();
 		
-		Collection<AuthenticationProvider> providers = LoginModule.getAuthenticationProviders();
+		Collection<AuthenticationProvider> providers = loginModule.getAuthenticationProviders();
 		for (AuthenticationProvider provider:providers) {
 			if (provider.isEnabled()) {
 				authKeyList.add(provider.getName());
diff --git a/src/main/java/org/olat/basesecurity/BaseSecurityManager.java b/src/main/java/org/olat/basesecurity/BaseSecurityManager.java
index 6c4615e9a96..06ac2db2567 100644
--- a/src/main/java/org/olat/basesecurity/BaseSecurityManager.java
+++ b/src/main/java/org/olat/basesecurity/BaseSecurityManager.java
@@ -84,6 +84,7 @@ import org.olat.user.UserManager;
  */
 public class BaseSecurityManager extends BasicManager implements BaseSecurity {
 	private DB dbInstance;
+	private LoginModule loginModule;
 	private OLATResourceManager orm;
 	private InvitationDAO invitationDao;
 	private String dbVendor = "";
@@ -106,6 +107,10 @@ public class BaseSecurityManager extends BasicManager implements BaseSecurity {
 		return INSTANCE;
 	}
 	
+	public void setLoginModule(LoginModule loginModule) {
+		this.loginModule = loginModule;
+	}
+	
 	/**
 	 * [used by spring]
 	 * @param orm
@@ -686,7 +691,7 @@ public class BaseSecurityManager extends BasicManager implements BaseSecurity {
 		IdentityImpl iimpl = new IdentityImpl(username, user);
 		dbInstance.getCurrentEntityManager().persist(iimpl);
 		if (provider != null) { 
-			createAndPersistAuthentication(iimpl, provider, authusername, credential, LoginModule.getDefaultHashAlgorithm());
+			createAndPersistAuthentication(iimpl, provider, authusername, credential, loginModule.getDefaultHashAlgorithm());
 		}
 		notifyNewIdentityCreated(iimpl);
 		return iimpl;
@@ -729,7 +734,7 @@ public class BaseSecurityManager extends BasicManager implements BaseSecurity {
 		iimpl.setExternalId(externalId);
 		dbInstance.getCurrentEntityManager().persist(iimpl);
 		if (provider != null) { 
-			createAndPersistAuthentication(iimpl, provider, authusername, credential, LoginModule.getDefaultHashAlgorithm());
+			createAndPersistAuthentication(iimpl, provider, authusername, credential, loginModule.getDefaultHashAlgorithm());
 		}
 		notifyNewIdentityCreated(iimpl);
 		return iimpl;
@@ -857,7 +862,7 @@ public class BaseSecurityManager extends BasicManager implements BaseSecurity {
 		  .append(SecurityGroupImpl.class.getName()).append("  as sgi ")
 		  .append(" where ngroup.groupName=:groupName and ngroup.securityGroup=sgi");
 
-		List<SecurityGroup> group = this.dbInstance.getCurrentEntityManager()
+		List<SecurityGroup> group = dbInstance.getCurrentEntityManager()
 				.createQuery(sb.toString(), SecurityGroup.class)
 				.setParameter("groupName", securityGroupName)
 				.setHint("org.hibernate.cacheable", Boolean.TRUE)
diff --git a/src/main/java/org/olat/basesecurity/_spring/baseSecurityContext.xml b/src/main/java/org/olat/basesecurity/_spring/baseSecurityContext.xml
index 073f0521714..7072c9c37fb 100644
--- a/src/main/java/org/olat/basesecurity/_spring/baseSecurityContext.xml
+++ b/src/main/java/org/olat/basesecurity/_spring/baseSecurityContext.xml
@@ -10,28 +10,28 @@
 
 	<context:component-scan base-package="org.olat.basesecurity.manager" />
 
-<!-- manager -->
-<bean id="baseSecurityManager" class="org.olat.basesecurity.BaseSecurityManager" init-method="init" 
-	depends-on="database, i18nModule, triggerI18nModuleInit">
-	<property name="resourceManager" ref="resourceManager"/>
-	<property name="dbInstance" ref="database"/>
-	<property name="invitationDao" ref="invitationDao" />
-	<property name="dbVendor" value="${db.vendor}" />
-</bean>
+	<!-- manager -->
+	<bean id="baseSecurityManager" class="org.olat.basesecurity.BaseSecurityManager" init-method="init" 
+		depends-on="database, i18nModule, triggerI18nModuleInit">
+		<property name="resourceManager" ref="resourceManager"/>
+		<property name="loginModule" ref="loginModule"/>
+		<property name="dbInstance" ref="database"/>
+		<property name="invitationDao" ref="invitationDao" />
+		<property name="dbVendor" value="${db.vendor}" />
+	</bean>
 
-<!-- module -->
-<bean id="baseSecurityModule" class="org.olat.basesecurity.BaseSecurityModule">
-	<constructor-arg type="java.lang.String" value="${default.auth.provider.identifier}" />
-	<property name="persistedProperties">
-	  <bean class="org.olat.core.configuration.PersistedProperties" scope="prototype" init-method="init" destroy-method="destroy">
-	    <constructor-arg index="0" ref="coordinatorManager"/>
-	    <constructor-arg index="1" ref="baseSecurityModule" />
-	  </bean>
-	</property>
-	
-</bean>
+	<!-- module -->
+	<bean id="baseSecurityModule" class="org.olat.basesecurity.BaseSecurityModule">
+		<constructor-arg type="java.lang.String" value="${default.auth.provider.identifier}" />
+		<property name="persistedProperties">
+		  <bean class="org.olat.core.configuration.PersistedProperties" scope="prototype" init-method="init" destroy-method="destroy">
+		    <constructor-arg index="0" ref="coordinatorManager"/>
+		    <constructor-arg index="1" ref="baseSecurityModule" />
+		  </bean>
+		</property>	
+	</bean>
                        
-       <bean  class="org.springframework.beans.factory.config.MethodInvokingFactoryBean">
+	<bean  class="org.springframework.beans.factory.config.MethodInvokingFactoryBean">
         <property name="targetObject" ref="baseSecurityModule" />
         <property name="targetMethod" value="init" />
         <property name="arguments">
diff --git a/src/main/java/org/olat/core/commons/services/webdav/manager/WebDAVAuthManager.java b/src/main/java/org/olat/core/commons/services/webdav/manager/WebDAVAuthManager.java
index 6a7fd75d551..aec769fa620 100644
--- a/src/main/java/org/olat/core/commons/services/webdav/manager/WebDAVAuthManager.java
+++ b/src/main/java/org/olat/core/commons/services/webdav/manager/WebDAVAuthManager.java
@@ -53,6 +53,8 @@ public class WebDAVAuthManager implements AuthenticationSPI {
 	
 	private static final OLog log = Tracing.createLoggerFor(WebDAVAuthManager.class);
 
+	@Autowired
+	private LoginModule loginModule;
 	@Autowired
 	private WebDAVModule webDAVModule;
 	@Autowired
@@ -108,7 +110,7 @@ public class WebDAVAuthManager implements AuthenticationSPI {
 		if (securityManager.checkCredentials(authentication, password))	{
 			Algorithm algorithm = Algorithm.find(authentication.getAlgorithm());
 			if(Algorithm.md5.equals(algorithm)) {
-				authentication = securityManager.updateCredentials(authentication, password, LoginModule.getDefaultHashAlgorithm());
+				authentication = securityManager.updateCredentials(authentication, password, loginModule.getDefaultHashAlgorithm());
 			}
 			return authentication.getIdentity();
 		}
@@ -144,10 +146,10 @@ public class WebDAVAuthManager implements AuthenticationSPI {
 			Authentication auth = securityManager.findAuthentication(identity, PROVIDER_WEBDAV);
 			if (auth == null) { // create new authentication for provider OLAT
 				Identity reloadedIdentity = securityManager.loadIdentityByKey(identity.getKey());
-				auth = securityManager.createAndPersistAuthentication(reloadedIdentity, PROVIDER_WEBDAV, identity.getName(), newPwd, LoginModule.getDefaultHashAlgorithm());
+				auth = securityManager.createAndPersistAuthentication(reloadedIdentity, PROVIDER_WEBDAV, identity.getName(), newPwd, loginModule.getDefaultHashAlgorithm());
 				log.audit(doer.getName() + " created new WebDAV authenticatin for identity: " + identity.getName());
 			} else {
-				auth = securityManager.updateCredentials(auth, newPwd, LoginModule.getDefaultHashAlgorithm());
+				auth = securityManager.updateCredentials(auth, newPwd, loginModule.getDefaultHashAlgorithm());
 				log.audit(doer.getName() + " set new WebDAV password for identity: " +identity.getName());
 			}
 		}
diff --git a/src/main/java/org/olat/course/editor/PublishStep01.java b/src/main/java/org/olat/course/editor/PublishStep01.java
index da7943c0e03..58c610b2c59 100644
--- a/src/main/java/org/olat/course/editor/PublishStep01.java
+++ b/src/main/java/org/olat/course/editor/PublishStep01.java
@@ -49,6 +49,7 @@ import org.olat.login.LoginModule;
 import org.olat.repository.RepositoryEntry;
 import org.olat.repository.RepositoryModule;
 import org.olat.repository.RepositoryService;
+import org.springframework.beans.factory.annotation.Autowired;
 
 /**
  * Description:<br>
@@ -104,6 +105,9 @@ class PublishStep01 extends BasicStep {
 
 		private SingleSelection accessSelbox;
 		private String selectedAccess;
+		
+		@Autowired
+		private LoginModule loginModule;
 
 		PublishStep01AccessForm(UserRequest ureq, WindowControl control, Form rootForm, StepsRunContext runContext) {
 			super(ureq, control, rootForm, runContext, LAYOUT_VERTICAL, null);
@@ -140,7 +144,7 @@ class PublishStep01 extends BasicStep {
 			keyList.add(Integer.toString(RepositoryEntry.ACC_OWNERS));
 			keyList.add(Integer.toString(RepositoryEntry.ACC_OWNERS_AUTHORS));
 			keyList.add(Integer.toString(RepositoryEntry.ACC_USERS));
-			if(LoginModule.isGuestLoginLinksEnabled()) {
+			if(loginModule.isGuestLoginLinksEnabled()) {
 				keyList.add(Integer.toString(RepositoryEntry.ACC_USERS_GUESTS));
 			}
 			keyList.add(RepositoryEntry.MEMBERS_ONLY);
@@ -150,7 +154,7 @@ class PublishStep01 extends BasicStep {
 			valueList.add(pt.translate("cif.access.owners"));
 			valueList.add(pt.translate("cif.access.owners_authors"));
 			valueList.add(pt.translate("cif.access.users"));
-			if(LoginModule.isGuestLoginLinksEnabled()) {
+			if(loginModule.isGuestLoginLinksEnabled()) {
 				valueList.add(pt.translate("cif.access.users_guests"));
 			}
 			valueList.add(pt.translate("cif.access.membersonly"));
@@ -159,7 +163,7 @@ class PublishStep01 extends BasicStep {
 			//use the addDropDownSingleselect method with null as label i18n - key, because there is no label to set. OLAT-3682
 			accessSelbox = uifactory.addDropdownSingleselect("accessBox",null, fic, keys, values, null);
 			accessSelbox.setElementCssClass("o_sel_course_publish_access");
-			if(!LoginModule.isGuestLoginLinksEnabled() && "4".equals(selectedAccess)) {//no guest but BARG
+			if(!loginModule.isGuestLoginLinksEnabled() && "4".equals(selectedAccess)) {//no guest but BARG
 				accessSelbox.select("3", true);//-> set BAR-
 			} else {
 				accessSelbox.select(selectedAccess, true);
diff --git a/src/main/java/org/olat/dispatcher/AuthenticatedDispatcher.java b/src/main/java/org/olat/dispatcher/AuthenticatedDispatcher.java
index 5b45747b558..06903edd213 100644
--- a/src/main/java/org/olat/dispatcher/AuthenticatedDispatcher.java
+++ b/src/main/java/org/olat/dispatcher/AuthenticatedDispatcher.java
@@ -127,7 +127,7 @@ public class AuthenticatedDispatcher implements Dispatcher {
 				usess.putEntryInNonClearedStore(AUTHDISPATCHER_ENTRYURL, allGet);
 			}
 			String guestAccess = ureq.getParameter(GUEST);
-			if (guestAccess == null || !LoginModule.isGuestLoginLinksEnabled()) {
+			if (guestAccess == null || !CoreSpringFactory.getImpl(LoginModule.class).isGuestLoginEnabled()) {
 				DispatcherModule.redirectToDefaultDispatcher(response);
 				return;
 			} else if (guestAccess.equals(TRUE)) {
diff --git a/src/main/java/org/olat/dispatcher/RESTDispatcher.java b/src/main/java/org/olat/dispatcher/RESTDispatcher.java
index 5790cbc71f4..953edab1196 100644
--- a/src/main/java/org/olat/dispatcher/RESTDispatcher.java
+++ b/src/main/java/org/olat/dispatcher/RESTDispatcher.java
@@ -226,10 +226,10 @@ public class RESTDispatcher implements Dispatcher {
 			}
 		} else {
 			//prepare for redirect
-			//fxdiff FXOLAT-113: business path in DMZ
+			LoginModule loginModule = CoreSpringFactory.getImpl(LoginModule.class);
 			setBusinessPathInUserSession(usess, businessPath, ureq.getParameter(WINDOW_SETTINGS));
 			String invitationAccess = ureq.getParameter(AuthenticatedDispatcher.INVITATION);
-			if (invitationAccess != null && LoginModule.isInvitationEnabled()) {
+			if (invitationAccess != null && loginModule.isInvitationEnabled()) {
 			// try to log in as anonymous
 				// use the language from the lang paramter if available, otherwhise use the system default locale
 				Locale guestLoc = getLang(ureq);
@@ -249,7 +249,7 @@ public class RESTDispatcher implements Dispatcher {
 				}
 			} else {
 				String guestAccess = ureq.getParameter(AuthenticatedDispatcher.GUEST);
-				if (guestAccess == null || !LoginModule.isGuestLoginLinksEnabled()) {
+				if (guestAccess == null || !loginModule.isGuestLoginLinksEnabled()) {
 					DispatcherModule.redirectToDefaultDispatcher(response);
 					return;
 				} else if (guestAccess.equals(AuthenticatedDispatcher.TRUE)) {
diff --git a/src/main/java/org/olat/ldap/_spring/ldapContext.xml b/src/main/java/org/olat/ldap/_spring/ldapContext.xml
index 6822bc11503..594fe53458b 100644
--- a/src/main/java/org/olat/ldap/_spring/ldapContext.xml
+++ b/src/main/java/org/olat/ldap/_spring/ldapContext.xml
@@ -163,7 +163,7 @@
 
 	<!-- LDAP admin. panel -->
 	<bean class="org.olat.core.extensions.action.GenericActionExtension" id="sysadmin.menupoint.syscfg.ldapcfg" init-method="initExtensionPoints">
-		<property name="order" value="7214" />
+		<property name="order" value="8820" />
 		<property name="enabled" value="${ldap.enable}" />
 		<property name="actionController">	
 			<bean class="org.olat.core.gui.control.creator.AutoCreator" scope="prototype">
@@ -179,6 +179,6 @@
 				<value>org.olat.admin.SystemAdminMainController</value>		
 			</list>
 		</property>
-		<property name="parentTreeNodeIdentifier" value="sysconfigParent" /> 
+		<property name="parentTreeNodeIdentifier" value="loginAndSecurityParent" /> 
 	</bean>
 </beans>
\ No newline at end of file
diff --git a/src/main/java/org/olat/ldap/ui/LDAPAuthenticationController.java b/src/main/java/org/olat/ldap/ui/LDAPAuthenticationController.java
index c6b8a11631e..03905c33e7e 100644
--- a/src/main/java/org/olat/ldap/ui/LDAPAuthenticationController.java
+++ b/src/main/java/org/olat/ldap/ui/LDAPAuthenticationController.java
@@ -78,6 +78,8 @@ public class LDAPAuthenticationController extends AuthenticationController imple
 	
 	private final OLATAuthManager olatAuthenticationSpi;
 	
+	@Autowired
+	private LoginModule loginModule;
 	@Autowired
 	private LDAPLoginModule ldapLoginModule;
 
@@ -142,9 +144,9 @@ public class LDAPAuthenticationController extends AuthenticationController imple
 			String login = loginForm.getLogin();
 			String pass = loginForm.getPass();
 
-			if (LoginModule.isLoginBlocked(login)) {
+			if (loginModule.isLoginBlocked(login)) {
 				// do not proceed when already blocked
-				showError("login.blocked", LoginModule.getAttackPreventionTimeoutMin().toString());
+				showError("login.blocked", loginModule.getAttackPreventionTimeoutMin().toString());
 				getLogger().audit("Login attempt on already blocked login for " + login + ". IP::" + ureq.getHttpReq().getRemoteAddr(), null);
 				return;
 			}
@@ -176,9 +178,9 @@ public class LDAPAuthenticationController extends AuthenticationController imple
 			}
 			// Still not found? register for hacking attempts
 			if (authenticatedIdentity == null) {
-				if (LoginModule.registerFailedLoginAttempt(login)) {
+				if (loginModule.registerFailedLoginAttempt(login)) {
 					logAudit("Too many failed login attempts for " + login + ". Login blocked. IP::" + ureq.getHttpReq().getRemoteAddr(), null);
-					showError("login.blocked", LoginModule.getAttackPreventionTimeoutMin().toString());
+					showError("login.blocked", loginModule.getAttackPreventionTimeoutMin().toString());
 					return;
 				} else {
 					showError("login.error", ldapError.get());
@@ -196,7 +198,7 @@ public class LDAPAuthenticationController extends AuthenticationController imple
 				}
 			}
 
-			LoginModule.clearFailedLoginAttempts(login);
+			loginModule.clearFailedLoginAttempts(login);
 
 			// Check if disclaimer has been accepted
 			if (RegistrationManager.getInstance().needsToConfirmDisclaimer(authenticatedIdentity)) {
diff --git a/src/main/java/org/olat/login/AfterLoginInterceptionManager.java b/src/main/java/org/olat/login/AfterLoginInterceptionManager.java
index 6b8b9f9b68d..9de93a45424 100644
--- a/src/main/java/org/olat/login/AfterLoginInterceptionManager.java
+++ b/src/main/java/org/olat/login/AfterLoginInterceptionManager.java
@@ -25,7 +25,9 @@ import java.util.Iterator;
 import java.util.List;
 import java.util.Map;
 
-import org.olat.core.manager.BasicManager;
+import org.olat.core.logging.OLog;
+import org.olat.core.logging.Tracing;
+import org.springframework.stereotype.Service;
 
 /**
  * Used to manage a list of all Controllers to be presented afterLogin.
@@ -35,31 +37,13 @@ import org.olat.core.manager.BasicManager;
  * 
  * @author Roman Haag, roman.haag@frentix.com, www.frentix.com
  */
-public class AfterLoginInterceptionManager extends BasicManager{
-	private static AfterLoginInterceptionManager INSTANCE;
+@Service("afterLoginInterceptionManager")
+public class AfterLoginInterceptionManager {
+	private static final OLog log = Tracing.createLoggerFor(AfterLoginInterceptionManager.class);
+	
 	private List<Map<String, Object>> afterLoginControllerList;
 
-	/**
-	 * 
-	 * @return
-	 */
-	public static AfterLoginInterceptionManager getInstance() {
-		return INSTANCE;
-	}
-
-	/**
-	 *  [used by spring]
-	 */
-	private AfterLoginInterceptionManager() {
-		INSTANCE = this;
-	}
-
-	
-	/**
-	 * 
-	 */
 	protected static List<Map<String,Object>> sortControllerListByOrder(List<Map<String,Object>> list2order){
-		
 	    int n = list2order.size();
 	    for (int pass=1; pass < n; pass++) {  // count how many times
 	        // This next loop becomes shorter and shorter
@@ -83,7 +67,6 @@ public class AfterLoginInterceptionManager extends BasicManager{
 		return list2order;
 	}
 	
-	
 	/**
 	 * @return Returns the afterLoginControllerList.
 	 */
@@ -114,14 +97,14 @@ public class AfterLoginInterceptionManager extends BasicManager{
 		if (afterLoginControllerList == null) {
 			afterLoginControllerList = new ArrayList<Map<String, Object>>();
 		}
-		logInfo("added one or more afterLoginControllers to the list.");
+		log.info("added one or more afterLoginControllers to the list.");
 		List<Map<String, Object>> ctrlList = aLConf.getAfterLoginControllerList();
 		for (Iterator<Map<String, Object>> iterator = ctrlList.iterator(); iterator.hasNext();) {
 			Map<String, Object> map = iterator.next();
-			if (map.containsKey("controller-instance")) logInfo("  controller-instance: " + map.get("controller-instance"));
-			if (map.containsKey("controller")) logInfo("  controller-key to instantiate: " + map.get("controller"));
-			if (map.containsKey("forceUser")) logInfo("  force User: " + map.get("forceUser"));
-			if (map.containsKey("redoTimeout")) logInfo("  redo-Timeout: " + map.get("redoTimeout"));
+			if (map.containsKey("controller-instance")) log.info("  controller-instance: " + map.get("controller-instance"));
+			if (map.containsKey("controller")) log.info("  controller-key to instantiate: " + map.get("controller"));
+			if (map.containsKey("forceUser")) log.info("  force User: " + map.get("forceUser"));
+			if (map.containsKey("redoTimeout")) log.info("  redo-Timeout: " + map.get("redoTimeout"));
 		}
 		afterLoginControllerList.addAll(aLConf.getAfterLoginControllerList());
 	}
@@ -133,5 +116,4 @@ public class AfterLoginInterceptionManager extends BasicManager{
 			return false;
 		}
 	}
-
 }
diff --git a/src/main/java/org/olat/login/LoginAdminController.java b/src/main/java/org/olat/login/LoginAdminController.java
new file mode 100644
index 00000000000..84fcaa83a50
--- /dev/null
+++ b/src/main/java/org/olat/login/LoginAdminController.java
@@ -0,0 +1,78 @@
+package org.olat.login;
+
+import org.olat.core.gui.UserRequest;
+import org.olat.core.gui.components.form.flexible.FormItem;
+import org.olat.core.gui.components.form.flexible.FormItemContainer;
+import org.olat.core.gui.components.form.flexible.elements.MultipleSelectionElement;
+import org.olat.core.gui.components.form.flexible.impl.FormBasicController;
+import org.olat.core.gui.components.form.flexible.impl.FormEvent;
+import org.olat.core.gui.control.Controller;
+import org.olat.core.gui.control.WindowControl;
+import org.springframework.beans.factory.annotation.Autowired;
+
+/**
+ * 
+ * Initial date: 14.01.2015<br>
+ * @author srosse, stephane.rosse@frentix.com, http://www.frentix.com
+ *
+ */
+public class LoginAdminController extends FormBasicController {
+	
+	private MultipleSelectionElement guestLoginEl, guestLinkEl, invitationLoginEl;
+	
+	private static final String[] keys = new String[]{ "on" };
+	private final String[] values;
+	
+	@Autowired
+	private LoginModule loginModule;
+	
+	public LoginAdminController(UserRequest ureq, WindowControl wControl) {
+		super(ureq, wControl);
+		
+		values = new String[]{ translate("enabled") };
+		
+		initForm(ureq);
+	}
+
+	@Override
+	protected void initForm(FormItemContainer formLayout, Controller listener, UserRequest ureq) {
+		setFormTitle("login.admin.title");
+		
+		guestLoginEl = uifactory.addCheckboxesHorizontal("guest.login", "guest.login", formLayout, keys, values);
+		guestLoginEl.select(keys[0], loginModule.isGuestLoginEnabled());
+		guestLoginEl.addActionListener(FormEvent.ONCHANGE);
+		
+		guestLinkEl = uifactory.addCheckboxesHorizontal("guest.login.links", "guest.login.links", formLayout, keys, values);
+		guestLinkEl.select(keys[0], loginModule.isGuestLoginLinksEnabled());
+		guestLinkEl.addActionListener(FormEvent.ONCHANGE);
+		
+		invitationLoginEl = uifactory.addCheckboxesHorizontal("invitation.login", "invitation.login", formLayout, keys, values);
+		invitationLoginEl.select(keys[0], loginModule.isInvitationEnabled());
+		invitationLoginEl.addActionListener(FormEvent.ONCHANGE);
+	}
+	
+	@Override
+	protected void doDispose() {
+		//
+	}
+
+	@Override
+	protected void formInnerEvent(UserRequest ureq, FormItem source, FormEvent event) {
+		if(guestLoginEl == source) {
+			boolean enabled = guestLoginEl.isAtLeastSelected(1);
+			loginModule.setGuestLoginEnabled(enabled);
+		} else if(guestLinkEl == source) {
+			boolean enabled = guestLinkEl.isAtLeastSelected(1);
+			loginModule.setGuestLoginLinksEnabled(enabled);
+		} else if(invitationLoginEl == source) {
+			boolean enabled = invitationLoginEl.isAtLeastSelected(1);
+			loginModule.setInvitationEnabled(enabled);
+		}
+		super.formInnerEvent(ureq, source, event);
+	}
+
+	@Override
+	protected void formOK(UserRequest ureq) {
+		//
+	}
+}
\ No newline at end of file
diff --git a/src/main/java/org/olat/login/LoginAuthprovidersController.java b/src/main/java/org/olat/login/LoginAuthprovidersController.java
index 7c61a9d669c..31badd48ef9 100644
--- a/src/main/java/org/olat/login/LoginAuthprovidersController.java
+++ b/src/main/java/org/olat/login/LoginAuthprovidersController.java
@@ -61,6 +61,7 @@ import org.olat.core.util.i18n.I18nManager;
 import org.olat.core.util.i18n.I18nModule;
 import org.olat.login.auth.AuthenticationEvent;
 import org.olat.login.auth.AuthenticationProvider;
+import org.springframework.beans.factory.annotation.Autowired;
 
 /**
  * Description:<br>
@@ -81,6 +82,9 @@ public class LoginAuthprovidersController extends MainLayoutBasicController impl
 	private Link anoLink;
 	private StackedPanel dmzPanel;
 	
+	@Autowired
+	private LoginModule loginModule;
+	
 	public LoginAuthprovidersController(UserRequest ureq, WindowControl wControl) {
 		// Use fallback translator from full webapp package to translate accessibility stuff
 		super(ureq, wControl, Util.createPackageTranslator(BaseFullWebappController.class, ureq.getLocale()));
@@ -114,7 +118,7 @@ public class LoginAuthprovidersController extends MainLayoutBasicController impl
 			showAboutPage();
 		} else if ("registration".equals(type)) {
 			// make sure the OLAT authentication controller is activated as only this one can handle registration requests
-			AuthenticationProvider OLATProvider = LoginModule.getAuthenticationProvider(BaseSecurityModule.getDefaultAuthProviderIdentifier());
+			AuthenticationProvider OLATProvider = loginModule.getAuthenticationProvider(BaseSecurityModule.getDefaultAuthProviderIdentifier());
 			if (OLATProvider.isEnabled()) {
 				initLoginContent(ureq, BaseSecurityModule.getDefaultAuthProviderIdentifier());
 				if(authController instanceof Activateable2) {
@@ -137,8 +141,8 @@ public class LoginAuthprovidersController extends MainLayoutBasicController impl
 		contentBorn.contextPut("browserWarningOn", bwo ? Boolean.TRUE : Boolean.FALSE);
 		
 		// prepare login
-		if (provider == null)	provider = LoginModule.getDefaultProviderName();
-		AuthenticationProvider authProvider = LoginModule.getAuthenticationProvider(provider);
+		if (provider == null)	provider = loginModule.getDefaultProviderName();
+		AuthenticationProvider authProvider = loginModule.getAuthenticationProvider(provider);
 		if (authProvider == null)
 			throw new AssertException("Invalid authentication provider: " + provider);
 		
@@ -156,7 +160,7 @@ public class LoginAuthprovidersController extends MainLayoutBasicController impl
 		listenTo(authController);
 		contentBorn.put("loginComp", authController.getInitialComponent());
 		contentBorn.contextPut("currentProvider", authProvider.getName());		
-		Collection<AuthenticationProvider> providers = LoginModule.getAuthenticationProviders();
+		Collection<AuthenticationProvider> providers = loginModule.getAuthenticationProviders();
 		List<AuthenticationProvider> providerSet = new ArrayList<AuthenticationProvider>(providers.size());
 		int count = 0;
 		for (AuthenticationProvider prov : providers) {
@@ -204,7 +208,7 @@ public class LoginAuthprovidersController extends MainLayoutBasicController impl
 		}
 
 		// guest link
-		if (LoginModule.isGuestLoginLinksEnabled()) {
+		if (loginModule.isGuestLoginEnabled()) {
 			anoLink = LinkFactory.createButton("menu.guest", contentBorn, this);
 			anoLink.setIconLeftCSS("o_icon o_icon-2x o_icon_provider_guest");
 			anoLink.setTitle("menu.guest.alt");
@@ -229,7 +233,7 @@ public class LoginAuthprovidersController extends MainLayoutBasicController impl
 	@Override
 	protected void event(UserRequest ureq, Component source, Event event) {
 		 if (source == anoLink) {
-			if (LoginModule.isGuestLoginLinksEnabled()) {				
+			if (loginModule.isGuestLoginEnabled()) {				
 				int loginStatus = AuthHelper.doAnonymousLogin(ureq, ureq.getLocale());
 				if (loginStatus == AuthHelper.LOGIN_OK) {
 					return;
diff --git a/src/main/java/org/olat/login/LoginModule.java b/src/main/java/org/olat/login/LoginModule.java
index 65b794d1290..6ccea99d487 100644
--- a/src/main/java/org/olat/login/LoginModule.java
+++ b/src/main/java/org/olat/login/LoginModule.java
@@ -25,17 +25,23 @@
 
 package org.olat.login;
 
+import java.util.ArrayList;
 import java.util.Collection;
 import java.util.Iterator;
-import java.util.Map;
+import java.util.List;
 
-import org.olat.core.configuration.AbstractOLATModule;
-import org.olat.core.configuration.PersistedProperties;
+import org.olat.core.configuration.AbstractSpringModule;
+import org.olat.core.logging.OLog;
 import org.olat.core.logging.StartupException;
+import org.olat.core.logging.Tracing;
 import org.olat.core.util.Encoder;
+import org.olat.core.util.StringHelper;
 import org.olat.core.util.cache.CacheWrapper;
 import org.olat.core.util.coordinate.CoordinatorManager;
 import org.olat.login.auth.AuthenticationProvider;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.stereotype.Service;
 
 /**
  * Initial Date:  04.08.2004
@@ -43,89 +49,137 @@ import org.olat.login.auth.AuthenticationProvider;
  * @author Mike Stock
  * @author guido
  */
-public class LoginModule extends AbstractOLATModule {
+@Service("loginModule")
+public class LoginModule extends AbstractSpringModule {
+	
+	private static final OLog log = Tracing.createLoggerFor(LoginModule.class);
+
+	@Autowired
+	private List<AuthenticationProvider> authenticationProviders;
+	
+	@Value("${login.attackPreventionEnabled:true}")
+	private boolean attackPreventionEnabled;
+	@Value("${login.AttackPreventionMaxattempts:5}")
+	private int attackPreventionMaxAttempts;
+	@Value("${login.AttackPreventionTimeoutmin:5}")
+	private int attackPreventionTimeout;
 
-	private static final String CONF_ATTACK_ENABLED = "AttackPreventionEnabled";
-	private static final String CONF_ATTACK_MAXATTEMPTS = "AttackPreventionMaxattempts";
-	private static final String CONF_ATTACK_TIMEOUTMIN = "AttackPreventionTimeoutmin";
-	private static final String CONF_GUESTLINKS_ENABLED = "GuestLoginLinksEnabled";
-	private static final String CONF_INVITATION_ENABLED = "InvitationEnabled";
-	private static final String ALLOW_LOGIN_USING_EMAIL = "allowLoginUsingEmail";
+	@Value("${invitation.login:enabled}")
+	private String invitationEnabled;
+	@Value("${guest.login:enabled}")
+	private String guestLoginEnabled;
+	@Value("${guest.login.links:enabled}")
+	private String guestLoginLinksEnabled;
+	
+	private String defaultProviderName = "OLAT";
+	@Value("${login.using.username.or.email.enabled:true}")
+	private boolean allowLoginUsingEmail;
 
-	private static Map<String, AuthenticationProvider> authenticationProviders;
-	private static boolean attackPreventionEnabled;
-	private static int attackPreventionMaxAttempts;
-	private static int attackPreventionTimeout;
-	private static boolean guestLoginLinksEnabled;
-	private static CacheWrapper<String,Integer> failedLoginCache;
-	private static String defaultProviderName;
-	private static boolean allowLoginUsingEmail;
 	private CoordinatorManager coordinatorManager;
-	private static boolean invitationEnabled ;
+	private CacheWrapper<String,Integer> failedLoginCache;
+
+	@Autowired
+	public LoginModule(CoordinatorManager coordinatorManager) {
+		super(coordinatorManager);
+		this.coordinatorManager = coordinatorManager;
+	}
 	
-	/**
-	 * [used by spring]
-	 */
-	private LoginModule() {
-		//
+	@Override
+	public void init() {
+		// configure timed cache default params: refresh 1 minute, timeout according to configuration
+		failedLoginCache = coordinatorManager.getCoordinator().getCacher().getCache(LoginModule.class.getSimpleName(), "blockafterfailedattempts");
+				
+		updateProperties();
+		
+		boolean defaultProviderFound = false;
+		for (Iterator<AuthenticationProvider> iterator = authenticationProviders.iterator(); iterator.hasNext();) {
+			AuthenticationProvider provider = iterator.next();
+			if (provider.isDefault()) {
+				defaultProviderFound = true;
+				defaultProviderName = provider.getName();
+				log.info("Using default authentication provider '" + defaultProviderName + "'.");
+			}
+		}
+		
+		if (!defaultProviderFound) {
+			throw new StartupException("Defined DefaultAuthProvider::" + defaultProviderName + " not existent or not enabled. Please fix.");
+		}
+	}
+
+	@Override
+	protected void initFromChangedProperties() {
+		updateProperties();
 	}
 	
 	@Override
 	protected void initDefaultProperties() {
-		attackPreventionEnabled = getBooleanConfigParameter(CONF_ATTACK_ENABLED, true);
+		super.initDefaultProperties();
 		if (attackPreventionEnabled) {
-			logInfo("Attack prevention enabled. Max number of attempts: " + attackPreventionMaxAttempts + ", timeout: " + attackPreventionTimeout + " minutes.");
+			log.info("Attack prevention enabled. Max number of attempts: " + attackPreventionMaxAttempts + ", timeout: " + attackPreventionTimeout + " minutes.");
 		} else {
-			logInfo("Attack prevention is disabled.");
+			log.info("Attack prevention is disabled.");
 		}
-		attackPreventionMaxAttempts = getIntConfigParameter(CONF_ATTACK_MAXATTEMPTS, 5);
-		attackPreventionTimeout = getIntConfigParameter(CONF_ATTACK_TIMEOUTMIN, 5);
 		
-		guestLoginLinksEnabled = getBooleanConfigParameter(CONF_GUESTLINKS_ENABLED, true);
-		if (guestLoginLinksEnabled) {
-			logInfo("Guest login links on login page enabled");
-		} else {
-			guestLoginLinksEnabled = false;
-			logInfo("Guest login links on login page disabled or not properly configured. ");
+		//compatibility with older settings
+		if("true".equals(guestLoginEnabled)) {
+			guestLoginEnabled = "enabled";
+		} else if("false".equals(guestLoginEnabled)) {
+			guestLoginEnabled = "disabled";
 		}
-		invitationEnabled = getBooleanConfigParameter(CONF_INVITATION_ENABLED, true);
-		if (invitationEnabled) {
-			logInfo("Invitation login enabled");
-		} else {
-			logInfo("Invitation login disabled");
-		}
-		
 		
-		allowLoginUsingEmail = getBooleanConfigParameter(ALLOW_LOGIN_USING_EMAIL, true);
+		if("true".equals(guestLoginLinksEnabled)) {
+			guestLoginLinksEnabled = "enabled";
+		} else if("false".equals(guestLoginLinksEnabled)) {
+			guestLoginLinksEnabled = "disabled";
+		}
 		
+		if("true".equals(invitationEnabled)) {
+			invitationEnabled = "enabled";
+		} else if("false".equals(guestLoginLinksEnabled)) {
+			invitationEnabled = "disabled";
+		}
 		
+		if (isGuestLoginEnabled()) {
+			log.info("Guest login on login page enabled");
+		} else {
+			log.info("Guest login on login page disabled or not properly configured. ");
+		}
 		
+		if (isInvitationEnabled()) {
+			log.info("Invitation login enabled");
+		} else {
+			log.info("Invitation login disabled");
+		}
 	}
 	
-	/**
-	 * [used by spring]
-	 * @param coordinatorManager
-	 */
-	public void setCoordinator(CoordinatorManager coordinatorManager) {
-		this.coordinatorManager = coordinatorManager;
-	}
-	
-	/**
-	 * [used by spring]
-	 * @param authProviders
-	 */
-	public void setAuthenticaionProviders(Map<String, AuthenticationProvider> authProviders) {
-		LoginModule.authenticationProviders = authProviders;
+	private void updateProperties() {
+		//set properties
+		String invitation = getStringPropertyValue("invitation.login", true);
+		if(StringHelper.containsNonWhitespace(invitation)) {
+			invitationEnabled = invitation;
+		}
+		String guestLogin = getStringPropertyValue("guest.login", true);
+		if(StringHelper.containsNonWhitespace(guestLogin)) {
+			guestLoginEnabled = guestLogin;
+		}
+		String guestLoginLinks = getStringPropertyValue("guest.login.links", true);
+		if(StringHelper.containsNonWhitespace(guestLoginLinks)) {
+			guestLoginLinksEnabled = guestLoginLinks;
+		}
+		String usernameOrEmailLogin = getStringPropertyValue("login.using.username.or.email.enabled", true);
+		if(StringHelper.containsNonWhitespace(usernameOrEmailLogin)) {
+			allowLoginUsingEmail = "true".equals(usernameOrEmailLogin);
+		}
 	}
 
 	/**
 	 * @return The configured default login provider.
 	 */
-	public static String getDefaultProviderName() {
+	public String getDefaultProviderName() {
 		return defaultProviderName;
 	}
 	
-	public static Encoder.Algorithm getDefaultHashAlgorithm() {
+	public Encoder.Algorithm getDefaultHashAlgorithm() {
 		return Encoder.Algorithm.sha512;
 	}
 	
@@ -133,15 +187,21 @@ public class LoginModule extends AbstractOLATModule {
 	 * @param provider
 	 * @return AuthenticationProvider implementation.
 	 */
-	public static AuthenticationProvider getAuthenticationProvider(String provider) {
-		return authenticationProviders.get(provider);
+	public AuthenticationProvider getAuthenticationProvider(String provider) {
+		AuthenticationProvider authenticationProvider = null;
+		for(AuthenticationProvider authProvider:authenticationProviders) {
+			if(authProvider.getName().equals(provider)) {
+				authenticationProvider = authProvider;
+			}
+		}
+		return authenticationProvider;
 	}
 	
 	/**
 	 * @return Collection of available AuthenticationProviders
 	 */
-	public static Collection<AuthenticationProvider> getAuthenticationProviders() {
-		return authenticationProviders.values();
+	public Collection<AuthenticationProvider> getAuthenticationProviders() {
+		return new ArrayList<>(authenticationProviders);
 	}
 	
 	/**
@@ -150,7 +210,7 @@ public class LoginModule extends AbstractOLATModule {
 	 * @param login
 	 * @return True if further logins will be prevented (i.e. max attempts reached).
 	 */
-	public static final boolean registerFailedLoginAttempt(String login) {
+	public final boolean registerFailedLoginAttempt(String login) {
 		if (!attackPreventionEnabled) return false;
 		Integer numAttempts = failedLoginCache.get(login);
 		
@@ -168,9 +228,10 @@ public class LoginModule extends AbstractOLATModule {
 	 * Clear all failed login attempts for a given login.
 	 * @param login
 	 */
-	public static final void clearFailedLoginAttempts(String login) {
-		if (!attackPreventionEnabled) return;
-		failedLoginCache.remove(login);
+	public final void clearFailedLoginAttempts(String login) {
+		if (attackPreventionEnabled) {
+			failedLoginCache.remove(login);
+		}
 	}
 	
 	/**
@@ -178,7 +239,7 @@ public class LoginModule extends AbstractOLATModule {
 	 * @param login
 	 * @return True if login is blocked by attack prevention mechanism
 	 */
-	public static final boolean isLoginBlocked(String login) {
+	public final boolean isLoginBlocked(String login) {
 		if (!attackPreventionEnabled) return false;
 		Integer numAttempts = failedLoginCache.get(login);
 		
@@ -187,58 +248,52 @@ public class LoginModule extends AbstractOLATModule {
 	}
 	
 	/**
-	 * @return True if guest login links must be shown on login screen, false
+	 * @return True if guest login must be shown on login screen, false
 	 *         otherwise
 	 */
-	public static final boolean isGuestLoginLinksEnabled() {
-		return guestLoginLinksEnabled;
+	public boolean isGuestLoginEnabled() {
+		return "enabled".equals(guestLoginEnabled);
+	}
+	
+	public void setGuestLoginEnabled(boolean enabled) {
+		guestLoginEnabled = enabled ? "enabled" : "disabled";
+		setStringProperty("guest.login", guestLoginEnabled, true);
+	}
+	
+	public boolean isGuestLoginLinksEnabled() {
+		return "enabled".equalsIgnoreCase(guestLoginLinksEnabled);
 	}
 	
-	public static final boolean isInvitationEnabled() {
-		return invitationEnabled;
+	public void setGuestLoginLinksEnabled(boolean enabled) {
+		guestLoginLinksEnabled = enabled ? "enabled" : "disabled";
+		setStringProperty("guest.login.links", guestLoginLinksEnabled, true);
+	}
+	
+	public boolean isInvitationEnabled() {
+		return "enabled".equals(invitationEnabled);
+	}
+	
+	public void setInvitationEnabled(boolean enabled) {
+		invitationEnabled = enabled ? "enabled" : "disabled";
+		setStringProperty("invitation.login", invitationEnabled, true);
 	}
 	
 	/**
 	 * @return Number of minutes a login gets blocked after too many attempts.
 	 */
-	public static Integer getAttackPreventionTimeoutMin() {
+	public Integer getAttackPreventionTimeoutMin() {
 		return new Integer(attackPreventionTimeout);
 	}
 	
 	/**
 	 * @return True if login with email is allowed (set in olat.properties)
 	 */
-	public static boolean allowLoginUsingEmail() {
+	public boolean isAllowLoginUsingEmail() {
 		return allowLoginUsingEmail;
 	}
-
-	@Override
-	public void init() {
-		boolean defaultProviderFound = false;
-		for (Iterator<AuthenticationProvider> iterator = authenticationProviders.values().iterator(); iterator.hasNext();) {
-			AuthenticationProvider provider = iterator.next();
-			if (provider.isDefault()) {
-				defaultProviderFound = true;
-				defaultProviderName = provider.getName();
-				logInfo("Using default authentication provider '" + defaultProviderName + "'.");
-			}
-		}
-		
-		if (!defaultProviderFound) {
-			throw new StartupException("Defined DefaultAuthProvider::" + defaultProviderName + " not existent or not enabled. Please fix.");
-		}
-		
-		// configure timed cache default params: refresh 1 minute, timeout according to configuration
-		failedLoginCache = coordinatorManager.getCoordinator().getCacher().getCache(LoginModule.class.getSimpleName(), "blockafterfailedattempts");
-	}
-
-	@Override
-	protected void initFromChangedProperties() {
-		//
-	}
-
-	@Override
-	public void setPersistedProperties(PersistedProperties persistedProperties) {
-		this.moduleConfigProperties = persistedProperties;
+	
+	public void setAllowLoginUsingEmail(boolean allow) {
+		allowLoginUsingEmail = allow;
+		setStringProperty("login.using.username.or.email.enabled", Boolean.toString(allow), true);
 	}
 }
diff --git a/src/main/java/org/olat/login/OLATAuthenticationController.java b/src/main/java/org/olat/login/OLATAuthenticationController.java
index e835bb3af26..de1d49cd385 100644
--- a/src/main/java/org/olat/login/OLATAuthenticationController.java
+++ b/src/main/java/org/olat/login/OLATAuthenticationController.java
@@ -57,6 +57,7 @@ import org.olat.registration.RegistrationController;
 import org.olat.registration.RegistrationManager;
 import org.olat.registration.RegistrationModule;
 import org.olat.user.UserModule;
+import org.springframework.beans.factory.annotation.Autowired;
 
 /**
  * Initial Date:  04.08.2004
@@ -78,7 +79,10 @@ public class OLATAuthenticationController extends AuthenticationController imple
 	private Link pwLink;
 	private Link registerLink;
 	
-	private final OLATAuthManager olatAuthenticationSpi;
+	@Autowired
+	private LoginModule loginModule;
+	@Autowired
+	private OLATAuthManager olatAuthenticationSpi;
 	
 	/**
 	 * @see org.olat.login.auth.AuthenticationController#init(org.olat.core.gui.UserRequest, org.olat.core.gui.control.WindowControl)
@@ -86,8 +90,6 @@ public class OLATAuthenticationController extends AuthenticationController imple
 	public OLATAuthenticationController(UserRequest ureq, WindowControl winControl) {
 		// use fallback translator to registration module
 		super(ureq, winControl, Util.createPackageTranslator(RegistrationManager.class, ureq.getLocale()));
-
-		olatAuthenticationSpi = CoreSpringFactory.getImpl(OLATAuthManager.class);
 		
 		loginComp = createVelocityContainer("olat_log", "olatlogin");
 		
@@ -175,17 +177,17 @@ public class OLATAuthenticationController extends AuthenticationController imple
 		if (source == loginForm && event == Event.DONE_EVENT) {
 			String login = loginForm.getLogin();
 			String pass = loginForm.getPass();	
-			if (LoginModule.isLoginBlocked(login)) {
+			if (loginModule.isLoginBlocked(login)) {
 				// do not proceed when blocked
-				showError("login.blocked", LoginModule.getAttackPreventionTimeoutMin().toString());
+				showError("login.blocked", loginModule.getAttackPreventionTimeoutMin().toString());
 				getLogger().audit("Login attempt on already blocked login for " + login + ". IP::" + ureq.getHttpReq().getRemoteAddr(), null);
 				return;
 			}
 			authenticatedIdentity = olatAuthenticationSpi.authenticate(null, login, pass);
 			if (authenticatedIdentity == null) {
-				if (LoginModule.registerFailedLoginAttempt(login)) {
+				if (loginModule.registerFailedLoginAttempt(login)) {
 					getLogger().audit("Too many failed login attempts for " + login + ". Login blocked. IP::" + ureq.getHttpReq().getRemoteAddr(), null);
-					showError("login.blocked", LoginModule.getAttackPreventionTimeoutMin().toString());
+					showError("login.blocked", loginModule.getAttackPreventionTimeoutMin().toString());
 					return;
 				} else {
 					showError("login.error", WebappHelper.getMailConfig("mailReplyTo"));
@@ -203,7 +205,7 @@ public class OLATAuthenticationController extends AuthenticationController imple
 				}
 			}
 			
-			LoginModule.clearFailedLoginAttempts(login);
+			loginModule.clearFailedLoginAttempts(login);
 			
 			// Check if disclaimer has been accepted
 			if (RegistrationManager.getInstance().needsToConfirmDisclaimer(authenticatedIdentity)) {
diff --git a/src/main/java/org/olat/login/_i18n/LocalStrings_de.properties b/src/main/java/org/olat/login/_i18n/LocalStrings_de.properties
index 631a47ac0e3..6aba4ebb5d3 100644
--- a/src/main/java/org/olat/login/_i18n/LocalStrings_de.properties
+++ b/src/main/java/org/olat/login/_i18n/LocalStrings_de.properties
@@ -55,6 +55,9 @@ accesskey.tools=$org.olat.core.commons.fullWebApp\:accesskey.tools
 accesskey.top=$org.olat.core.commons.fullWebApp\:accesskey.top
 accesskey.topnav=$org.olat.core.commons.fullWebApp\:accesskey.topnav
 
+admin.menu.title=Gast und Einladung
+admin.menu.title.alt=$\:admin.menu.title
+
 authentication.provider.description=Geh\u00F6ren Sie keiner der oben aufgelisteten Institutionen an oder haben ein lokales Nutzerkonto?
 authentication.provider.linkText=Anmelden mit OpenOLAT Konto 
 browsercheck.bestresults.newerversion=oder neuere Version
@@ -103,6 +106,7 @@ lf.error.loginempty=Bitte geben Sie einen Benutzernamen ein.
 lf.error.passempty=Bitte geben Sie ein Passwort ein.
 lf.login=OpenOLAT-Benutzername
 lf.pass=OpenOLAT-Passwort
+login.admin.title=Gast und Einladung
 login.altprovider=Alternative M\u00F6glichkeiten f\u00FCr Login
 login.blocked=<b>Anmeldung ist f\u00FCr diesen Benutzernamen gesperrt.</b><p><font size\="-1">Es wurden zu viele ung\u00FCltige Anmeldeversuche registriert. Eine Anmeldung mit diesem Benutzernamen wurde aus Sicherheitsgr\u00FCnden f\u00FCr die n\u00E4chsten {0} Minuten gesperrt.</p></font>
 login.blocked.forAll=Logins sind momentan gesperrt. Probieren Sie es bitte sp\u00E4ter noch einmal.
@@ -117,6 +121,11 @@ login.custommsg=
 
 login.customfootermsg=
 
+guest.login=Gastlogin auf Login Seite
+guest.login.links=Links für Gast
+invitation.login=Einladung erlauben
+enabled=ein
+
 menu.about=\u00DCber OpenOLAT
 menu.about.alt=Informationen zu OpenOLAT
 menu.check=Browsercheck
diff --git a/src/main/java/org/olat/login/_i18n/LocalStrings_en.properties b/src/main/java/org/olat/login/_i18n/LocalStrings_en.properties
index fbf6426ca5e..933419e6218 100644
--- a/src/main/java/org/olat/login/_i18n/LocalStrings_en.properties
+++ b/src/main/java/org/olat/login/_i18n/LocalStrings_en.properties
@@ -48,6 +48,8 @@ accesskey.tools=$org.olat.core.commons.fullWebApp\:accesskey.tools
 accesskey.top=$org.olat.core.commons.fullWebApp\:accesskey.top
 accesskey.topnav=$org.olat.core.commons.fullWebApp\:accesskey.topnav
 
+admin.menu.title=Guest and invitation
+admin.menu.title.alt=$\:admin.menu.title
 authentication.provider.description=Don't you belong to one of the institutions mentioned above or have a local user acount?
 authentication.provider.linkText=Login with OpenOLAT account
 browsercheck.bestresults.newerversion=or later version
@@ -98,6 +100,7 @@ lf.error.passempty=Please insert a password.
 lf.login=OpenOLAT user name
 lf.pass=OpenOLAT password
 loadtest.warn=Attention\! Load test mode is activated\!
+login.admin.title=Guest and invitation
 login.altprovider=Alternative login possibilities.
 login.blocked=<b>Login blocked for this user name.</b><p><font size\="-1">Too many failed login attempts. For security reasons, further attempts will be blocked for a period of {0} minutes.</p></font>
 login.blocked.forAll=Login are blocked. Please try later.
@@ -112,6 +115,11 @@ login.custommsg=
 
 login.customfootermsg=
 
+guest.login=Guest login on login page
+guest.login.links=Links for guests
+invitation.login=Allow invitation
+enabled=enabled
+
 mail.pwd.subject=Password changed
 mail.pwd.body=The password for your OpenOLAT account {0} with the email address {1} has been changed by {2}.\n\n\nIf you do not agree with this change or if you think your account has been compromised by third parties, please contact support immediately at {3} or use the Link {4} to change the password again.
 menu.about=About OpenOLAT
diff --git a/src/main/java/org/olat/login/_spring/loginContext.xml b/src/main/java/org/olat/login/_spring/loginContext.xml
index b1e18a03cc2..348161b8f08 100644
--- a/src/main/java/org/olat/login/_spring/loginContext.xml
+++ b/src/main/java/org/olat/login/_spring/loginContext.xml
@@ -8,109 +8,70 @@
   http://www.springframework.org/schema/context 
   http://www.springframework.org/schema/context/spring-context.xsd">
 
-	<context:component-scan base-package="org.olat.login.oauth" />
+	<context:component-scan base-package="org.olat.login" />
   
+	<bean id="OLATAuthenticationProvider" class="org.olat.login.auth.AuthenticationProvider" >
+		<constructor-arg index="0" value="OLAT"/>
+		<constructor-arg index="1" value="org.olat.login.OLATAuthenticationController"/>
+		<constructor-arg index="2" value="${olatprovider.enable}"/>
+		<constructor-arg index="3" value="${olatprovider.default}"/>
+		<constructor-arg index="4" value="o_icon_provider_olat"/>
+	</bean>
 
-<bean id="loginModule" class="org.olat.login.LoginModule">
-	<property name="persistedProperties">
-	  <bean class="org.olat.core.configuration.PersistedProperties" scope="prototype" init-method="init" destroy-method="destroy">
-	    <constructor-arg index="0" ref="coordinatorManager"/>
-	    <constructor-arg index="1" ref="loginModule" />
-	  </bean>
-	</property>
+	<bean id="ShibUZHAuthenticationProvider" class="org.olat.login.auth.AuthenticationProvider" >
+		<constructor-arg index="0" value="Shib"/>
+		<constructor-arg index="1" value="org.olat.shibboleth.ShibbolethAuthenticationController"/>
+		<constructor-arg index="2" value="${shibbolethUZH.enable}"/>
+		<constructor-arg index="3" value="${shibbolethUZH.default}"/>
+		<constructor-arg index="4" value="o_icon_provider_shibboleth"/>
+	</bean>
 
-	<property name="coordinator" ref="coordinatorManager" />
-	<property name="authenticaionProviders">
-		<map>
-		<!--
-			An authentication provider needs to provide its Authenticator class and a name. 
-			Description and link text have to be i18n-properties files in xxAuthenticationController-package and be named
-			authentication.provider.linkText, authentication.provider.description . 
-		-->
-		
-		<!-- The standard OLAT authentication provider (username/password) -->
-		<entry key="OLAT">
-			<bean id="OLATAuthenticationProvider" class="org.olat.login.auth.AuthenticationProvider" >
-					<constructor-arg index="0" value="OLAT"/>
-					<constructor-arg index="1" value="org.olat.login.OLATAuthenticationController"/>
-					<constructor-arg index="2" value="${olatprovider.enable}"/>
-					<constructor-arg index="3" value="${olatprovider.default}"/>
-					<constructor-arg index="4" value="o_icon_provider_olat"/>
-			</bean>
-		</entry>
-		<!-- The Shibboleth authentication provider used by UZH with switch embedded WAYF -->
-		<entry key="Shib">
-			<bean id="ShibUZHAuthenticationProvider" class="org.olat.login.auth.AuthenticationProvider" >
-					<constructor-arg index="0" value="Shib"/>
-					<constructor-arg index="1" value="org.olat.shibboleth.ShibbolethAuthenticationController"/>
-					<constructor-arg index="2" value="${shibbolethUZH.enable}"/>
-					<constructor-arg index="3" value="${shibbolethUZH.default}"/>
-					<constructor-arg index="4" value="o_icon_provider_shibboleth"/>
-			</bean>
-		</entry>
-		<!-- The Shibboleth default authentication provider (WAYF activated over shibd config) -->
-		<entry key="ShibGeneric">
-			<bean id="ShibAuthenticationProvider" class="org.olat.login.auth.AuthenticationProvider" >
-					<constructor-arg index="0" value="ShibGeneric"/>
-					<constructor-arg index="1" value="org.olat.shibboleth.DefaultShibbolethAuthenticationController"/>
-					<constructor-arg index="2" value="${shibbolethGeneric.enable}"/>
-					<constructor-arg index="3" value="${shibbolethGeneric.default}"/>
-					<constructor-arg index="4" value="o_icon_provider_shibboleth"/>
-			</bean>
-		</entry>
-			<!-- The LDAP authentication provider -->
-			<entry key="LDAP">
-				<bean id="LDAPAuthenticationProvider" class="org.olat.login.auth.AuthenticationProvider" >
-					<constructor-arg index="0" value="LDAP"/>
-					<constructor-arg index="1" value="org.olat.ldap.ui.LDAPAuthenticationController"/>
-					<constructor-arg index="2" value="${ldap.enable}"/>
-					<constructor-arg index="3" value="${ldap.default}"/>
-					<constructor-arg index="4" value="o_icon_provider_ldap"/>
-				</bean>
-			</entry>
-			<!-- The OAuth authentication providers -->
-			<entry key="OAuth">
-				<bean id="OAuthAuthenticationProvider" class="org.olat.login.oauth.OAuthAuthenticationProvider" >
-					<constructor-arg index="0" value="OAuth"/>
-					<constructor-arg index="1" value="org.olat.login.oauth.ui.OAuthAuthenticationController"/>
-					<constructor-arg index="2" value="false"/>
-					<constructor-arg index="3" value="o_icon_provider_oauth"/>
-				</bean>
-			</entry>
-		</map>
-	</property>
-</bean>
+	<bean id="ShibAuthenticationProvider" class="org.olat.login.auth.AuthenticationProvider" >
+		<constructor-arg index="0" value="ShibGeneric"/>
+		<constructor-arg index="1" value="org.olat.shibboleth.DefaultShibbolethAuthenticationController"/>
+		<constructor-arg index="2" value="${shibbolethGeneric.enable}"/>
+		<constructor-arg index="3" value="${shibbolethGeneric.default}"/>
+		<constructor-arg index="4" value="o_icon_provider_shibboleth"/>
+	</bean>
 
-	<bean  class="org.springframework.beans.factory.config.MethodInvokingFactoryBean">
-        <property name="targetObject" ref="loginModule" />
-        <property name="targetMethod" value="init" />
-        <property name="arguments">
-                    <value>
-                   		 <!--
-						Used to prevent brute-force login attacks. If enabled, logins for this IP are blocked for
-						the given period of time after the given number of unsuccessfull login attempts.
-						After timeoutmin is reached, the user (this IP) may log in again.
-						-->
-	                    AttackPreventionEnabled=true
-	                    AttackPreventionMaxattempts=5
-	                    AttackPreventionTimeoutmin=5
-	                    
-	                    <!--
-						Show login links for guests on the login page if set to true
-						-->
-						GuestLoginLinksEnabled=${login.enableGuestLoginLinks}
-						InvitationEnabled=${login.invitationLogin}
-						allowLoginUsingEmail=${login.using.username.or.email.enabled}
-                    </value>
-          </property>
+	<bean id="LDAPAuthenticationProvider" class="org.olat.login.auth.AuthenticationProvider" >
+		<constructor-arg index="0" value="LDAP"/>
+		<constructor-arg index="1" value="org.olat.ldap.ui.LDAPAuthenticationController"/>
+		<constructor-arg index="2" value="${ldap.enable}"/>
+		<constructor-arg index="3" value="${ldap.default}"/>
+		<constructor-arg index="4" value="o_icon_provider_ldap"/>
 	</bean>
 
-	<bean id="afterLoginInterceptionManager" class="org.olat.login.AfterLoginInterceptionManager" />
-	<bean id="olatAuthenticationSpi" class="org.olat.login.auth.OLATAuthManager" />
+	<bean id="OAuthAuthenticationProvider" class="org.olat.login.oauth.OAuthAuthenticationProvider" >
+		<constructor-arg index="0" value="OAuth"/>
+		<constructor-arg index="1" value="org.olat.login.oauth.ui.OAuthAuthenticationController"/>
+		<constructor-arg index="2" value="false"/>
+		<constructor-arg index="3" value="o_icon_provider_oauth"/>
+	</bean>
+	
+	<!-- Login admin. panel -->
+	<bean class="org.olat.core.extensions.action.GenericActionExtension" init-method="initExtensionPoints">
+		<property name="order" value="8810" />
+		<property name="actionController">	
+			<bean class="org.olat.core.gui.control.creator.AutoCreator" scope="prototype">
+				<property name="className" value="org.olat.login.LoginAdminController"/>
+			</bean>
+		</property>
+		<property name="navigationKey" value="loginadmin" />
+		<property name="i18nActionKey" value="admin.menu.title"/>
+		<property name="i18nDescriptionKey" value="admin.menu.title.alt"/>
+		<property name="translationPackage" value="org.olat.login"/>
+		<property name="parentTreeNodeIdentifier" value="loginAndSecurityParent" /> 
+		<property name="extensionPoints">
+			<list>	
+				<value>org.olat.admin.SystemAdminMainController</value>		
+			</list>
+		</property>
+	</bean>
 
 	<!-- OAuth admin. panel -->
 	<bean class="org.olat.core.extensions.action.GenericActionExtension" init-method="initExtensionPoints">
-		<property name="order" value="8206" />
+		<property name="order" value="8825" />
 		<property name="actionController">	
 			<bean class="org.olat.core.gui.control.creator.AutoCreator" scope="prototype">
 				<property name="className" value="org.olat.login.oauth.ui.OAuthAdminController"/>
@@ -120,12 +81,11 @@
 		<property name="i18nActionKey" value="admin.menu.title"/>
 		<property name="i18nDescriptionKey" value="admin.menu.title.alt"/>
 		<property name="translationPackage" value="org.olat.login.oauth.ui"/>
-		<property name="parentTreeNodeIdentifier" value="modulesParent" /> 
+		<property name="parentTreeNodeIdentifier" value="loginAndSecurityParent" /> 
 		<property name="extensionPoints">
 			<list>	
 				<value>org.olat.admin.SystemAdminMainController</value>		
 			</list>
 		</property>
 	</bean>
-
 </beans>
\ No newline at end of file
diff --git a/src/main/java/org/olat/login/auth/OLATAuthManager.java b/src/main/java/org/olat/login/auth/OLATAuthManager.java
index 4d466313dee..6b1e052adac 100644
--- a/src/main/java/org/olat/login/auth/OLATAuthManager.java
+++ b/src/main/java/org/olat/login/auth/OLATAuthManager.java
@@ -64,6 +64,7 @@ import org.olat.registration.RegistrationManager;
 import org.olat.registration.TemporaryKey;
 import org.olat.user.UserManager;
 import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
 
 import com.thoughtworks.xstream.XStream;
 
@@ -75,6 +76,7 @@ import com.thoughtworks.xstream.XStream;
  * Initial Date:  26.09.2007 <br>
  * @author Felix Jost, http://www.goodsolutions.ch
  */
+@Service("olatAuthenticationSpi")
 public class OLATAuthManager extends BasicManager implements AuthenticationSPI {
 	
 	private static OLog log = Tracing.createLoggerFor(OLATAuthenticationController.class);
@@ -88,6 +90,8 @@ public class OLATAuthManager extends BasicManager implements AuthenticationSPI {
 	@Autowired
 	private WebDAVAuthManager webDAVAuthManager;
 	@Autowired
+	private LoginModule loginModule;
+	@Autowired
 	private LDAPLoginModule ldapLoginModule;
 	
 	/**
@@ -102,7 +106,7 @@ public class OLATAuthManager extends BasicManager implements AuthenticationSPI {
 		Authentication authentication;	
 		if (ident == null) {
 			// check for email instead of username if ident is null
-			if(LoginModule.allowLoginUsingEmail()) {
+			if(loginModule.isAllowLoginUsingEmail()) {
 				if (MailHelper.isValidEmailAddress(login)){
 					ident = userManager.findIdentityByEmail(login);
 					// check for email changed with verification workflow
@@ -130,7 +134,7 @@ public class OLATAuthManager extends BasicManager implements AuthenticationSPI {
 		if (securityManager.checkCredentials(authentication, password))	{
 			Algorithm algorithm = Algorithm.find(authentication.getAlgorithm());
 			if(Algorithm.md5.equals(algorithm)) {
-				Algorithm defAlgorithm = LoginModule.getDefaultHashAlgorithm();
+				Algorithm defAlgorithm = loginModule.getDefaultHashAlgorithm();
 				authentication = securityManager.updateCredentials(authentication, password, defAlgorithm);
 			}
 			Identity identity = authentication.getIdentity();
@@ -240,10 +244,10 @@ public class OLATAuthManager extends BasicManager implements AuthenticationSPI {
 	public boolean changeOlatPassword(Identity doer, Identity identity, String newPwd) {
 		Authentication auth = securityManager.findAuthentication(identity, "OLAT");
 		if (auth == null) { // create new authentication for provider OLAT
-			auth = securityManager.createAndPersistAuthentication(identity, "OLAT", identity.getName(), newPwd, LoginModule.getDefaultHashAlgorithm());
+			auth = securityManager.createAndPersistAuthentication(identity, "OLAT", identity.getName(), newPwd, loginModule.getDefaultHashAlgorithm());
 			log.audit(doer.getName() + " created new authenticatin for identity: " + identity.getName());
 		} else {
-			auth = securityManager.updateCredentials(auth, newPwd, LoginModule.getDefaultHashAlgorithm());
+			auth = securityManager.updateCredentials(auth, newPwd, loginModule.getDefaultHashAlgorithm());
 			log.audit(doer.getName() + " set new password for identity: " + identity.getName());
 		}
 		
diff --git a/src/main/java/org/olat/portfolio/ui/structel/EPShareListController.java b/src/main/java/org/olat/portfolio/ui/structel/EPShareListController.java
index 339f7407fe9..3b029cc0b2d 100644
--- a/src/main/java/org/olat/portfolio/ui/structel/EPShareListController.java
+++ b/src/main/java/org/olat/portfolio/ui/structel/EPShareListController.java
@@ -68,6 +68,7 @@ import org.olat.group.BusinessGroup;
 import org.olat.group.BusinessGroupService;
 import org.olat.group.model.BusinessGroupSelectionEvent;
 import org.olat.group.ui.main.SelectBusinessGroupController;
+import org.olat.login.LoginModule;
 import org.olat.portfolio.manager.EPFrontendManager;
 import org.olat.portfolio.manager.EPMapPolicy;
 import org.olat.portfolio.manager.EPMapPolicy.Type;
@@ -93,6 +94,8 @@ public class EPShareListController extends FormBasicController {
 	
 	private PortfolioStructureMap map;
 	
+	@Autowired
+	private LoginModule loginModule;
 	@Autowired
 	private EPFrontendManager ePFMgr;
 	@Autowired
@@ -502,7 +505,25 @@ public class EPShareListController extends FormBasicController {
 			container.setRootForm(mainForm);
 
 			if(policyWrapper.getType() != null) {
-				SingleSelection type = uifactory.addDropdownSingleselect("map.share.target." + cmpName, "map.share.target", container, targetKeys, targetValues, null);
+				String[] curatedTargetKeys;
+				String[] curatedTargetValues;
+				if(!Type.invitation.equals(policyWrapper.getType()) && !loginModule.isInvitationEnabled()) {
+					curatedTargetKeys = new String[targetKeys.length - 1];
+					curatedTargetValues = new String[targetKeys.length - 1];
+					
+					int pos = 0;
+					for(int i=targetKeys.length; i-->0; ) {
+						if(!targetKeys[i].equals(Type.invitation.name())) {
+							curatedTargetKeys[pos] = targetKeys[i];
+							curatedTargetValues[pos++] = targetValues[i];
+						}
+					}
+				} else {
+					curatedTargetKeys = targetKeys;
+					curatedTargetValues = targetValues;
+				}
+
+				SingleSelection type = uifactory.addDropdownSingleselect("map.share.target." + cmpName, "map.share.target", container, curatedTargetKeys, curatedTargetValues, null);
 				type.addActionListener(FormEvent.ONCHANGE);
 				type.setUserObject(policyWrapper);
 				type.select(policyWrapper.getType().name(), true);
@@ -552,7 +573,7 @@ public class EPShareListController extends FormBasicController {
 					FormLink inviteLink = uifactory.addFormLink("map.share.policy.invite." + cmpName, "map.share.policy.invite", null, container, Link.BUTTON);
 					inviteLink.setIconLeftCSS("o_icon o_icon-fw o_icon_share");
 					inviteLink.setUserObject(policyWrapper);
-					inviteLink.setEnabled(!policyWrapper.isInvitationSend());
+					inviteLink.setEnabled(!policyWrapper.isInvitationSend() && (loginModule.isInvitationEnabled() || !policyWrapper.getType().equals(Type.invitation)));
 				}
 				StaticTextElement genErrorPanel = uifactory.addStaticTextElement("errorpanel." + cmpName, "", container);
 				genErrorPanel.setUserObject(policyWrapper);
diff --git a/src/main/java/org/olat/registration/_spring/registrationContext.xml b/src/main/java/org/olat/registration/_spring/registrationContext.xml
index 8e695da4254..666da25a684 100644
--- a/src/main/java/org/olat/registration/_spring/registrationContext.xml
+++ b/src/main/java/org/olat/registration/_spring/registrationContext.xml
@@ -56,7 +56,7 @@
 		
 	<!-- Registration admin. panel -->
 	<bean class="org.olat.core.extensions.action.GenericActionExtension" init-method="initExtensionPoints">
-		<property name="order" value="7215" />
+		<property name="order" value="8815" />
 		<property name="actionController">	
 			<bean class="org.olat.core.gui.control.creator.AutoCreator" scope="prototype">
 				<property name="className" value="org.olat.registration.RegistrationAdminController"/>
@@ -66,7 +66,7 @@
 		<property name="i18nActionKey" value="admin.menu.title"/>
 		<property name="i18nDescriptionKey" value="admin.menu.title.alt"/>
 		<property name="translationPackage" value="org.olat.registration"/>
-		<property name="parentTreeNodeIdentifier" value="sysconfigParent" /> 
+		<property name="parentTreeNodeIdentifier" value="loginAndSecurityParent" /> 
 		<property name="extensionPoints">
 			<list>	
 				<value>org.olat.admin.SystemAdminMainController</value>		
diff --git a/src/main/java/org/olat/repository/ui/RepositoryEntryAccessColumnDescriptor.java b/src/main/java/org/olat/repository/ui/RepositoryEntryAccessColumnDescriptor.java
index 5214df3b0c1..090bea91e6f 100644
--- a/src/main/java/org/olat/repository/ui/RepositoryEntryAccessColumnDescriptor.java
+++ b/src/main/java/org/olat/repository/ui/RepositoryEntryAccessColumnDescriptor.java
@@ -21,6 +21,7 @@ package org.olat.repository.ui;
 
 import java.util.Locale;
 
+import org.olat.core.CoreSpringFactory;
 import org.olat.core.gui.components.table.CustomCellRenderer;
 import org.olat.core.gui.render.Renderer;
 import org.olat.core.gui.render.StringOutput;
@@ -42,7 +43,7 @@ public class RepositoryEntryAccessColumnDescriptor implements CustomCellRenderer
 	
 	public RepositoryEntryAccessColumnDescriptor(Translator translator) {
 		this.translator = translator;
-		guestLoginEnabled = LoginModule.isGuestLoginLinksEnabled();
+		guestLoginEnabled = CoreSpringFactory.getImpl(LoginModule.class).isGuestLoginLinksEnabled();
 	}
 
 	@Override
diff --git a/src/main/java/org/olat/repository/ui/RepositoryTableModel.java b/src/main/java/org/olat/repository/ui/RepositoryTableModel.java
index 36b821e611c..70ffff45cfe 100644
--- a/src/main/java/org/olat/repository/ui/RepositoryTableModel.java
+++ b/src/main/java/org/olat/repository/ui/RepositoryTableModel.java
@@ -85,6 +85,7 @@ public class RepositoryTableModel extends DefaultTableDataModel<RepositoryEntry>
 	private static final int COLUMN_COUNT = 7;
 	private final Translator translator; // package-local to avoid synthetic accessor method.
 	private final ACService acService;
+	private final LoginModule loginModule;
 	private final AccessControlModule acModule;
 	private final RepositoryModule repositoryModule;
 	private final RepositoryEntryLifecycleDAO lifecycleDao;
@@ -102,10 +103,11 @@ public class RepositoryTableModel extends DefaultTableDataModel<RepositoryEntry>
 		this.translator = translator;
 
 		acService = CoreSpringFactory.getImpl(ACService.class);
+		loginModule = CoreSpringFactory.getImpl(LoginModule.class);
+		userManager = CoreSpringFactory.getImpl(UserManager.class);
 		acModule = CoreSpringFactory.getImpl(AccessControlModule.class);
 		repositoryModule = CoreSpringFactory.getImpl(RepositoryModule.class);
 		lifecycleDao = CoreSpringFactory.getImpl(RepositoryEntryLifecycleDAO.class);
-		userManager = CoreSpringFactory.getImpl(UserManager.class);
 	}
 
 	/**
@@ -287,7 +289,7 @@ public class RepositoryTableModel extends DefaultTableDataModel<RepositoryEntry>
 					case RepositoryEntry.ACC_OWNERS_AUTHORS: return translator.translate("table.header.access.author");
 					case RepositoryEntry.ACC_USERS: return translator.translate("table.header.access.user");
 					case RepositoryEntry.ACC_USERS_GUESTS: {
-						if(!LoginModule.isGuestLoginLinksEnabled()) {
+						if(!loginModule.isGuestLoginLinksEnabled()) {
 							return translator.translate("table.header.access.user");
 						}
 						return translator.translate("table.header.access.guest");
diff --git a/src/main/java/org/olat/repository/ui/author/AccessRenderer.java b/src/main/java/org/olat/repository/ui/author/AccessRenderer.java
index 79e112dc08e..709a1227fc4 100644
--- a/src/main/java/org/olat/repository/ui/author/AccessRenderer.java
+++ b/src/main/java/org/olat/repository/ui/author/AccessRenderer.java
@@ -19,6 +19,7 @@
  */
 package org.olat.repository.ui.author;
 
+import org.olat.core.CoreSpringFactory;
 import org.olat.core.gui.components.form.flexible.impl.elements.table.FlexiCellRenderer;
 import org.olat.core.gui.components.form.flexible.impl.elements.table.FlexiTableComponent;
 import org.olat.core.gui.render.Renderer;
@@ -40,7 +41,7 @@ public class AccessRenderer implements FlexiCellRenderer {
 	private final boolean guestLoginEnabled;
 	
 	public AccessRenderer() {
-		guestLoginEnabled = LoginModule.isGuestLoginLinksEnabled();
+		guestLoginEnabled = CoreSpringFactory.getImpl(LoginModule.class).isGuestLoginLinksEnabled();
 	}
 
 	@Override
diff --git a/src/main/java/org/olat/repository/ui/author/AuthoringEntryPublishController.java b/src/main/java/org/olat/repository/ui/author/AuthoringEntryPublishController.java
index 969e12a5adf..fdfdd67f10a 100644
--- a/src/main/java/org/olat/repository/ui/author/AuthoringEntryPublishController.java
+++ b/src/main/java/org/olat/repository/ui/author/AuthoringEntryPublishController.java
@@ -43,6 +43,7 @@ import org.olat.repository.RepositoryEntryManagedFlag;
 import org.olat.repository.RepositoryService;
 import org.olat.repository.handlers.RepositoryHandler;
 import org.olat.repository.handlers.RepositoryHandlerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
 
 /**
  * Form controller to configure the access and publish settings of a repository
@@ -78,6 +79,8 @@ public class AuthoringEntryPublishController extends FormBasicController {
 	private static final String MEMBERSONLY_KEY = "m";
 	private String[] publishedKeys;
 
+	@Autowired
+	private LoginModule loginModule;
 	
 	/**
 	 * The details form is initialized with data collected from entry and
@@ -97,7 +100,7 @@ public class AuthoringEntryPublishController extends FormBasicController {
 			handler = RepositoryHandlerFactory.getInstance().getRepositoryHandler(typeName);
 		}
 		
-		if (LoginModule.isGuestLoginLinksEnabled()) {
+		if (loginModule.isGuestLoginLinksEnabled()) {
 			publishedKeys = new String[]{OAU_KEY, OAUG_KEY, MEMBERSONLY_KEY};
 		} else {
 			publishedKeys = new String[]{OAU_KEY, MEMBERSONLY_KEY};
@@ -216,7 +219,7 @@ public class AuthoringEntryPublishController extends FormBasicController {
 		uifactory.addSpacerElement("authorSpacer", authorConfigLayout, true);
 
 		String[] publishedValues;
-		if (LoginModule.isGuestLoginLinksEnabled()) {
+		if (loginModule.isGuestLoginLinksEnabled()) {
 			publishedValues = new String[]{translate("cif.access.users"), translate("cif.access.users_guests"), translate("cif.access.membersonly")};
 		} else {
 			publishedValues = new String[]{translate("cif.access.users"), translate("cif.access.membersonly")};
@@ -253,14 +256,14 @@ public class AuthoringEntryPublishController extends FormBasicController {
 		if (entry.getAccess() == RepositoryEntry.ACC_USERS) {
 			publishedForUsers.select(OAU_KEY, true);
 			usersSwitch.select(YES_KEY, true);
-		} else if (LoginModule.isGuestLoginLinksEnabled() && entry.getAccess() == RepositoryEntry.ACC_USERS_GUESTS){
+		} else if (loginModule.isGuestLoginLinksEnabled() && entry.getAccess() == RepositoryEntry.ACC_USERS_GUESTS){
 			publishedForUsers.select(OAUG_KEY, true);			
 			usersSwitch.select(YES_KEY, true);
 		} else if (entry.isMembersOnly()) {
 			publishedForUsers.select(MEMBERSONLY_KEY, true);
 			usersSwitch.select(YES_KEY, true);
 		} else {
-			if (LoginModule.isGuestLoginLinksEnabled()) {
+			if (loginModule.isGuestLoginLinksEnabled()) {
 				publishedForUsers.select(OAUG_KEY, false);
 			} else {
 				publishedForUsers.select(OAU_KEY, true);
@@ -285,7 +288,7 @@ public class AuthoringEntryPublishController extends FormBasicController {
 		} else {
 			// reset to default
 			publishedForUsers.select(OAU_KEY, true);
-			if (LoginModule.isGuestLoginLinksEnabled()) {
+			if (loginModule.isGuestLoginLinksEnabled()) {
 				publishedForUsers.select(OAUG_KEY, false);
 			}
 			publishedForUsers.select(MEMBERSONLY_KEY, false);
diff --git a/src/main/java/org/olat/repository/ui/catalog/CatalogNodeManagerController.java b/src/main/java/org/olat/repository/ui/catalog/CatalogNodeManagerController.java
index 5a48e2f01fa..af77cc19c10 100644
--- a/src/main/java/org/olat/repository/ui/catalog/CatalogNodeManagerController.java
+++ b/src/main/java/org/olat/repository/ui/catalog/CatalogNodeManagerController.java
@@ -74,14 +74,15 @@ import org.olat.core.util.mail.ContactList;
 import org.olat.core.util.mail.ContactMessage;
 import org.olat.core.util.resource.OresHelper;
 import org.olat.core.util.vfs.VFSLeaf;
+import org.olat.login.LoginModule;
 import org.olat.modules.co.ContactFormController;
 import org.olat.repository.CatalogEntry;
+import org.olat.repository.CatalogEntry.Style;
 import org.olat.repository.RepositoryEntry;
 import org.olat.repository.RepositoryEntryRef;
 import org.olat.repository.RepositoryManager;
 import org.olat.repository.RepositoryModule;
 import org.olat.repository.RepositoryService;
-import org.olat.repository.CatalogEntry.Style;
 import org.olat.repository.controllers.RepositorySearchController;
 import org.olat.repository.manager.CatalogManager;
 import org.olat.repository.model.SearchAuthorRepositoryEntryViewParams.OrderBy;
@@ -149,6 +150,8 @@ public class CatalogNodeManagerController extends FormBasicController implements
 	@Autowired
 	private UserManager userManager;
 	@Autowired
+	private LoginModule loginModule;
+	@Autowired
 	private AccessControlModule acModule;
 	@Autowired
 	private RepositoryModule repositoryModule;
@@ -204,7 +207,9 @@ public class CatalogNodeManagerController extends FormBasicController implements
 		flc.contextPut("catalogLevel", level);
 		
 		String url = Settings.getServerContextPathURI() + "/url/CatalogEntry/" + catalogEntry.getKey();
-		flc.contextPut("guestExtLink", url + "?guest=true&amp;lang=" + getLocale().getLanguage());
+		if(loginModule.isGuestLoginLinksEnabled()) {
+			flc.contextPut("guestExtLink", url + "?guest=true&amp;lang=" + getLocale().getLanguage());
+		}
 		if (!isGuest) {
 			flc.contextPut("extLink", url);
 		}
diff --git a/src/main/java/org/olat/repository/ui/catalog/_content/node.html b/src/main/java/org/olat/repository/ui/catalog/_content/node.html
index a73846788cf..d0b60327bc7 100644
--- a/src/main/java/org/olat/repository/ui/catalog/_content/node.html
+++ b/src/main/java/org/olat/repository/ui/catalog/_content/node.html
@@ -71,13 +71,34 @@
 	#end
 	
 	#if($extLink || $guestExtLink)
-	<div class="o_catalog_links">
-	#o_togglebox_start("o_catalog_extlink" $r.translate("cat.externalLink"))
+	<div class="o_extlink clearfix o_block_large_bottom">
+		<h4>$r.translate("cat.externalLink")</h4>
 		#if($extLink)
-			<pre>$extLink</pre>
+			<div class="o_copy_code">
+				<a href="javascript:;" id="o_extlink"><i class="o_icon o_icon-lg o_icon-fw o_icon_qrcode"></i></a>
+				$extLink
+				<script type="text/javascript">
+				/* <![CDATA[ */
+					jQuery(function() {
+						o_QRCodePopup('o_extlink', '$extLink', 'right');
+					});
+				/* ]]> */
+				</script>
+			</div>
+		#end
+		#if($guestExtLink)
+			<div class="o_copy_code">
+				<a href="javascript:;" id="o_guestextlink"><i class="o_icon o_icon-lg o_icon-fw o_icon_qrcode"></i></a>
+				${guestExtLink}
+				<script type="text/javascript">
+				/* <![CDATA[ */
+					jQuery(function() {
+						o_QRCodePopup('o_guestextlink', '$guestExtLink', 'right');
+					});
+				/* ]]> */
+				</script>
+			</div>
 		#end
-		<pre>$guestExtLink</pre>
-	#o_togglebox_end()
 	</div>
 	#end
 </div>
\ No newline at end of file
diff --git a/src/main/java/org/olat/repository/ui/list/RepositoryEntryDetailsController.java b/src/main/java/org/olat/repository/ui/list/RepositoryEntryDetailsController.java
index a941c451aad..b260245238f 100644
--- a/src/main/java/org/olat/repository/ui/list/RepositoryEntryDetailsController.java
+++ b/src/main/java/org/olat/repository/ui/list/RepositoryEntryDetailsController.java
@@ -69,6 +69,7 @@ import org.olat.course.run.RunMainController;
 import org.olat.group.BusinessGroup;
 import org.olat.group.BusinessGroupService;
 import org.olat.group.model.SearchBusinessGroupParams;
+import org.olat.login.LoginModule;
 import org.olat.repository.CatalogEntry;
 import org.olat.repository.RepositoryEntry;
 import org.olat.repository.RepositoryEntryRef;
@@ -111,6 +112,8 @@ public class RepositoryEntryDetailsController extends FormBasicController {
 	protected RepositoryEntryRow row;
 	private Integer index;
 
+	@Autowired
+	private LoginModule loginModule;
 	@Autowired
 	protected UserRatingsDAO userRatingsDao;
 	@Autowired
@@ -432,7 +435,9 @@ public class RepositoryEntryDetailsController extends FormBasicController {
             // Link to bookmark entry
             String url = Settings.getServerContextPathURI() + "/url/RepositoryEntry/" + entry.getKey();
             layoutCont.contextPut("extlink", url);
-            layoutCont.contextPut("isGuestAllowed", (entry.getAccess() >= RepositoryEntry.ACC_USERS_GUESTS ? Boolean.TRUE : Boolean.FALSE));
+            Boolean guestAllowed = (entry.getAccess() >= RepositoryEntry.ACC_USERS_GUESTS && loginModule.isGuestLoginLinksEnabled())
+            		? Boolean.TRUE : Boolean.FALSE;
+            layoutCont.contextPut("isGuestAllowed", guestAllowed);
 
             //Owners
             List<String> authorLinkNames = new ArrayList<String>(authorKeys.size());
diff --git a/src/main/java/org/olat/shibboleth/ShibbolethMigrationForm.java b/src/main/java/org/olat/shibboleth/ShibbolethMigrationForm.java
index 56f8f7cb5ba..43a5de2aeed 100644
--- a/src/main/java/org/olat/shibboleth/ShibbolethMigrationForm.java
+++ b/src/main/java/org/olat/shibboleth/ShibbolethMigrationForm.java
@@ -39,6 +39,7 @@ import org.olat.core.gui.control.WindowControl;
 import org.olat.core.logging.OLog;
 import org.olat.core.logging.Tracing;
 import org.olat.login.LoginModule;
+import org.springframework.beans.factory.annotation.Autowired;
 
 /**
  * Initial Date:  09.08.2004
@@ -57,6 +58,9 @@ public class ShibbolethMigrationForm extends FormBasicController {
 	private TextElement login;
 	private TextElement password;
 	
+	@Autowired
+	private LoginModule loginModule;
+	@Autowired
 	private BaseSecurity securityManager;
 	
 	public ShibbolethMigrationForm(UserRequest ureq, WindowControl wControl, Authentication authentication) {
@@ -69,7 +73,7 @@ public class ShibbolethMigrationForm extends FormBasicController {
 	@Override
 	protected boolean validateFormLogic(UserRequest ureq) {
 		if (!securityManager.checkCredentials(authentication, password.getValue())) {
-			if (LoginModule.registerFailedLoginAttempt(login.getValue())) {
+			if (loginModule.registerFailedLoginAttempt(login.getValue())) {
 				password.setErrorKey("smf.error.blocked", null);
 				log.audit("Too many failed login attempts for " + login.getValue() + ". Login blocked.");
 			} else {
diff --git a/src/main/java/org/olat/user/_spring/additionalUserContext.xml b/src/main/java/org/olat/user/_spring/additionalUserContext.xml
deleted file mode 100644
index 210b104c78f..00000000000
--- a/src/main/java/org/olat/user/_spring/additionalUserContext.xml
+++ /dev/null
@@ -1,37 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<beans xmlns="http://www.springframework.org/schema/beans"
-	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
-	xsi:schemaLocation="
-  http://www.springframework.org/schema/beans 
-  http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">
-
-<!-- EXAMPLE SPRING CONFIG FILE FOR ADDITIONAL TEST USERS -->
-<!-- Copy this file to the top of your web-app CLASSPATH e.g. webapp/WEB-INF/classes and add your test-users to additionalTestUsers-list -->
-<!-- Delete this two line which contains 'REMOVE THIS LINE TO ENABLE' below -->
-
-<!--  REMOVE THIS LINE TO ENABLE
-
-<bean class="org.olat.user.TestUserAdder">
-	<constructor-arg ref="userModule"></constructor-arg>
-	
-	<property name="additionalTestUsers">
-        <list>
-                <bean class="org.olat.user.DefaultUser">
-                       <constructor-arg type="java.lang.String" value="author2" />
-                       <property name="firstName" value="Aurich2" />
-                       <property name="lastName" value="Thorw2" />
-                       <property name="email" value="author2@olat-newinstallation.org" />
-                       <property name="password" value="test" />
-                       <property name="language" value="${defaultlang}" />
-                       <property name="guest" value="false" />
-                       <property name="author" value="true" />
-                       <property name="admin" value="false" />
-                       
-               </bean>
-           </list>
-	</property>
-</bean>
-
-  REMOVE THIS LINE TO ENABLE -->
-
-</beans>
\ No newline at end of file
diff --git a/src/main/java/org/olat/user/_spring/userContext.xml b/src/main/java/org/olat/user/_spring/userContext.xml
index 7ea69b5502a..21d7fc3c4b5 100644
--- a/src/main/java/org/olat/user/_spring/userContext.xml
+++ b/src/main/java/org/olat/user/_spring/userContext.xml
@@ -5,7 +5,6 @@
   http://www.springframework.org/schema/beans 
   http://www.springframework.org/schema/beans/spring-beans.xsd">
 
-	<import resource="classpath:/org/olat/user/_spring/additionalUserContext.xml"/>
 	<import resource="classpath:/org/olat/user/propertyhandlers/_spring/userPropertiesContext.xml"/>
 	<import resource="classpath:/org/olat/user/propertyhandlers/_spring/userPropertriesHandlersContext.xml"/>
 
diff --git a/src/main/resources/serviceconfig/olat.properties b/src/main/resources/serviceconfig/olat.properties
index 4a944b6204f..12dff17584f 100644
--- a/src/main/resources/serviceconfig/olat.properties
+++ b/src/main/resources/serviceconfig/olat.properties
@@ -186,10 +186,16 @@ registration.preset.username.allowChanges=true
 # the shibboleth attribute to use to preset the username
 registration.preset.username.shibbolethAttribute=Shib-SwissEP-UniqueID
 
-# provide guest login links
+# provide guest login on the dmz page
 login.enableGuestLoginLinks=true
+guest.login=${login.enableGuestLoginLinks}
+# provider guest url in groups and courses
+guest.login.links=${login.enableGuestLoginLinks}
+
 # allow invitation login
 login.invitationLogin=true
+invitation.login=${login.invitationLogin}
+
 # Allow users to login using alternatively their email address or username
 login.using.username.or.email.enabled=true
 # permit users to change their own passwords 
diff --git a/src/test/java/org/olat/basesecurity/BaseSecurityManagerTest.java b/src/test/java/org/olat/basesecurity/BaseSecurityManagerTest.java
index 0ada5e6e243..a480287c311 100644
--- a/src/test/java/org/olat/basesecurity/BaseSecurityManagerTest.java
+++ b/src/test/java/org/olat/basesecurity/BaseSecurityManagerTest.java
@@ -60,6 +60,8 @@ public class BaseSecurityManagerTest extends OlatTestCase {
 	@Autowired
 	private UserManager userManager;
 	@Autowired
+	private LoginModule loginModule;
+	@Autowired
 	private BaseSecurity securityManager;
 	
 	
@@ -808,7 +810,7 @@ public class BaseSecurityManagerTest extends OlatTestCase {
 		
 		Authentication auth = securityManager.findAuthentication(ident, "OLAT");
 		String credentials = auth.getCredential();
-		Authentication updatedAuth = securityManager.updateCredentials(auth, "secret", LoginModule.getDefaultHashAlgorithm());
+		Authentication updatedAuth = securityManager.updateCredentials(auth, "secret", loginModule.getDefaultHashAlgorithm());
 		Assert.assertNotNull(auth);
 		Assert.assertNotNull(updatedAuth);
 		Assert.assertEquals(auth, updatedAuth);
@@ -817,7 +819,7 @@ public class BaseSecurityManagerTest extends OlatTestCase {
 		
 		Authentication auth2 = securityManager.findAuthentication(ident, "OLAT");
 		String credentials2 = auth2.getCredential();
-		Authentication notUpdatedAuth = securityManager.updateCredentials(auth2, "secret", LoginModule.getDefaultHashAlgorithm());
+		Authentication notUpdatedAuth = securityManager.updateCredentials(auth2, "secret", loginModule.getDefaultHashAlgorithm());
 		Assert.assertNotNull(auth2);
 		Assert.assertNotNull(notUpdatedAuth);
 		Assert.assertSame(auth2, notUpdatedAuth);
-- 
GitLab