JndiLoginModule is working
git-svn-id: https://svn.libreccm.org/ccm/trunk@6268 8810af33-2d31-482b-a856-94f89814c4dfmaster
parent
24092bc982
commit
0063bc49ce
|
|
@ -30,6 +30,7 @@ import javax.security.auth.login.FailedLoginException;
|
||||||
import javax.security.auth.login.LoginException;
|
import javax.security.auth.login.LoginException;
|
||||||
import javax.security.auth.spi.LoginModule;
|
import javax.security.auth.spi.LoginModule;
|
||||||
|
|
||||||
|
import com.arsdigita.domain.DataObjectNotFoundException;
|
||||||
import com.arsdigita.kernel.UserAuthentication;
|
import com.arsdigita.kernel.UserAuthentication;
|
||||||
|
|
||||||
import java.math.BigDecimal;
|
import java.math.BigDecimal;
|
||||||
|
|
@ -47,8 +48,8 @@ public class JndiLoginModule extends PasswordLoginModule implements LoginModule
|
||||||
private Map<String, ?> sharedState;
|
private Map<String, ?> sharedState;
|
||||||
private Map<String, ?> options;
|
private Map<String, ?> options;
|
||||||
|
|
||||||
private String username;
|
private UserAuthentication userAuthentication;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@SuppressWarnings({"unchecked", "rawtypes"})
|
@SuppressWarnings({"unchecked", "rawtypes"})
|
||||||
public void initialize(final Subject subject,
|
public void initialize(final Subject subject,
|
||||||
|
|
@ -62,51 +63,70 @@ public class JndiLoginModule extends PasswordLoginModule implements LoginModule
|
||||||
this.options = options;
|
this.options = options;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean login() throws LoginException {
|
||||||
|
|
||||||
|
try {
|
||||||
|
userAuthentication = UserAuthentication
|
||||||
|
.retrieveForSSOlogin(getUsername());
|
||||||
|
} catch (DataObjectNotFoundException ex) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
final boolean result = super.login();
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean commit() throws LoginException {
|
public boolean commit() throws LoginException {
|
||||||
LOGGER.debug("Commit");
|
LOGGER.debug("Commit");
|
||||||
|
|
||||||
final UserAuthentication auth = UserAuthentication
|
if (userAuthentication == null) {
|
||||||
.retrieveForSSOlogin(username);
|
return false;
|
||||||
final BigDecimal userId = auth.getUser().getID();
|
}
|
||||||
|
|
||||||
|
final BigDecimal userId = userAuthentication.getUser().getID();
|
||||||
subject.getPrincipals().add(new PartyPrincipal(userId));
|
subject.getPrincipals().add(new PartyPrincipal(userId));
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean abort() throws LoginException {
|
public boolean abort() throws LoginException {
|
||||||
LOGGER.debug("Aborting");
|
LOGGER.debug("Aborting");
|
||||||
|
if (userAuthentication == null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean logout() throws LoginException {
|
public boolean logout() throws LoginException {
|
||||||
LOGGER.debug("Logout");
|
LOGGER.debug("Logout");
|
||||||
|
if (userAuthentication == null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void checkPassword(final String username, final char[] password)
|
protected void checkPassword(final String username, final char[] password)
|
||||||
throws LoginException {
|
throws LoginException {
|
||||||
|
|
||||||
this.username = username;
|
|
||||||
|
|
||||||
|
final SecurityConfig securityConfig = SecurityConfig.getConfig();
|
||||||
|
final String connectionUrl = securityConfig.getLdapConnectionUrl();
|
||||||
|
final String userBase = securityConfig.getLdapUserBase();
|
||||||
|
final String userSearch = securityConfig.getLdapUserSearch();
|
||||||
|
|
||||||
final Hashtable<String, Object> env = new Hashtable<>();
|
final Hashtable<String, Object> env = new Hashtable<>();
|
||||||
env.put(Context.INITIAL_CONTEXT_FACTORY,
|
env.put(Context.INITIAL_CONTEXT_FACTORY,
|
||||||
"com.sun.jndi.ldap.LdapCtxFactory");
|
"com.sun.jndi.ldap.LdapCtxFactory");
|
||||||
env.put(Context.PROVIDER_URL, options.get("connectionURL"));
|
env.put(Context.PROVIDER_URL, connectionUrl);
|
||||||
env.put(Context.SECURITY_AUTHENTICATION, "none");
|
env.put(Context.SECURITY_AUTHENTICATION, "none");
|
||||||
|
|
||||||
try {
|
try {
|
||||||
final DirContext context = new InitialDirContext(env);
|
final DirContext context = new InitialDirContext(env);
|
||||||
|
|
||||||
final String userBase = (String) options.get("userBase");
|
final String filter = String.format(userSearch, username);
|
||||||
final MessageFormat userSearchFormat = new MessageFormat(
|
|
||||||
(String) options.get("userSearch")
|
|
||||||
);
|
|
||||||
final String filter = userSearchFormat
|
|
||||||
.format(new String[]{username});
|
|
||||||
final SearchControls searchControls = new SearchControls();
|
final SearchControls searchControls = new SearchControls();
|
||||||
final NamingEnumeration<SearchResult> results = context.search(
|
final NamingEnumeration<SearchResult> results = context.search(
|
||||||
userBase, filter, searchControls
|
userBase, filter, searchControls
|
||||||
|
|
@ -148,14 +168,14 @@ public class JndiLoginModule extends PasswordLoginModule implements LoginModule
|
||||||
throw new KernelLoginException(ex);
|
throw new KernelLoginException(ex);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
final String userDn = name.toString();
|
final String userDn = name.toString();
|
||||||
context.addToEnvironment(Context.SECURITY_PRINCIPAL, userDn);
|
context.addToEnvironment(Context.SECURITY_PRINCIPAL, userDn);
|
||||||
context.addToEnvironment(Context.SECURITY_CREDENTIALS, password);
|
context.addToEnvironment(Context.SECURITY_CREDENTIALS, password);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
context.getAttributes("", null);
|
context.getAttributes("", null);
|
||||||
} catch(AuthenticationException ex) {
|
} catch (AuthenticationException ex) {
|
||||||
LOGGER.info("LDAP login failed.");
|
LOGGER.info("LDAP login failed.");
|
||||||
throw new FailedLoginException(
|
throw new FailedLoginException(
|
||||||
"Bad username / password for LDAP"
|
"Bad username / password for LDAP"
|
||||||
|
|
|
||||||
|
|
@ -100,7 +100,7 @@ public abstract class PasswordLoginModule implements LoginModule {
|
||||||
*
|
*
|
||||||
* @throws LoginException if an error occurs.
|
* @throws LoginException if an error occurs.
|
||||||
*/
|
*/
|
||||||
private String getUsername() throws LoginException {
|
protected String getUsername() throws LoginException {
|
||||||
// get name from shared data
|
// get name from shared data
|
||||||
// TODO: only if *Pass option set
|
// TODO: only if *Pass option set
|
||||||
String username = (String)m_shared.get(NAME_KEY);
|
String username = (String)m_shared.get(NAME_KEY);
|
||||||
|
|
@ -129,7 +129,7 @@ public abstract class PasswordLoginModule implements LoginModule {
|
||||||
*
|
*
|
||||||
* @throws LoginException if an error occurs.
|
* @throws LoginException if an error occurs.
|
||||||
*/
|
*/
|
||||||
private char[] getPassword() throws LoginException {
|
protected char[] getPassword() throws LoginException {
|
||||||
// get password from shared data
|
// get password from shared data
|
||||||
// TODO: only if *Pass option set
|
// TODO: only if *Pass option set
|
||||||
char[] password = (char[])m_shared.get(PASSWORD_KEY);
|
char[] password = (char[])m_shared.get(PASSWORD_KEY);
|
||||||
|
|
|
||||||
|
|
@ -141,6 +141,18 @@ public class SecurityConfig extends AbstractConfig {
|
||||||
private final Parameter m_enableQuestion = new BooleanParameter(
|
private final Parameter m_enableQuestion = new BooleanParameter(
|
||||||
"waf.user_question.enable", Parameter.REQUIRED, Boolean.FALSE);
|
"waf.user_question.enable", Parameter.REQUIRED, Boolean.FALSE);
|
||||||
|
|
||||||
|
private final Parameter m_ldapConnectionUrl = new StringParameter(
|
||||||
|
"waf.ldap.connectionUrl", Parameter.REQUIRED, "localhost"
|
||||||
|
);
|
||||||
|
|
||||||
|
private final Parameter m_ldapUserBase = new StringParameter(
|
||||||
|
"waf.ldap.userBase", Parameter.REQUIRED, "ou=users,dc=example,dc=org"
|
||||||
|
);
|
||||||
|
|
||||||
|
private final Parameter m_ldapUserSearch = new StringParameter(
|
||||||
|
"waf.ldap.userSearch", Parameter.REQUIRED, "(mail=%s)"
|
||||||
|
);
|
||||||
|
|
||||||
private final Parameter m_enableSaml = new BooleanParameter(
|
private final Parameter m_enableSaml = new BooleanParameter(
|
||||||
"waf.enable_saml", Parameter.REQUIRED, Boolean.FALSE);
|
"waf.enable_saml", Parameter.REQUIRED, Boolean.FALSE);
|
||||||
private final Parameter m_oneLoginSaml2Strict = new BooleanParameter(
|
private final Parameter m_oneLoginSaml2Strict = new BooleanParameter(
|
||||||
|
|
@ -222,6 +234,10 @@ public class SecurityConfig extends AbstractConfig {
|
||||||
register(m_userBanOn);
|
register(m_userBanOn);
|
||||||
register(m_enableQuestion);
|
register(m_enableQuestion);
|
||||||
|
|
||||||
|
register(m_ldapConnectionUrl);
|
||||||
|
register(m_ldapUserBase);
|
||||||
|
register(m_ldapUserSearch);
|
||||||
|
|
||||||
register(m_enableSaml);
|
register(m_enableSaml);
|
||||||
|
|
||||||
register(m_oneLoginSaml2Debug);
|
register(m_oneLoginSaml2Debug);
|
||||||
|
|
@ -331,6 +347,18 @@ public class SecurityConfig extends AbstractConfig {
|
||||||
return ((Boolean) get(m_autoRegistrationOn)).booleanValue();
|
return ((Boolean) get(m_autoRegistrationOn)).booleanValue();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public final String getLdapConnectionUrl() {
|
||||||
|
return (String) get(m_ldapConnectionUrl);
|
||||||
|
}
|
||||||
|
|
||||||
|
public final String getLdapUserBase() {
|
||||||
|
return (String) get(m_ldapUserBase);
|
||||||
|
}
|
||||||
|
|
||||||
|
public final String getLdapUserSearch() {
|
||||||
|
return (String) get(m_ldapUserSearch);
|
||||||
|
}
|
||||||
|
|
||||||
public final boolean getEnableSaml() {
|
public final boolean getEnableSaml() {
|
||||||
return (Boolean) get(m_enableSaml);
|
return (Boolean) get(m_enableSaml);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue