diff --git a/account/src/main/java/de/muehlencord/shared/account/presentation/LoginView.java b/account/src/main/java/de/muehlencord/shared/account/presentation/LoginView.java index 7bc72d2..7bb411c 100644 --- a/account/src/main/java/de/muehlencord/shared/account/presentation/LoginView.java +++ b/account/src/main/java/de/muehlencord/shared/account/presentation/LoginView.java @@ -10,6 +10,7 @@ import javax.faces.context.ExternalContext; import javax.faces.context.FacesContext; import javax.faces.view.ViewScoped; import javax.inject.Named; +import javax.naming.NamingException; import javax.servlet.ServletRequest; import javax.servlet.ServletResponse; @@ -68,10 +69,19 @@ public class LoginView implements Serializable { String hint = "Error while authenticating user " + username; if (LOGGER.isDebugEnabled()) { LOGGER.debug(hint, ex); - } else { - LOGGER.error(hint + " Reason: " + ex.toString()); } - FacesUtil.addGlobalErrorMessage("Login failed", hint); + + if (ex.getMessage() != null) { + hint += "Reason: " + ex.getMessage(); + } else { + hint += "Reason: " + ex.toString(); + } + if ((ex.getCause() != null) && (ex.getCause().getMessage() != null)) { + hint += "Rootcause: " + ex.getMessage(); + + LOGGER.error(hint); + } + FacesUtil.addGlobalErrorMessage("Login failed", hint); AccountEntity account = accountService.getAccountEntity(username, false); if (account != null) { @@ -123,7 +133,7 @@ public class LoginView implements Serializable { return login(); } else { // TODO add email notificaton on failed password reset - FacesUtil.addGlobalErrorMessage("Password reset failed", null); + FacesUtil.addGlobalErrorMessage("Password reset failed", null); return login(); } } diff --git a/account/src/main/java/de/muehlencord/shared/account/util/UserNameActiveDirectoryRealm.java b/account/src/main/java/de/muehlencord/shared/account/util/UserNameActiveDirectoryRealm.java index 664f1bf..7792e8c 100644 --- a/account/src/main/java/de/muehlencord/shared/account/util/UserNameActiveDirectoryRealm.java +++ b/account/src/main/java/de/muehlencord/shared/account/util/UserNameActiveDirectoryRealm.java @@ -1,101 +1,106 @@ -package de.muehlencord.shared.account.util; - -import java.util.HashSet; -import java.util.Set; -import javax.naming.NamingException; -import javax.naming.ldap.LdapContext; -import org.apache.shiro.authc.AuthenticationInfo; -import org.apache.shiro.authc.AuthenticationToken; -import org.apache.shiro.authc.UsernamePasswordToken; -import org.apache.shiro.authz.AuthorizationInfo; -import org.apache.shiro.realm.activedirectory.ActiveDirectoryRealm; -import org.apache.shiro.realm.ldap.LdapContextFactory; -import org.apache.shiro.realm.ldap.LdapUtils; -import org.apache.shiro.subject.PrincipalCollection; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -/** - * - * @author joern.muehlencord - */ -public class UserNameActiveDirectoryRealm extends ActiveDirectoryRealm { - - private static final Logger LOGGER = LoggerFactory.getLogger(UserNameActiveDirectoryRealm.class); - - private boolean permissionsLookupEnabled = true; - - @Override - protected AuthenticationInfo queryForAuthenticationInfo(AuthenticationToken token, LdapContextFactory ldapContextFactory) throws NamingException { - UsernamePasswordToken upToken = (UsernamePasswordToken) token; - - LdapContext ctx = null; - String userName = upToken.getUsername(); - try { - if (principalSuffix != null) { - if (!userName.contains(principalSuffix)) { - userName += principalSuffix; - } - } - - // Binds using the username and password provided by the user. - LOGGER.debug("start creating context"); - ctx = ldapContextFactory.getLdapContext(userName, upToken.getCredentials()); - LOGGER.debug("context created"); - } finally { - LdapUtils.closeContext(ctx); - } - - LOGGER.debug("building authentication info"); - AuthenticationInfo authInfo = buildAuthenticationInfo(userName, upToken.getPassword()); - LOGGER.debug("authentifaction info created"); - return authInfo; - } - - /** - * Builds an {@link org.apache.shiro.authz.AuthorizationInfo} object by - * querying the active directory LDAP context for the groups that a user is - * a member of. The groups are then translated to role names by using the - * configured {@link #groupRolesMap}. - *

- * This implementation expects the principal argument to be a - * String username. - *

- * Subclasses can override this method to determine authorization data - * (roles, permissions, etc) in a more complex way. Note that this default - * implementation does not support permissions, only roles. - * - * @param principals the principal of the Subject whose account is being - * retrieved. - * @param ldapContextFactory the factory used to create LDAP connections. - * @return the AuthorizationInfo for the given Subject principal. - * @throws NamingException if an error occurs when searching the LDAP - * server. - */ - @Override - protected AuthorizationInfo queryForAuthorizationInfo(PrincipalCollection principals, LdapContextFactory ldapContextFactory) throws NamingException { - Set roleNames; - if (this.permissionsLookupEnabled) { - String username = (String) getAvailablePrincipal(principals); - // Perform context search - LdapContext ldapContext = ldapContextFactory.getSystemLdapContext(); - try { - roleNames = getRoleNamesForUser(username, ldapContext); - } finally { - LdapUtils.closeContext(ldapContext); - } - } else { - roleNames = new HashSet<>(); - } - return buildAuthorizationInfo(roleNames); - } - - public boolean isPermissionsLookupEnabled() { - return permissionsLookupEnabled; - } - - public void setPermissionsLookupEnabled(boolean permissionsLookupEnabled) { - this.permissionsLookupEnabled = permissionsLookupEnabled; - } - -} +package de.muehlencord.shared.account.util; + +import java.util.HashSet; +import java.util.Set; +import javax.naming.NamingException; +import javax.naming.ldap.LdapContext; +import org.apache.shiro.authc.AuthenticationInfo; +import org.apache.shiro.authc.AuthenticationToken; +import org.apache.shiro.authc.UsernamePasswordToken; +import org.apache.shiro.authz.AuthorizationInfo; +import org.apache.shiro.realm.activedirectory.ActiveDirectoryRealm; +import org.apache.shiro.realm.ldap.LdapContextFactory; +import org.apache.shiro.realm.ldap.LdapUtils; +import org.apache.shiro.subject.PrincipalCollection; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * + * @author joern.muehlencord + */ +public class UserNameActiveDirectoryRealm extends ActiveDirectoryRealm { + + private static final Logger LOGGER = LoggerFactory.getLogger(UserNameActiveDirectoryRealm.class); + + private boolean permissionsLookupEnabled = true; + + @Override + protected AuthenticationInfo queryForAuthenticationInfo(AuthenticationToken token, LdapContextFactory ldapContextFactory) throws NamingException { + UsernamePasswordToken upToken = (UsernamePasswordToken) token; + + LdapContext ctx = null; + String userName = upToken.getUsername(); + try { + if (principalSuffix != null) { + if (!userName.contains(principalSuffix)) { + userName += principalSuffix; + } + } + + // Binds using the username and password provided by the user. + if (LOGGER.isDebugEnabled()) { + LOGGER.debug("start creating context"); + } + ctx = ldapContextFactory.getLdapContext(userName, upToken.getCredentials()); + if (LOGGER.isDebugEnabled()) { + LOGGER.debug("User {} LDAP authenticated", userName); + } + } finally { + LdapUtils.closeContext(ctx); + } + + LOGGER.debug("building authentication info"); + AuthenticationInfo authInfo = buildAuthenticationInfo(userName, upToken.getPassword()); + + LOGGER.debug("authentifaction info created"); + return authInfo; + } + + /** + * Builds an {@link org.apache.shiro.authz.AuthorizationInfo} object by + * querying the active directory LDAP context for the groups that a user is + * a member of. The groups are then translated to role names by using the + * configured {@link #groupRolesMap}. + *

+ * This implementation expects the principal argument to be a + * String username. + *

+ * Subclasses can override this method to determine authorization data + * (roles, permissions, etc) in a more complex way. Note that this default + * implementation does not support permissions, only roles. + * + * @param principals the principal of the Subject whose account is being + * retrieved. + * @param ldapContextFactory the factory used to create LDAP connections. + * @return the AuthorizationInfo for the given Subject principal. + * @throws NamingException if an error occurs when searching the LDAP + * server. + */ + @Override + protected AuthorizationInfo queryForAuthorizationInfo(PrincipalCollection principals, LdapContextFactory ldapContextFactory) throws NamingException { + Set roleNames; + if (this.permissionsLookupEnabled) { + String username = (String) getAvailablePrincipal(principals); + // Perform context search + LdapContext ldapContext = ldapContextFactory.getSystemLdapContext(); + try { + roleNames = getRoleNamesForUser(username, ldapContext); + } finally { + LdapUtils.closeContext(ldapContext); + } + } else { + roleNames = new HashSet<>(); + } + return buildAuthorizationInfo(roleNames); + } + + public boolean isPermissionsLookupEnabled() { + return permissionsLookupEnabled; + } + + public void setPermissionsLookupEnabled(boolean permissionsLookupEnabled) { + this.permissionsLookupEnabled = permissionsLookupEnabled; + } + +}