diff --git a/ccm-core/src/com/arsdigita/kernel/security/OneLoginUtil.java b/ccm-core/src/com/arsdigita/kernel/security/OneLoginUtil.java
new file mode 100644
index 000000000..438dc1648
--- /dev/null
+++ b/ccm-core/src/com/arsdigita/kernel/security/OneLoginUtil.java
@@ -0,0 +1,78 @@
+/*
+ * To change this license header, choose License Headers in Project Properties.
+ * To change this template file, choose Tools | Templates
+ * and open the template in the editor.
+ */
+package com.arsdigita.kernel.security;
+
+import com.arsdigita.ui.login.LoginServlet;
+import com.arsdigita.web.URL;
+
+import com.onelogin.saml2.settings.Saml2Settings;
+import com.onelogin.saml2.settings.SettingsBuilder;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import javax.servlet.http.HttpServletRequest;
+
+/**
+ * Utility functions for integrating the OneLogin SAML implementation into CCM.
+ *
+ * @see https://github.com/onelogin/java-saml
+ *
+ * @author Jens Pelzetter
+ */
+public final class OneLoginUtil {
+
+ private OneLoginUtil() {
+ // Nothing
+ }
+
+ public static Saml2Settings buildSettings(
+ final HttpServletRequest request) {
+
+ final SecurityConfig securityConfig = SecurityConfig.getConfig();
+
+ final Map settings = new HashMap<>();
+ settings.put("onelogin.saml2.strict",
+ securityConfig.getOneLoginSaml2Strict());
+ settings.put("onelogin.saml2.debug",
+ securityConfig.getOneLoginSaml2Debug());
+ settings.put("onelogin.saml2.sp.entityid",
+ securityConfig.getOneLoginSaml2SpEntityId());
+ settings.put("onelogin.saml2.sp.assertation.consumer_service.url",
+ URL.there(request, LoginServlet.APPLICATION_NAME));
+ settings.put(
+ "onelogin.saml2.sp.assertation_consumer_service.binding",
+ securityConfig.getOneLoginSaml2SpAssertationConsumerServiceBinding());
+ settings.put("onelogin.saml2.sp.single_logout_service.url",
+ URL.there(request, LoginServlet.getLogoutPageURL()));
+ settings.put(
+ "onelogin.saml2.sp.single_logout_service.binding",
+ securityConfig.getOneLoginSaml2SpSingleLogoutServiceBinding());
+ settings.put("onelogin.saml2.sp.nameidformat",
+ securityConfig.getOneLoginSaml2SpNameIdFormat());
+
+ settings.put("onelogin.saml2.idp.entityid",
+ securityConfig.getOneLoginSaml2IdpEntityId());
+ settings.put("onelogin.saml2.idp.single_sign_on_service.url",
+ securityConfig.getOneLoginSaml2IdpSingleSignOnServiceUrl());
+ settings.put("onelogin.saml2.idp.single_sign_on_service.binding",
+ securityConfig
+ .getOneLoginSaml2IdpSingleSignOnServiceBinding());
+ settings.put("onelogin.saml2.ipd.single_logout_service.url",
+ securityConfig.getOneLoginSaml2IdpSingleLogoutServiceUrl());
+ settings.put(
+ "onelogin.saml2.idp.single_logout_service.response.url",
+ securityConfig.getOneLoginSaml2IdpSingleLogoutServiceResponseUrl());
+ settings.put(
+ "onelogin.saml2.idp.single_logout_service.binding",
+ securityConfig.getOneLoginSaml2IdpSingleLogoutServiceBinding());
+
+ final SettingsBuilder builder = new SettingsBuilder();
+
+ return builder.fromValues(settings).build();
+ }
+
+}
diff --git a/ccm-core/src/com/arsdigita/kernel/security/SamlLoginModule.java b/ccm-core/src/com/arsdigita/kernel/security/SamlLoginModule.java
index 69ec6a2f7..bd0e12ca0 100644
--- a/ccm-core/src/com/arsdigita/kernel/security/SamlLoginModule.java
+++ b/ccm-core/src/com/arsdigita/kernel/security/SamlLoginModule.java
@@ -55,13 +55,15 @@ public class SamlLoginModule implements LoginModule {
@Override
public boolean login() throws LoginException {
- final HttpServletRequest request = getRequest();
- final HttpServletResponse response = getResponse();
+ final HttpServletRequest httpRequest = getRequest();
+ final HttpServletResponse httpResponse = getResponse();
final Auth auth;
try {
- auth = new Auth(request, response);
- } catch (IOException | SettingsException | Error ex) {
+ auth = new Auth(OneLoginUtil.buildSettings(httpRequest),
+ httpRequest,
+ httpResponse);
+ } catch (SettingsException ex) {
LOGGER.error("SAML Login failed.", ex);
throw new LoginException("SAML Login failed. Configuration error?");
}
@@ -85,7 +87,7 @@ public class SamlLoginModule implements LoginModule {
@Override
public boolean commit() throws LoginException {
-
+
if (userId != null) {
subject.getPrincipals().add(new PartyPrincipal(userId));
}
@@ -99,7 +101,7 @@ public class SamlLoginModule implements LoginModule {
@Override
public boolean logout() throws LoginException {
-
+
getRequest().getSession().invalidate();
return true;
}
@@ -132,18 +134,19 @@ public class SamlLoginModule implements LoginModule {
}
}
- protected BigDecimal getUserId(final String ssoLogin)
+ protected BigDecimal getUserId(final String ssoLogin)
throws LoginException {
-
+
try {
final UserAuthentication userAuth = UserAuthentication
.retrieveForSSOlogin(ssoLogin);
-
+
return userAuth.getUser().getID();
- } catch(DataObjectNotFoundException ex) {
+ } catch (DataObjectNotFoundException ex) {
throw new FailedLoginException(
String.format("SSO login %s not found", ssoLogin)
);
}
}
+
}
diff --git a/ccm-core/src/com/arsdigita/kernel/security/SecurityConfig.java b/ccm-core/src/com/arsdigita/kernel/security/SecurityConfig.java
index 9de959e08..9a2dea80e 100755
--- a/ccm-core/src/com/arsdigita/kernel/security/SecurityConfig.java
+++ b/ccm-core/src/com/arsdigita/kernel/security/SecurityConfig.java
@@ -151,21 +151,21 @@ public class SecurityConfig extends AbstractConfig {
"waf.onelogin.saml2.sp.entityid",
Parameter.REQUIRED,
"http://localhost:8080/ccm-saml/metadata");
- private final Parameter m_oneLoginSaml2SpAssertationConsumerServiceUrl
- = new StringParameter(
- "waf.onelogin.saml2.sp.assertion_consumer_service.url",
- Parameter.REQUIRED,
- "http://localhost:8080/ccm-saml/acs");
+// private final Parameter m_oneLoginSaml2SpAssertationConsumerServiceUrl
+// = new StringParameter(
+// "waf.onelogin.saml2.sp.assertion_consumer_service.url",
+// Parameter.REQUIRED,
+// "http://localhost:8080/ccm-saml/acs");
private final Parameter m_oneLoginSaml2SpAssertationConsumerServiceBinding
= new StringParameter(
"waf.onelogin.saml2.sp.assertion_consumer_service.binding",
Parameter.REQUIRED,
"urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST");
- private final Parameter m_oneLoginSaml2SpSingleLogoutServiceUrl
- = new StringParameter(
- "waf.onelogin.saml2.sp.single_logout_service.url",
- Parameter.REQUIRED,
- "http://localhost:8080/ccm-saml/sls");
+// private final Parameter m_oneLoginSaml2SpSingleLogoutServiceUrl
+// = new StringParameter(
+// "waf.onelogin.saml2.sp.single_logout_service.url",
+// Parameter.REQUIRED,
+// "http://localhost:8080/ccm-saml/sls");
private final Parameter m_oneLoginSaml2SpSingleLogoutServiceBinding
= new StringParameter(
"waf.onelogin.saml2.sp.single_logout_service.binding",
@@ -232,11 +232,11 @@ public class SecurityConfig extends AbstractConfig {
register(m_oneLoginSaml2IdpSingleSignOnServiceBinding);
register(m_oneLoginSaml2IdpSingleSignOnServiceUrl);
register(m_oneLoginSaml2SpAssertationConsumerServiceBinding);
- register(m_oneLoginSaml2SpAssertationConsumerServiceUrl);
+// register(m_oneLoginSaml2SpAssertationConsumerServiceUrl);
register(m_oneLoginSaml2SpEntityId);
register(m_oneLoginSaml2SpNameIdFormat);
register(m_oneLoginSaml2SpSingleLogoutServiceBinding);
- register(m_oneLoginSaml2SpSingleLogoutServiceUrl);
+// register(m_oneLoginSaml2SpSingleLogoutServiceUrl);
register(m_oneLoginSaml2Strict);
loadInfo();
@@ -339,25 +339,25 @@ public class SecurityConfig extends AbstractConfig {
return (Boolean) get(m_oneLoginSaml2Strict);
}
- public final Boolean getM_oneLoginSaml2Debug() {
+ public final Boolean getOneLoginSaml2Debug() {
return (boolean) get(m_oneLoginSaml2Debug);
}
- public final String getM_oneLoginSaml2SpEntityId() {
+ public final String getOneLoginSaml2SpEntityId() {
return (String) get(m_oneLoginSaml2SpEntityId);
}
- public final String getOneLoginSaml2SpAssertationConsumerServiceUrl() {
- return (String) get(m_oneLoginSaml2SpAssertationConsumerServiceUrl);
- }
+// public final String getOneLoginSaml2SpAssertationConsumerServiceUrl() {
+// return (String) get(m_oneLoginSaml2SpAssertationConsumerServiceUrl);
+// }
public final String getOneLoginSaml2SpAssertationConsumerServiceBinding() {
return (String) get(m_oneLoginSaml2SpAssertationConsumerServiceBinding);
}
- public final String getOneLoginSaml2SpSingleLogoutServiceUrl() {
- return (String) get(m_oneLoginSaml2SpSingleLogoutServiceUrl);
- }
+// public final String getOneLoginSaml2SpSingleLogoutServiceUrl() {
+// return (String) get(m_oneLoginSaml2SpSingleLogoutServiceUrl);
+// }
public final String getOneLoginSaml2SpSingleLogoutServiceBinding() {
return (String) get(m_oneLoginSaml2SpSingleLogoutServiceBinding);
diff --git a/ccm-core/src/com/arsdigita/ui/login/LoginServlet.java b/ccm-core/src/com/arsdigita/ui/login/LoginServlet.java
index 352bf7621..ed35fbb2b 100644
--- a/ccm-core/src/com/arsdigita/ui/login/LoginServlet.java
+++ b/ccm-core/src/com/arsdigita/ui/login/LoginServlet.java
@@ -18,6 +18,7 @@
*/
package com.arsdigita.ui.login;
+import com.arsdigita.bebop.BoxPanel;
import com.arsdigita.bebop.Component;
import com.arsdigita.bebop.ElementComponent;
import com.arsdigita.bebop.Label;
@@ -31,6 +32,7 @@ import com.arsdigita.bebop.page.BebopApplicationServlet;
import com.arsdigita.dispatcher.DispatcherConfig;
import com.arsdigita.dispatcher.DispatcherHelper;
import com.arsdigita.kernel.Kernel;
+import com.arsdigita.kernel.security.SecurityConfig;
import com.arsdigita.ui.UI;
import com.arsdigita.web.ReturnSignal;
import com.arsdigita.web.URL;
@@ -41,15 +43,16 @@ import javax.servlet.http.HttpServletRequest;
import org.apache.log4j.Logger;
/**
- * Login Application Servlet class, central entry point to create and process the Login application
- * UI.
+ * Login Application Servlet class, central entry point to create and process
+ * the Login application UI.
*
- * It manages user registration page, new user page, user workspace, logout, and permissions admin
- * pages.
+ * It manages user registration page, new user page, user workspace, logout, and
+ * permissions admin pages.
*
- * It just defines a mapping URL <-> various pages and uses the super class to actually server the
- * pages. Additionally is provides service methods to expose various properties, especially the
- * URL's of public subpages (e.g. logout) and initializes the creation of the UI.
+ * It just defines a mapping URL <-> various pages and uses the super class to
+ * actually server the pages. Additionally is provides service methods to expose
+ * various properties, especially the URL's of public subpages (e.g. logout) and
+ * initializes the creation of the UI.
*
* @author Peter Boy
* @version $Id: LoginServlet.java 2161 2012-03-15 00:16:13Z pboy $
@@ -65,49 +68,53 @@ public class LoginServlet extends BebopApplicationServlet {
// Define various URLs to subpages of Login to manage administrative tasks.
// ////////////////////////////////////////////////////////////////////////
/**
- * PathInfo into the Login application to access the (optional) newUser * page. Ends with "/"
- * because it is a servlet/directory
+ * PathInfo into the Login application to access the (optional) newUser *
+ * page. Ends with "/" because it is a servlet/directory
*/
public static final String EDIT_USER_PROFILE_PATH_INFO = "/edit-profile/";
/**
- * PathInfo into the Login application to access the (optional) newUser * page. Ends with "/"
- * because it is a servlet/directory
+ * PathInfo into the Login application to access the (optional) newUser *
+ * page. Ends with "/" because it is a servlet/directory
*/
public static final String NEW_USER_PATH_INFO = "/new-user/";
/**
- * PathInfo into the Login application to access the (optional) newUser * page. Ends with "/"
- * because it is a servlet/directory
+ * PathInfo into the Login application to access the (optional) newUser *
+ * page. Ends with "/" because it is a servlet/directory
*/
- public static final String CHANGE_USER_PASSWORD_PATH_INFO = "/change-password/";
+ public static final String CHANGE_USER_PASSWORD_PATH_INFO
+ = "/change-password/";
/**
- * PathInfo into the Login application to access the (optional) newUser page. Ends with "/"
- * because it is a servlet/directory
+ * PathInfo into the Login application to access the (optional) newUser
+ * page. Ends with "/" because it is a servlet/directory
*/
- public static final String RECOVER_USER_PASSWORD_PATH_INFO = "/recover-password/";
+ public static final String RECOVER_USER_PASSWORD_PATH_INFO
+ = "/recover-password/";
/**
- * PathInfo into the Login application to access the (optional) newUser page. Ends with "/"
- * because it is a servlet/directory
+ * PathInfo into the Login application to access the (optional) newUser
+ * page. Ends with "/" because it is a servlet/directory
*/
- public static final String EXPLAIN_PERSISTENT_COOKIES_PATH_INFO = "/explain-persistent-cookies/";
+ public static final String EXPLAIN_PERSISTENT_COOKIES_PATH_INFO
+ = "/explain-persistent-cookies/";
/**
- * PathInfo into the Login application to access the (optional) newUser page. Ends with "/"
- * because it is a servlet/directory
+ * PathInfo into the Login application to access the (optional) newUser
+ * page. Ends with "/" because it is a servlet/directory
*/
public static final String LOGIN_EXPIRED_PATH_INFO = "/login-expired/";
/**
- * PathInfo into the Login application to access the (optional) newUser page. Ends with "/"
- * because it is a servlet/directory
+ * PathInfo into the Login application to access the (optional) newUser
+ * page. Ends with "/" because it is a servlet/directory
*/
public static final String LOGOUT_PATH_INFO = "/logout/";
/**
- * Base URL of the Login application for internal use, fetched from Login domain class.
+ * Base URL of the Login application for internal use, fetched from Login
+ * domain class.
*/
private final static String s_loginURL = Login.LOGIN_PAGE_URL;
@@ -117,7 +124,8 @@ public class LoginServlet extends BebopApplicationServlet {
public static final String APPLICATION_NAME = "login";
/**
- * User extension point used to create the pages to server and setup a URL - page mapping.
+ * User extension point used to create the pages to server and setup a URL -
+ * page mapping.
*
* @throws ServletException
*/
@@ -135,8 +143,7 @@ public class LoginServlet extends BebopApplicationServlet {
* to a NewUserRegistrationForm or to skip. */
put("/",
buildSimplePage("login.userRegistrationForm.title",
- new UserLoginForm(Kernel.getSecurityConfig()
- .isAutoRegistrationOn()),
+ buildLogin(),
"login"));
disableClientCaching("/");
@@ -159,8 +166,9 @@ public class LoginServlet extends BebopApplicationServlet {
/* Create ExplainPersistentCookiesPage and add to the page map */
put(EXPLAIN_PERSISTENT_COOKIES_PATH_INFO,
buildSimplePage("login.explainCookiesPage.title",
- new ElementComponent("subsite:explainPersistentCookies",
- SUBSITE_NS_URI),
+ new ElementComponent(
+ "subsite:explainPersistentCookies",
+ SUBSITE_NS_URI),
"cookies"));
/* Create ChangeUserPasswordPage and add to the page map */
@@ -205,12 +213,12 @@ public class LoginServlet extends BebopApplicationServlet {
}
/**
- * Check wether a custom base Page class (top-level container for all Bebop components and
- * containersPages) is configured and return the appropriate Page. Here used (only) for
- * UserInfo() workspace.
+ * Check wether a custom base Page class (top-level container for all Bebop
+ * components and containersPages) is configured and return the appropriate
+ * Page. Here used (only) for UserInfo() workspace.
*
- * @return Page to use for top-level container for all Bebop components and containersPage, null
- * to use default class
+ * @return Page to use for top-level container for all Bebop components and
+ * containersPage, null to use default class
*/
private static Page checkForPageSubClass() {
//check to see if there is subclass of Page defined in Config
@@ -223,7 +231,8 @@ public class LoginServlet extends BebopApplicationServlet {
Class c = Class.forName(pageClass);
p = (Page) c.newInstance();
} catch (Exception e) {
- s_log.error("Unable to instantiate waf.dispatcher.default_page_class", e);
+ s_log.error(
+ "Unable to instantiate waf.dispatcher.default_page_class", e);
}
}
return p;
@@ -238,7 +247,8 @@ public class LoginServlet extends BebopApplicationServlet {
private static Page buildSimplePage(String title, Component body, String id) {
Page page = PageFactory.buildPage(APPLICATION_NAME,
- new Label(LoginHelper.getMessage(title)),
+ new Label(LoginHelper
+ .getMessage(title)),
id);
page.add(body);
page.lock();
@@ -246,7 +256,8 @@ public class LoginServlet extends BebopApplicationServlet {
}
/**
- * Creates a page informing the user the login has expired. Provides links to login again, etc.
+ * Creates a page informing the user the login has expired. Provides links
+ * to login again, etc.
*
* @return Page (login expired info)
*/
@@ -256,11 +267,14 @@ public class LoginServlet extends BebopApplicationServlet {
new Label(LoginHelper.getMessage("login.loginExpiredPage.title"))
);
page.add(new SimpleContainer() {
+
{ // constructor
- add(new Label(LoginHelper.getMessage("login.loginExpiredPage.before")));
+ add(new Label(LoginHelper.getMessage(
+ "login.loginExpiredPage.before")));
add(new DynamicLink("login.loginExpiredPage.link",
Login.getLoginPageURL()));
- add(new Label(LoginHelper.getMessage("login.loginExpiredPage.after")));
+ add(new Label(LoginHelper.getMessage(
+ "login.loginExpiredPage.after")));
add(new ElementComponent("subsite:explainLoginExpired",
SUBSITE_NS_URI));
}
@@ -281,6 +295,7 @@ public class LoginServlet extends BebopApplicationServlet {
);
page.addActionListener(new UserLogoutListener());
page.addActionListener(new ActionListener() {
+
public void actionPerformed(ActionEvent event) {
final PageState state = event.getPageState();
@@ -297,14 +312,37 @@ public class LoginServlet extends BebopApplicationServlet {
return page;
}
+ private Component buildLogin() {
+
+ final SecurityConfig securityConfig = SecurityConfig.getConfig();
+
+ if (SecurityConfig.getConfig().getEnableSaml()) {
+
+ final UserLoginForm userLoginForm = new UserLoginForm(
+ securityConfig.isAutoRegistrationOn());
+
+ final SamlLoginForm samlLoginForm = new SamlLoginForm();
+
+ final BoxPanel panel = new BoxPanel(BoxPanel.HORIZONTAL);
+ panel.add(samlLoginForm);
+ panel.add(userLoginForm);
+
+ return panel;
+ } else {
+ return new UserLoginForm(securityConfig.isAutoRegistrationOn());
+ }
+ }
+
/**
- * Provides an (absolute) URL to a user profile editig page. It is relative to document root
- * without any constant prefix if there is one configured.
+ * Provides an (absolute) URL to a user profile editig page. It is relative
+ * to document root without any constant prefix if there is one configured.
*
- * XXX This implementation starts with a leading slash and ends with a slash. In previous
- * configurations String urls began without a slash in order to be able to provide a full URL
- * which also contains the context part. Since version 5.2 the context part is handled by (new)
- * dispatcher. The leading slash it API change! It's impacts have to be checked. (2011-02)
+ * XXX This implementation starts with a leading slash and ends with a
+ * slash. In previous configurations String urls began without a slash in
+ * order to be able to provide a full URL which also contains the context
+ * part. Since version 5.2 the context part is handled by (new) dispatcher.
+ * The leading slash it API change! It's impacts have to be checked.
+ * (2011-02)
*
* @return url to EditUserProfile page as String
*/
@@ -317,14 +355,16 @@ public class LoginServlet extends BebopApplicationServlet {
}
/**
- * Provides an (absolute URL) to an optional new user registration page (accessible only if
- * activated). It is relative to document root without any constant prefix if there is one
- * configured.
+ * Provides an (absolute URL) to an optional new user registration page
+ * (accessible only if activated). It is relative to document root without
+ * any constant prefix if there is one configured.
*
- * XXX This implementation starts with a leading slash and ends with a slash. In previous
- * configurations String urls began without a slash in order to be able to provide a full URL
- * which also contains the context part. Since version 5.2 the context part is handled by (new)
- * dispatcher. The leading slash it API change! It's impacts have to be checked. (2011-02)
+ * XXX This implementation starts with a leading slash and ends with a
+ * slash. In previous configurations String urls began without a slash in
+ * order to be able to provide a full URL which also contains the context
+ * part. Since version 5.2 the context part is handled by (new) dispatcher.
+ * The leading slash it API change! It's impacts have to be checked.
+ * (2011-02)
*
* @return url to new user registration page as String
*/
@@ -333,13 +373,16 @@ public class LoginServlet extends BebopApplicationServlet {
}
/**
- * Provides an absolute URL (leading slash) for a password recovery page. It is relative to
- * document root without any constant prefix if there is one configured.
+ * Provides an absolute URL (leading slash) for a password recovery page. It
+ * is relative to document root without any constant prefix if there is one
+ * configured.
*
- * XXX This implementation starts with a leading slash and ends with a slash. In previous
- * configurations String urls began without a slash in order to be able to provide a full URL
- * which also contains the context part. Since version 5.2 the context part is handled by (new)
- * dispatcher. The leading slash it API change! It's impacts have tp be checked. (2011-02)
+ * XXX This implementation starts with a leading slash and ends with a
+ * slash. In previous configurations String urls began without a slash in
+ * order to be able to provide a full URL which also contains the context
+ * part. Since version 5.2 the context part is handled by (new) dispatcher.
+ * The leading slash it API change! It's impacts have tp be checked.
+ * (2011-02)
*
* @return url String for new user registration page as String
*/
@@ -348,13 +391,16 @@ public class LoginServlet extends BebopApplicationServlet {
}
/**
- * Provides an absolute URL (leading slash) for a cookie explanation page. It is relative to
- * document root without any constant prefix if there is one configured.
+ * Provides an absolute URL (leading slash) for a cookie explanation page.
+ * It is relative to document root without any constant prefix if there is
+ * one configured.
*
- * XXX This implementation starts with a leading slash and ends with a slash. In previous
- * configurations String urls began without a slash in order to be able to provide a full URL
- * which also contains the context part. Since version 5.2 the context part is handled by (new)
- * dispatcher. The leading slash it API change! It's impacts have tp be checked. (2011-02)
+ * XXX This implementation starts with a leading slash and ends with a
+ * slash. In previous configurations String urls began without a slash in
+ * order to be able to provide a full URL which also contains the context
+ * part. Since version 5.2 the context part is handled by (new) dispatcher.
+ * The leading slash it API change! It's impacts have tp be checked.
+ * (2011-02)
*
* @return url String for new user registration page as String
*/
@@ -363,13 +409,16 @@ public class LoginServlet extends BebopApplicationServlet {
}
/**
- * Provides an absolute URL (leading slash) for a login expired info page. It is relative to
- * document root without any constant prefix if there is one configured.
+ * Provides an absolute URL (leading slash) for a login expired info page.
+ * It is relative to document root without any constant prefix if there is
+ * one configured.
*
- * XXX This implementation starts with a leading slash and ends with a slash. In previous
- * configurations String urls began without a slash in order to be able to provide a full URL
- * which also contains the context part. Since version 5.2 the context part is handled by (new)
- * dispatcher. The leading slash it API change! It's impacts have tp be checked. (2011-02)
+ * XXX This implementation starts with a leading slash and ends with a
+ * slash. In previous configurations String urls began without a slash in
+ * order to be able to provide a full URL which also contains the context
+ * part. Since version 5.2 the context part is handled by (new) dispatcher.
+ * The leading slash it API change! It's impacts have tp be checked.
+ * (2011-02)
*
* @return url String for new user registration page as String
*/
@@ -378,13 +427,16 @@ public class LoginServlet extends BebopApplicationServlet {
}
/**
- * Provides an absolute URL (leading slash) for the system logout page. It is relative to
- * document root without any constant prefix if there is one configured.
+ * Provides an absolute URL (leading slash) for the system logout page. It
+ * is relative to document root without any constant prefix if there is one
+ * configured.
*
- * XXX This implementation starts with a leading slash and ends with a slash. In previous
- * configurations String urls began without a slash in order to be able to provide a full URL
- * which also contains the context part. Since version 5.2 the context part is handled by (new)
- * dispatcher. The leading slash it API change! It's impacts have tp be checked. (2011-02)
+ * XXX This implementation starts with a leading slash and ends with a
+ * slash. In previous configurations String urls began without a slash in
+ * order to be able to provide a full URL which also contains the context
+ * part. Since version 5.2 the context part is handled by (new) dispatcher.
+ * The leading slash it API change! It's impacts have tp be checked.
+ * (2011-02)
*
* @return URL for logout page as String
*/
diff --git a/ccm-core/src/com/arsdigita/ui/login/SamlLoginForm.java b/ccm-core/src/com/arsdigita/ui/login/SamlLoginForm.java
new file mode 100644
index 000000000..9f95dff16
--- /dev/null
+++ b/ccm-core/src/com/arsdigita/ui/login/SamlLoginForm.java
@@ -0,0 +1,81 @@
+/*
+ * To change this license header, choose License Headers in Project Properties.
+ * To change this template file, choose Tools | Templates
+ * and open the template in the editor.
+ */
+package com.arsdigita.ui.login;
+
+import com.arsdigita.bebop.ActionLink;
+import com.arsdigita.bebop.BoxPanel;
+import com.arsdigita.bebop.Container;
+import com.arsdigita.bebop.Form;
+import com.arsdigita.bebop.FormProcessException;
+import com.arsdigita.bebop.PageState;
+import com.arsdigita.bebop.event.ActionEvent;
+import com.arsdigita.bebop.event.ActionListener;
+import com.arsdigita.bebop.event.FormProcessListener;
+import com.arsdigita.bebop.event.FormSectionEvent;
+import com.arsdigita.bebop.form.Submit;
+import com.arsdigita.kernel.security.OneLoginUtil;
+
+import com.onelogin.saml2.Auth;
+import com.onelogin.saml2.exception.SettingsException;
+
+import java.io.IOException;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+/**
+ *
+ * @author Jens Pelzetter
+ */
+public class SamlLoginForm
+ extends Form
+ implements LoginConstants, FormProcessListener {
+
+ final static String FORM_NAME = "saml-login";
+
+ private Submit submitLogin;
+
+ public SamlLoginForm() {
+
+ this(new BoxPanel());
+ }
+
+ public SamlLoginForm(final Container panel) {
+
+ super(FORM_NAME, panel);
+ setMethod(Form.POST);
+ addProcessListener(this);
+
+ submitLogin = new Submit(
+ LoginGlobalizationUtil.globalize("login.saml.submit")
+ );
+ add(submitLogin);
+ }
+
+ @Override
+ public void process(final FormSectionEvent event)
+ throws FormProcessException {
+
+ final PageState state = event.getPageState();
+
+ if (submitLogin.isSelected(state)) {
+ final HttpServletRequest request = state.getRequest();
+ final HttpServletResponse response = state.getResponse();
+
+ try {
+ final Auth auth = new Auth(OneLoginUtil.buildSettings(request),
+ request,
+ response);
+ auth.login();
+ } catch (IOException | SettingsException ex) {
+ throw new FormProcessException(ex);
+ }
+ }
+ }
+
+}