SAML support for CCM
git-svn-id: https://svn.libreccm.org/ccm/trunk@6168 8810af33-2d31-482b-a856-94f89814c4dfmaster^2^2^2^2^2^2
parent
288dd00ca1
commit
401c71b6d6
|
|
@ -5,13 +5,24 @@
|
||||||
*/
|
*/
|
||||||
package com.arsdigita.kernel.security;
|
package com.arsdigita.kernel.security;
|
||||||
|
|
||||||
|
import com.arsdigita.domain.DataObjectNotFoundException;
|
||||||
|
import com.arsdigita.kernel.UserAuthentication;
|
||||||
|
|
||||||
|
import com.onelogin.saml2.Auth;
|
||||||
|
import com.onelogin.saml2.exception.Error;
|
||||||
|
import com.onelogin.saml2.exception.SettingsException;
|
||||||
|
import org.apache.log4j.Logger;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
import java.math.BigDecimal;
|
||||||
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
import javax.security.auth.Subject;
|
import javax.security.auth.Subject;
|
||||||
import javax.security.auth.callback.Callback;
|
import javax.security.auth.callback.Callback;
|
||||||
import javax.security.auth.callback.CallbackHandler;
|
import javax.security.auth.callback.CallbackHandler;
|
||||||
import javax.security.auth.callback.UnsupportedCallbackException;
|
import javax.security.auth.callback.UnsupportedCallbackException;
|
||||||
|
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 javax.servlet.http.HttpServletRequest;
|
import javax.servlet.http.HttpServletRequest;
|
||||||
|
|
@ -23,10 +34,13 @@ import javax.servlet.http.HttpServletResponse;
|
||||||
*/
|
*/
|
||||||
public class SamlLoginModule implements LoginModule {
|
public class SamlLoginModule implements LoginModule {
|
||||||
|
|
||||||
|
private static final Logger LOGGER = Logger.getLogger(SamlLoginModule.class);
|
||||||
|
|
||||||
private CallbackHandler callbackHandler;
|
private CallbackHandler callbackHandler;
|
||||||
private HttpServletRequest request;
|
private HttpServletRequest request;
|
||||||
private HttpServletResponse response;
|
private HttpServletResponse response;
|
||||||
private Subject subject;
|
private Subject subject;
|
||||||
|
private BigDecimal userId;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void initialize(final Subject subject,
|
public void initialize(final Subject subject,
|
||||||
|
|
@ -40,22 +54,54 @@ public class SamlLoginModule implements LoginModule {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean login() throws LoginException {
|
public boolean login() throws LoginException {
|
||||||
throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
|
|
||||||
|
final HttpServletRequest request = getRequest();
|
||||||
|
final HttpServletResponse response = getResponse();
|
||||||
|
|
||||||
|
final Auth auth;
|
||||||
|
try {
|
||||||
|
auth = new Auth(request, response);
|
||||||
|
} catch (IOException | SettingsException | Error ex) {
|
||||||
|
LOGGER.error("SAML Login failed.", ex);
|
||||||
|
throw new LoginException("SAML Login failed. Configuration error?");
|
||||||
|
}
|
||||||
|
|
||||||
|
final List<String> errors = auth.getErrors();
|
||||||
|
if (!errors.isEmpty()) {
|
||||||
|
LOGGER.error(String.format("SAML Login errors: %s",
|
||||||
|
String.join(";\n", errors)));
|
||||||
|
throw new LoginException(String.format("SAML Login errors: %s",
|
||||||
|
String.join(";\n", errors)));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!auth.isAuthenticated()) {
|
||||||
|
throw new LoginException("Not authenticated.");
|
||||||
|
}
|
||||||
|
|
||||||
|
userId = getUserId(auth.getNameId());
|
||||||
|
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean commit() throws LoginException {
|
public boolean commit() throws LoginException {
|
||||||
throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
|
|
||||||
|
if (userId != null) {
|
||||||
|
subject.getPrincipals().add(new PartyPrincipal(userId));
|
||||||
|
}
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean abort() throws LoginException {
|
public boolean abort() throws LoginException {
|
||||||
throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean logout() throws LoginException {
|
public boolean logout() throws LoginException {
|
||||||
throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
|
|
||||||
|
getRequest().getSession().invalidate();
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected HttpServletRequest getRequest() throws LoginException {
|
protected HttpServletRequest getRequest() throws LoginException {
|
||||||
|
|
@ -86,4 +132,18 @@ public class SamlLoginModule implements LoginModule {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected BigDecimal getUserId(final String ssoLogin)
|
||||||
|
throws LoginException {
|
||||||
|
|
||||||
|
try {
|
||||||
|
final UserAuthentication userAuth = UserAuthentication
|
||||||
|
.retrieveForSSOlogin(ssoLogin);
|
||||||
|
|
||||||
|
return userAuth.getUser().getID();
|
||||||
|
} catch(DataObjectNotFoundException ex) {
|
||||||
|
throw new FailedLoginException(
|
||||||
|
String.format("SSO login %s not found", ssoLogin)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -126,7 +126,9 @@ public class SecurityConfig extends AbstractConfig {
|
||||||
"Register:com.arsdigita.kernel.security.UserIDLoginModule:requisite",
|
"Register:com.arsdigita.kernel.security.UserIDLoginModule:requisite",
|
||||||
"Register:com.arsdigita.kernel.security.CookieLoginModule:optional",
|
"Register:com.arsdigita.kernel.security.CookieLoginModule:optional",
|
||||||
"RegisterSSO:com.arsdigita.kernel.security.SimpleSSOLoginModule:requisite",
|
"RegisterSSO:com.arsdigita.kernel.security.SimpleSSOLoginModule:requisite",
|
||||||
"RegisterSSO:com.arsdigita.kernel.security.CookieLoginModule:optional"
|
"RegisterSSO:com.arsdigita.kernel.security.CookieLoginModule:optional",
|
||||||
|
"RegisterSAML:com.arsdigita.kernel.security.SamlLoginModule:requisite",
|
||||||
|
"RegisterSAML:com.arsdigita.kernel.security.CookieLoginModule:optional"
|
||||||
});
|
});
|
||||||
private final Parameter m_adminEmail = new StringParameter(
|
private final Parameter m_adminEmail = new StringParameter(
|
||||||
"waf.admin.contact_email", Parameter.OPTIONAL, null);
|
"waf.admin.contact_email", Parameter.OPTIONAL, null);
|
||||||
|
|
|
||||||
|
|
@ -57,7 +57,8 @@ import org.apache.commons.codec.binary.Base64;
|
||||||
import org.apache.log4j.Logger;
|
import org.apache.log4j.Logger;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Provides methods for logging in and logging out the current user and accessing the user ID.
|
* Provides methods for logging in and logging out the current user and
|
||||||
|
* accessing the user ID.
|
||||||
*
|
*
|
||||||
* @author Sameer Ajmani
|
* @author Sameer Ajmani
|
||||||
* @version $Id: UserContext.java 1498 2007-03-19 16:22:15Z apevec $
|
* @version $Id: UserContext.java 1498 2007-03-19 16:22:15Z apevec $
|
||||||
|
|
@ -81,6 +82,11 @@ public class UserContext {
|
||||||
*/
|
*/
|
||||||
public static final String REGISTER_SSO_LOGIN_CONTEXT = "RegisterSSO";
|
public static final String REGISTER_SSO_LOGIN_CONTEXT = "RegisterSSO";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Name of the SAML login context
|
||||||
|
*/
|
||||||
|
public static final String REGISTER_SAML_LOGIN_CONTEXT = "RegisterSAML";
|
||||||
|
|
||||||
// fields
|
// fields
|
||||||
private HttpServletRequest m_req;
|
private HttpServletRequest m_req;
|
||||||
private HttpServletResponse m_res;
|
private HttpServletResponse m_res;
|
||||||
|
|
@ -101,7 +107,8 @@ public class UserContext {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Loads the values for this <code>UserContext</code> from the given Subject.
|
* Loads the values for this <code>UserContext</code> from the given
|
||||||
|
* Subject.
|
||||||
*/
|
*/
|
||||||
private void loadValues(Subject subject)
|
private void loadValues(Subject subject)
|
||||||
throws LoginException {
|
throws LoginException {
|
||||||
|
|
@ -118,11 +125,12 @@ public class UserContext {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a user context from an HTTP request. Attempts to log in the user automatically to
|
* Creates a user context from an HTTP request. Attempts to log in the user
|
||||||
* load the user ID. Code should access this class using
|
* automatically to load the user ID. Code should access this class using
|
||||||
* <code>KernelHelper.getKernelRequestContext(req).getUserContext()</code>.
|
* <code>KernelHelper.getKernelRequestContext(req).getUserContext()</code>.
|
||||||
*
|
*
|
||||||
* @throws RedirectException if the user should be redirected to the login page.
|
* @throws RedirectException if the user should be redirected to the login
|
||||||
|
* page.
|
||||||
*/
|
*/
|
||||||
public UserContext(HttpServletRequest req,
|
public UserContext(HttpServletRequest req,
|
||||||
HttpServletResponse res)
|
HttpServletResponse res)
|
||||||
|
|
@ -149,7 +157,8 @@ public class UserContext {
|
||||||
login(UserAuthentication.retrieveForLoginName(username).getUser());
|
login(UserAuthentication.retrieveForLoginName(username).getUser());
|
||||||
s_log.debug("SUCCESS login(username)");
|
s_log.debug("SUCCESS login(username)");
|
||||||
} catch (DataObjectNotFoundException e) {
|
} catch (DataObjectNotFoundException e) {
|
||||||
throw new AccountNotFoundException("user " + username + " does not exist", e);
|
throw new AccountNotFoundException("user " + username
|
||||||
|
+ " does not exist", e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -169,7 +178,8 @@ public class UserContext {
|
||||||
login(User.retrieve(userID));
|
login(User.retrieve(userID));
|
||||||
s_log.debug("SUCCESS login(userID)");
|
s_log.debug("SUCCESS login(userID)");
|
||||||
} catch (DataObjectNotFoundException e) {
|
} catch (DataObjectNotFoundException e) {
|
||||||
throw new AccountNotFoundException("user " + userID + " does not exist", e);
|
throw new AccountNotFoundException("user " + userID
|
||||||
|
+ " does not exist", e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -178,8 +188,9 @@ public class UserContext {
|
||||||
*
|
*
|
||||||
* @param target the User to become
|
* @param target the User to become
|
||||||
*
|
*
|
||||||
* @throws FailedLoginException if the current user is not logged in, doesn't exist, or doesn't
|
* @throws FailedLoginException if the current user is not logged in,
|
||||||
* have admin privileges on the target user.
|
* doesn't exist, or doesn't have admin
|
||||||
|
* privileges on the target user.
|
||||||
*
|
*
|
||||||
* @throws LoginException if an error occurs.
|
* @throws LoginException if an error occurs.
|
||||||
*/
|
*/
|
||||||
|
|
@ -205,7 +216,8 @@ public class UserContext {
|
||||||
throw new LoginException("This user is currently banned");
|
throw new LoginException("This user is currently banned");
|
||||||
}
|
}
|
||||||
|
|
||||||
PermissionDescriptor superuser = new PermissionDescriptor(PrivilegeDescriptor.ADMIN, target,
|
PermissionDescriptor superuser = new PermissionDescriptor(
|
||||||
|
PrivilegeDescriptor.ADMIN, target,
|
||||||
user);
|
user);
|
||||||
|
|
||||||
if (!PermissionService.checkPermission(superuser)) {
|
if (!PermissionService.checkPermission(superuser)) {
|
||||||
|
|
@ -214,14 +226,16 @@ public class UserContext {
|
||||||
+ " failed to log in as user "
|
+ " failed to log in as user "
|
||||||
+ target.getID()
|
+ target.getID()
|
||||||
+ " due to insufficient privileges");
|
+ " due to insufficient privileges");
|
||||||
throw new FailedLoginException("insufficient privileges to become target user");
|
throw new FailedLoginException(
|
||||||
|
"insufficient privileges to become target user");
|
||||||
}
|
}
|
||||||
|
|
||||||
// set the target user ID in the Subject and login
|
// set the target user ID in the Subject and login
|
||||||
Subject subject = new Subject();
|
Subject subject = new Subject();
|
||||||
subject.getPrincipals().add(new PartyPrincipal(target.getID()));
|
subject.getPrincipals().add(new PartyPrincipal(target.getID()));
|
||||||
CallbackHandler handler = new RequestCallbackHandler();
|
CallbackHandler handler = new RequestCallbackHandler();
|
||||||
LoginContext context = new LoginContext(REQUEST_LOGIN_CONTEXT, subject, handler);
|
LoginContext context = new LoginContext(REQUEST_LOGIN_CONTEXT, subject,
|
||||||
|
handler);
|
||||||
clearValues();
|
clearValues();
|
||||||
context.login();
|
context.login();
|
||||||
loadValues(context.getSubject());
|
loadValues(context.getSubject());
|
||||||
|
|
@ -241,7 +255,8 @@ public class UserContext {
|
||||||
/**
|
/**
|
||||||
* Determines whether the user is logged in.
|
* Determines whether the user is logged in.
|
||||||
*
|
*
|
||||||
* @return <code>true</code> if the user is logged in, <code>false</code> otherwise.
|
* @return <code>true</code> if the user is logged in, <code>false</code>
|
||||||
|
* otherwise.
|
||||||
*/
|
*/
|
||||||
public boolean isLoggedIn() {
|
public boolean isLoggedIn() {
|
||||||
return (m_userID != null);
|
return (m_userID != null);
|
||||||
|
|
@ -250,7 +265,8 @@ public class UserContext {
|
||||||
/**
|
/**
|
||||||
* Determines whether the user is recovering a forgotten password.
|
* Determines whether the user is recovering a forgotten password.
|
||||||
*
|
*
|
||||||
* @return <code>true</code> if the user is recovering, <code>false</code> otherwise.
|
* @return <code>true</code> if the user is recovering, <code>false</code>
|
||||||
|
* otherwise.
|
||||||
*/
|
*/
|
||||||
public boolean isRecovering() {
|
public boolean isRecovering() {
|
||||||
return m_recovering;
|
return m_recovering;
|
||||||
|
|
@ -266,7 +282,8 @@ public class UserContext {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the set of all possible URL params used by UserContext. Package-private.
|
* Returns the set of all possible URL params used by UserContext.
|
||||||
|
* Package-private.
|
||||||
*
|
*
|
||||||
* @return an unmodifiable set of bebop ParameterModels.
|
* @return an unmodifiable set of bebop ParameterModels.
|
||||||
*/
|
*/
|
||||||
|
|
@ -274,7 +291,8 @@ public class UserContext {
|
||||||
try {
|
try {
|
||||||
// LoginModules add ParameterModels to Subject in initialize()
|
// LoginModules add ParameterModels to Subject in initialize()
|
||||||
LoginContext context = new LoginContext(REQUEST_LOGIN_CONTEXT);
|
LoginContext context = new LoginContext(REQUEST_LOGIN_CONTEXT);
|
||||||
return Collections.unmodifiableSet(context.getSubject().getPublicCredentials(
|
return Collections.unmodifiableSet(context.getSubject()
|
||||||
|
.getPublicCredentials(
|
||||||
ParameterModel.class));
|
ParameterModel.class));
|
||||||
} catch (LoginException e) {
|
} catch (LoginException e) {
|
||||||
throw new UncheckedWrapperException("Could not load context", e);
|
throw new UncheckedWrapperException("Could not load context", e);
|
||||||
|
|
@ -296,10 +314,12 @@ public class UserContext {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns a User object for the current user. Subsequent calls to this method return references
|
* Returns a User object for the current user. Subsequent calls to this
|
||||||
* to the same User object until the <code>logout</code> method is called.
|
* method return references to the same User object until the
|
||||||
|
* <code>logout</code> method is called.
|
||||||
*
|
*
|
||||||
* @return the User object for the logged in user or null if the user is not found.
|
* @return the User object for the logged in user or null if the user is not
|
||||||
|
* found.
|
||||||
*
|
*
|
||||||
* @throws IllegalStateException if the user is not logged in.
|
* @throws IllegalStateException if the user is not logged in.
|
||||||
*/
|
*/
|
||||||
|
|
@ -321,10 +341,11 @@ public class UserContext {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Logs in the user from data in the current request. Checks the session ID using
|
* Logs in the user from data in the current request. Checks the session ID
|
||||||
* <code>SessionContext</code>.
|
* using <code>SessionContext</code>.
|
||||||
*
|
*
|
||||||
* @throws RedirectException if the user should be redirected to the login page.
|
* @throws RedirectException if the user should be redirected to the login
|
||||||
|
* page.
|
||||||
*/
|
*/
|
||||||
private void login()
|
private void login()
|
||||||
throws RedirectException {
|
throws RedirectException {
|
||||||
|
|
@ -333,7 +354,8 @@ public class UserContext {
|
||||||
boolean success = false;
|
boolean success = false;
|
||||||
try {
|
try {
|
||||||
// log in user from request parameters
|
// log in user from request parameters
|
||||||
LoginContext context = new LoginContext(REQUEST_LOGIN_CONTEXT, handler);
|
LoginContext context = new LoginContext(REQUEST_LOGIN_CONTEXT,
|
||||||
|
handler);
|
||||||
clearValues();
|
clearValues();
|
||||||
context.login();
|
context.login();
|
||||||
loadValues(context.getSubject());
|
loadValues(context.getSubject());
|
||||||
|
|
@ -404,7 +426,8 @@ public class UserContext {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
m_username = userpass.substring(0, colon);
|
m_username = userpass.substring(0, colon);
|
||||||
m_password = userpass.substring(colon + 1, userpass.length()).toCharArray();
|
m_password = userpass.substring(colon + 1, userpass.length())
|
||||||
|
.toCharArray();
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
throw new UncheckedWrapperException(e);
|
throw new UncheckedWrapperException(e);
|
||||||
}
|
}
|
||||||
|
|
@ -417,10 +440,12 @@ public class UserContext {
|
||||||
for (int i = 0; i < callbacks.length; i++) {
|
for (int i = 0; i < callbacks.length; i++) {
|
||||||
Callback cb = callbacks[i];
|
Callback cb = callbacks[i];
|
||||||
if (cb instanceof HTTPRequestCallback) {
|
if (cb instanceof HTTPRequestCallback) {
|
||||||
((HTTPRequestCallback) cb).setRequest(UserContext.this.m_req);
|
((HTTPRequestCallback) cb)
|
||||||
|
.setRequest(UserContext.this.m_req);
|
||||||
|
|
||||||
} else if (cb instanceof HTTPResponseCallback) {
|
} else if (cb instanceof HTTPResponseCallback) {
|
||||||
((HTTPResponseCallback) cb).setResponse(UserContext.this.m_res);
|
((HTTPResponseCallback) cb).setResponse(
|
||||||
|
UserContext.this.m_res);
|
||||||
|
|
||||||
} else if (cb instanceof LifetimeCallback) {
|
} else if (cb instanceof LifetimeCallback) {
|
||||||
((LifetimeCallback) cb).setForever(false);
|
((LifetimeCallback) cb).setForever(false);
|
||||||
|
|
@ -440,7 +465,8 @@ public class UserContext {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a URL to send the user to the login page and then return to the current page.
|
* Creates a URL to send the user to the login page and then return to the
|
||||||
|
* current page.
|
||||||
*
|
*
|
||||||
* @throws com.arsdigita.web.LoginSignal
|
* @throws com.arsdigita.web.LoginSignal
|
||||||
*/
|
*/
|
||||||
|
|
@ -449,18 +475,19 @@ public class UserContext {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Name of the request parameter that stores the URL to return to after redirecting to the login
|
* Name of the request parameter that stores the URL to return to after
|
||||||
* page.
|
* redirecting to the login page.
|
||||||
*
|
*
|
||||||
* @deprecated Use com.arsdigita.ui.login.LoginHelper.RETURN_URL_PARAM_NAME instead
|
* @deprecated Use com.arsdigita.ui.login.LoginHelper.RETURN_URL_PARAM_NAME
|
||||||
|
* instead
|
||||||
*/
|
*/
|
||||||
public final static String RETURN_URL_PARAM_NAME = "return_url";
|
public final static String RETURN_URL_PARAM_NAME = "return_url";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Encodes the given request into a return URL parameter. Returns
|
* Encodes the given request into a return URL parameter. Returns
|
||||||
* <code>URLencode(returnURL)</code> where returnURL is
|
* <code>URLencode(returnURL)</code> where returnURL is
|
||||||
* <code>returnURI?key=URLencode(val)&...</code>. The original parameter values are
|
* <code>returnURI?key=URLencode(val)&...</code>. The original parameter
|
||||||
* doubly-encoded so that they are decoded appropriately.
|
* values are doubly-encoded so that they are decoded appropriately.
|
||||||
*
|
*
|
||||||
*
|
*
|
||||||
* @param req the request to encode
|
* @param req the request to encode
|
||||||
|
|
@ -496,7 +523,8 @@ public class UserContext {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Logs in the user. Checks the session ID using <code>SessionContext</code>.
|
* Logs in the user. Checks the session ID using
|
||||||
|
* <code>SessionContext</code>.
|
||||||
*
|
*
|
||||||
* @param username the user's username
|
* @param username the user's username
|
||||||
* @param password the user's password
|
* @param password the user's password
|
||||||
|
|
@ -510,15 +538,18 @@ public class UserContext {
|
||||||
throws LoginException {
|
throws LoginException {
|
||||||
s_log.debug("START login(username, password, forever)");
|
s_log.debug("START login(username, password, forever)");
|
||||||
try {
|
try {
|
||||||
CallbackHandler handler = new LoginCallbackHandler(username, password, forever);
|
CallbackHandler handler = new LoginCallbackHandler(username,
|
||||||
LoginContext context = new LoginContext(REGISTER_LOGIN_CONTEXT, handler);
|
password, forever);
|
||||||
|
LoginContext context = new LoginContext(REGISTER_LOGIN_CONTEXT,
|
||||||
|
handler);
|
||||||
clearValues();
|
clearValues();
|
||||||
context.login();
|
context.login();
|
||||||
|
|
||||||
// We now check if the user is banned and, if so, we don't allow
|
// We now check if the user is banned and, if so, we don't allow
|
||||||
// the user to login.
|
// the user to login.
|
||||||
if (Kernel.getSecurityConfig().isUserBanOn()
|
if (Kernel.getSecurityConfig().isUserBanOn()
|
||||||
&& UserAuthentication.retrieveForLoginName(username).getUser()
|
&& UserAuthentication.retrieveForLoginName(username)
|
||||||
|
.getUser()
|
||||||
.isBanned()) {
|
.isBanned()) {
|
||||||
throw new LoginException("This user is currently banned");
|
throw new LoginException("This user is currently banned");
|
||||||
}
|
}
|
||||||
|
|
@ -533,8 +564,8 @@ public class UserContext {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Logs in the user using alternative "RegisterSSO" login context. It is expected that SSO token
|
* Logs in the user using alternative "RegisterSSO" login context. It is
|
||||||
* is present in the request
|
* expected that SSO token is present in the request
|
||||||
*
|
*
|
||||||
* @see SimpleSSOLoginModule
|
* @see SimpleSSOLoginModule
|
||||||
* @throws LoginException
|
* @throws LoginException
|
||||||
|
|
@ -560,6 +591,30 @@ public class UserContext {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Logs in the user using a SAML response (which should be available in the
|
||||||
|
* request).
|
||||||
|
* @throws javax.security.auth.login.LoginException
|
||||||
|
*/
|
||||||
|
public void loginSAML() throws LoginException {
|
||||||
|
|
||||||
|
try {
|
||||||
|
final CallbackHandler handler = new RequestCallbackHandler();
|
||||||
|
final LoginContext context = new LoginContext(
|
||||||
|
REGISTER_SAML_LOGIN_CONTEXT,
|
||||||
|
handler);
|
||||||
|
clearValues();
|
||||||
|
context.login();
|
||||||
|
|
||||||
|
loadValues(context.getSubject());
|
||||||
|
m_session.loadSessionID(handler);
|
||||||
|
s_log.debug("SUCCESS loginSAML()");
|
||||||
|
} catch (LoginException ex) {
|
||||||
|
SecurityLogger.info("register SAML login failed: ", ex);
|
||||||
|
throw ex;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Implements callbacks for interactive (register-based) login.
|
* Implements callbacks for interactive (register-based) login.
|
||||||
*/
|
*/
|
||||||
|
|
@ -597,10 +652,12 @@ public class UserContext {
|
||||||
for (int i = 0; i < callbacks.length; i++) {
|
for (int i = 0; i < callbacks.length; i++) {
|
||||||
Callback cb = callbacks[i];
|
Callback cb = callbacks[i];
|
||||||
if (cb instanceof HTTPRequestCallback) {
|
if (cb instanceof HTTPRequestCallback) {
|
||||||
((HTTPRequestCallback) cb).setRequest(UserContext.this.m_req);
|
((HTTPRequestCallback) cb)
|
||||||
|
.setRequest(UserContext.this.m_req);
|
||||||
|
|
||||||
} else if (cb instanceof HTTPResponseCallback) {
|
} else if (cb instanceof HTTPResponseCallback) {
|
||||||
((HTTPResponseCallback) cb).setResponse(UserContext.this.m_res);
|
((HTTPResponseCallback) cb).setResponse(
|
||||||
|
UserContext.this.m_res);
|
||||||
|
|
||||||
} else if (cb instanceof LifetimeCallback) {
|
} else if (cb instanceof LifetimeCallback) {
|
||||||
((LifetimeCallback) cb).setForever(m_forever);
|
((LifetimeCallback) cb).setForever(m_forever);
|
||||||
|
|
@ -639,8 +696,8 @@ public class UserContext {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Logs out the user. Clears the cached User object. Loads a new session ID using
|
* Logs out the user. Clears the cached User object. Loads a new session ID
|
||||||
* <code>SessionContext</code>.
|
* using <code>SessionContext</code>.
|
||||||
*
|
*
|
||||||
* @throws LoginException if logout fails.
|
* @throws LoginException if logout fails.
|
||||||
*/
|
*/
|
||||||
|
|
@ -657,7 +714,8 @@ public class UserContext {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Reports an unsupported callback to the debug log and throws an exception. Package-private.
|
* Reports an unsupported callback to the debug log and throws an exception.
|
||||||
|
* Package-private.
|
||||||
*
|
*
|
||||||
* @throws UnsupportedCallbackException with appropriate error message
|
* @throws UnsupportedCallbackException with appropriate error message
|
||||||
*/
|
*/
|
||||||
|
|
|
||||||
|
|
@ -75,9 +75,12 @@ import java.net.URISyntaxException;
|
||||||
*
|
*
|
||||||
* @version $Id: UserLoginForm.java 1230 2006-06-22 11:50:59Z apevec $
|
* @version $Id: UserLoginForm.java 1230 2006-06-22 11:50:59Z apevec $
|
||||||
*/
|
*/
|
||||||
public class UserLoginForm extends Form
|
public class UserLoginForm
|
||||||
implements LoginConstants, FormInitListener,
|
extends Form
|
||||||
FormValidationListener, FormProcessListener {
|
implements LoginConstants,
|
||||||
|
FormInitListener,
|
||||||
|
FormValidationListener,
|
||||||
|
FormProcessListener {
|
||||||
|
|
||||||
private static final Logger s_log
|
private static final Logger s_log
|
||||||
= Logger.getLogger(UserLoginForm.class);
|
= Logger.getLogger(UserLoginForm.class);
|
||||||
|
|
@ -91,7 +94,7 @@ public class UserLoginForm extends Form
|
||||||
private TextField m_loginName;
|
private TextField m_loginName;
|
||||||
private Password m_password;
|
private Password m_password;
|
||||||
private boolean m_autoRegistrationOn;
|
private boolean m_autoRegistrationOn;
|
||||||
private SecurityConfig securityConfig = SecurityConfig.getConfig();
|
private final SecurityConfig securityConfig = SecurityConfig.getConfig();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Default constructor delegates to a constructor which creates a LoginForm
|
* Default constructor delegates to a constructor which creates a LoginForm
|
||||||
|
|
@ -203,7 +206,8 @@ public class UserLoginForm extends Form
|
||||||
add(new Label(LoginHelper.getMessage(
|
add(new Label(LoginHelper.getMessage(
|
||||||
"login.userRegistrationForm.screenName")));
|
"login.userRegistrationForm.screenName")));
|
||||||
m_loginName = new TextField(new StringParameter(FORM_LOGIN));
|
m_loginName = new TextField(new StringParameter(FORM_LOGIN));
|
||||||
addInitListener(new ScreenNameInitListener((StringParameter) m_loginName.
|
addInitListener(new ScreenNameInitListener(
|
||||||
|
(StringParameter) m_loginName.
|
||||||
getParameterModel()));
|
getParameterModel()));
|
||||||
}
|
}
|
||||||
//m_loginName.addValidationListener(new NotNullValidationListener());
|
//m_loginName.addValidationListener(new NotNullValidationListener());
|
||||||
|
|
@ -213,6 +217,7 @@ public class UserLoginForm extends Form
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @param event
|
* @param event
|
||||||
|
*
|
||||||
* @throws FormProcessException
|
* @throws FormProcessException
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
|
|
@ -232,6 +237,9 @@ public class UserLoginForm extends Form
|
||||||
s_log.debug("SSO failed", le);
|
s_log.debug("SSO failed", le);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (securityConfig.getEnableSaml()) {
|
||||||
|
// ToDo Try SAML login via OneLogin
|
||||||
|
}
|
||||||
try {
|
try {
|
||||||
// create timestamp
|
// create timestamp
|
||||||
String value = Credential.create(FORM_TIMESTAMP,
|
String value = Credential.create(FORM_TIMESTAMP,
|
||||||
|
|
@ -248,6 +256,7 @@ public class UserLoginForm extends Form
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @param event
|
* @param event
|
||||||
|
*
|
||||||
* @throws FormProcessException
|
* @throws FormProcessException
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
|
|
@ -274,7 +283,8 @@ public class UserLoginForm extends Form
|
||||||
s_log.info("Invalid credential");
|
s_log.info("Invalid credential");
|
||||||
|
|
||||||
final String path = LoginServlet.getLoginExpiredPageURL();
|
final String path = LoginServlet.getLoginExpiredPageURL();
|
||||||
final URL url = com.arsdigita.web.URL.there(state.getRequest(),
|
final URL url = com.arsdigita.web.URL.there(state
|
||||||
|
.getRequest(),
|
||||||
path);
|
path);
|
||||||
|
|
||||||
throw new RedirectSignal(url, false);
|
throw new RedirectSignal(url, false);
|
||||||
|
|
@ -295,8 +305,10 @@ public class UserLoginForm extends Form
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @param event
|
* @param event
|
||||||
|
*
|
||||||
* @throws FormProcessException
|
* @throws FormProcessException
|
||||||
*/
|
*/
|
||||||
|
@Override
|
||||||
public void process(FormSectionEvent event) throws FormProcessException {
|
public void process(FormSectionEvent event) throws FormProcessException {
|
||||||
s_log.debug("In process");
|
s_log.debug("In process");
|
||||||
|
|
||||||
|
|
@ -323,7 +335,9 @@ public class UserLoginForm extends Form
|
||||||
if (refererURI.equals("/ccm/register/")) {
|
if (refererURI.equals("/ccm/register/")) {
|
||||||
|
|
||||||
final String path = UI.getRootPageURL(req);
|
final String path = UI.getRootPageURL(req);
|
||||||
throw new RedirectSignal(com.arsdigita.web.URL.there(req, path), true);
|
throw new RedirectSignal(com.arsdigita.web.URL.there(req,
|
||||||
|
path),
|
||||||
|
true);
|
||||||
}
|
}
|
||||||
throw new ReturnSignal(req, refererURI);
|
throw new ReturnSignal(req, refererURI);
|
||||||
} catch (URISyntaxException e) {
|
} catch (URISyntaxException e) {
|
||||||
|
|
@ -341,6 +355,7 @@ public class UserLoginForm extends Form
|
||||||
* onBadPassword, onAccountNotFound, onLoginException).
|
* onBadPassword, onAccountNotFound, onLoginException).
|
||||||
*
|
*
|
||||||
* @param event
|
* @param event
|
||||||
|
*
|
||||||
* @throws FormProcessException if there is an unexpected login error
|
* @throws FormProcessException if there is an unexpected login error
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
@ -382,6 +397,7 @@ public class UserLoginForm extends Form
|
||||||
* Executed when login succeeds. Default implementation does nothing.
|
* Executed when login succeeds. Default implementation does nothing.
|
||||||
*
|
*
|
||||||
* @param event
|
* @param event
|
||||||
|
*
|
||||||
* @throws com.arsdigita.bebop.FormProcessException
|
* @throws com.arsdigita.bebop.FormProcessException
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
@ -394,6 +410,7 @@ public class UserLoginForm extends Form
|
||||||
*
|
*
|
||||||
* @param event
|
* @param event
|
||||||
* @param e
|
* @param e
|
||||||
|
*
|
||||||
* @throws FormProcessException
|
* @throws FormProcessException
|
||||||
*/
|
*/
|
||||||
protected void onBadPassword(FormSectionEvent event,
|
protected void onBadPassword(FormSectionEvent event,
|
||||||
|
|
@ -409,6 +426,7 @@ public class UserLoginForm extends Form
|
||||||
*
|
*
|
||||||
* @param event
|
* @param event
|
||||||
* @param e
|
* @param e
|
||||||
|
*
|
||||||
* @throws com.arsdigita.bebop.FormProcessException
|
* @throws com.arsdigita.bebop.FormProcessException
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
@ -460,8 +478,9 @@ public class UserLoginForm extends Form
|
||||||
* Determines whether a persistent cookie is requested in the given form.
|
* Determines whether a persistent cookie is requested in the given form.
|
||||||
*
|
*
|
||||||
* @return true if the specified formdata has a field named
|
* @return true if the specified formdata has a field named
|
||||||
* FORM_PERSISTENT_LOGIN_P whose value is equal to "1". If there is no such
|
* FORM_PERSISTENT_LOGIN_P whose value is equal to "1". If there is
|
||||||
* field in the form data, returns the specified default value.
|
* no such field in the form data, returns the specified default
|
||||||
|
* value.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
protected boolean getPersistentLoginValue(PageState state,
|
protected boolean getPersistentLoginValue(PageState state,
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue