SAML Login Form

git-svn-id: https://svn.libreccm.org/ccm/trunk@6169 8810af33-2d31-482b-a856-94f89814c4df
master
jensp 2019-08-29 10:00:32 +00:00
parent 6e856be184
commit 1f30540fb1
5 changed files with 321 additions and 107 deletions

View File

@ -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 <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
*/
public final class OneLoginUtil {
private OneLoginUtil() {
// Nothing
}
public static Saml2Settings buildSettings(
final HttpServletRequest request) {
final SecurityConfig securityConfig = SecurityConfig.getConfig();
final Map<String, Object> 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();
}
}

View File

@ -55,13 +55,15 @@ public class SamlLoginModule implements LoginModule {
@Override @Override
public boolean login() throws LoginException { public boolean login() throws LoginException {
final HttpServletRequest request = getRequest(); final HttpServletRequest httpRequest = getRequest();
final HttpServletResponse response = getResponse(); final HttpServletResponse httpResponse = getResponse();
final Auth auth; final Auth auth;
try { try {
auth = new Auth(request, response); auth = new Auth(OneLoginUtil.buildSettings(httpRequest),
} catch (IOException | SettingsException | Error ex) { httpRequest,
httpResponse);
} catch (SettingsException ex) {
LOGGER.error("SAML Login failed.", ex); LOGGER.error("SAML Login failed.", ex);
throw new LoginException("SAML Login failed. Configuration error?"); throw new LoginException("SAML Login failed. Configuration error?");
} }
@ -85,7 +87,7 @@ public class SamlLoginModule implements LoginModule {
@Override @Override
public boolean commit() throws LoginException { public boolean commit() throws LoginException {
if (userId != null) { if (userId != null) {
subject.getPrincipals().add(new PartyPrincipal(userId)); subject.getPrincipals().add(new PartyPrincipal(userId));
} }
@ -99,7 +101,7 @@ public class SamlLoginModule implements LoginModule {
@Override @Override
public boolean logout() throws LoginException { public boolean logout() throws LoginException {
getRequest().getSession().invalidate(); getRequest().getSession().invalidate();
return true; 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 { throws LoginException {
try { try {
final UserAuthentication userAuth = UserAuthentication final UserAuthentication userAuth = UserAuthentication
.retrieveForSSOlogin(ssoLogin); .retrieveForSSOlogin(ssoLogin);
return userAuth.getUser().getID(); return userAuth.getUser().getID();
} catch(DataObjectNotFoundException ex) { } catch (DataObjectNotFoundException ex) {
throw new FailedLoginException( throw new FailedLoginException(
String.format("SSO login %s not found", ssoLogin) String.format("SSO login %s not found", ssoLogin)
); );
} }
} }
} }

View File

@ -151,21 +151,21 @@ public class SecurityConfig extends AbstractConfig {
"waf.onelogin.saml2.sp.entityid", "waf.onelogin.saml2.sp.entityid",
Parameter.REQUIRED, Parameter.REQUIRED,
"http://localhost:8080/ccm-saml/metadata"); "http://localhost:8080/ccm-saml/metadata");
private final Parameter m_oneLoginSaml2SpAssertationConsumerServiceUrl // private final Parameter m_oneLoginSaml2SpAssertationConsumerServiceUrl
= new StringParameter( // = new StringParameter(
"waf.onelogin.saml2.sp.assertion_consumer_service.url", // "waf.onelogin.saml2.sp.assertion_consumer_service.url",
Parameter.REQUIRED, // Parameter.REQUIRED,
"http://localhost:8080/ccm-saml/acs"); // "http://localhost:8080/ccm-saml/acs");
private final Parameter m_oneLoginSaml2SpAssertationConsumerServiceBinding private final Parameter m_oneLoginSaml2SpAssertationConsumerServiceBinding
= new StringParameter( = new StringParameter(
"waf.onelogin.saml2.sp.assertion_consumer_service.binding", "waf.onelogin.saml2.sp.assertion_consumer_service.binding",
Parameter.REQUIRED, Parameter.REQUIRED,
"urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST"); "urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST");
private final Parameter m_oneLoginSaml2SpSingleLogoutServiceUrl // private final Parameter m_oneLoginSaml2SpSingleLogoutServiceUrl
= new StringParameter( // = new StringParameter(
"waf.onelogin.saml2.sp.single_logout_service.url", // "waf.onelogin.saml2.sp.single_logout_service.url",
Parameter.REQUIRED, // Parameter.REQUIRED,
"http://localhost:8080/ccm-saml/sls"); // "http://localhost:8080/ccm-saml/sls");
private final Parameter m_oneLoginSaml2SpSingleLogoutServiceBinding private final Parameter m_oneLoginSaml2SpSingleLogoutServiceBinding
= new StringParameter( = new StringParameter(
"waf.onelogin.saml2.sp.single_logout_service.binding", "waf.onelogin.saml2.sp.single_logout_service.binding",
@ -232,11 +232,11 @@ public class SecurityConfig extends AbstractConfig {
register(m_oneLoginSaml2IdpSingleSignOnServiceBinding); register(m_oneLoginSaml2IdpSingleSignOnServiceBinding);
register(m_oneLoginSaml2IdpSingleSignOnServiceUrl); register(m_oneLoginSaml2IdpSingleSignOnServiceUrl);
register(m_oneLoginSaml2SpAssertationConsumerServiceBinding); register(m_oneLoginSaml2SpAssertationConsumerServiceBinding);
register(m_oneLoginSaml2SpAssertationConsumerServiceUrl); // register(m_oneLoginSaml2SpAssertationConsumerServiceUrl);
register(m_oneLoginSaml2SpEntityId); register(m_oneLoginSaml2SpEntityId);
register(m_oneLoginSaml2SpNameIdFormat); register(m_oneLoginSaml2SpNameIdFormat);
register(m_oneLoginSaml2SpSingleLogoutServiceBinding); register(m_oneLoginSaml2SpSingleLogoutServiceBinding);
register(m_oneLoginSaml2SpSingleLogoutServiceUrl); // register(m_oneLoginSaml2SpSingleLogoutServiceUrl);
register(m_oneLoginSaml2Strict); register(m_oneLoginSaml2Strict);
loadInfo(); loadInfo();
@ -339,25 +339,25 @@ public class SecurityConfig extends AbstractConfig {
return (Boolean) get(m_oneLoginSaml2Strict); return (Boolean) get(m_oneLoginSaml2Strict);
} }
public final Boolean getM_oneLoginSaml2Debug() { public final Boolean getOneLoginSaml2Debug() {
return (boolean) get(m_oneLoginSaml2Debug); return (boolean) get(m_oneLoginSaml2Debug);
} }
public final String getM_oneLoginSaml2SpEntityId() { public final String getOneLoginSaml2SpEntityId() {
return (String) get(m_oneLoginSaml2SpEntityId); return (String) get(m_oneLoginSaml2SpEntityId);
} }
public final String getOneLoginSaml2SpAssertationConsumerServiceUrl() { // public final String getOneLoginSaml2SpAssertationConsumerServiceUrl() {
return (String) get(m_oneLoginSaml2SpAssertationConsumerServiceUrl); // return (String) get(m_oneLoginSaml2SpAssertationConsumerServiceUrl);
} // }
public final String getOneLoginSaml2SpAssertationConsumerServiceBinding() { public final String getOneLoginSaml2SpAssertationConsumerServiceBinding() {
return (String) get(m_oneLoginSaml2SpAssertationConsumerServiceBinding); return (String) get(m_oneLoginSaml2SpAssertationConsumerServiceBinding);
} }
public final String getOneLoginSaml2SpSingleLogoutServiceUrl() { // public final String getOneLoginSaml2SpSingleLogoutServiceUrl() {
return (String) get(m_oneLoginSaml2SpSingleLogoutServiceUrl); // return (String) get(m_oneLoginSaml2SpSingleLogoutServiceUrl);
} // }
public final String getOneLoginSaml2SpSingleLogoutServiceBinding() { public final String getOneLoginSaml2SpSingleLogoutServiceBinding() {
return (String) get(m_oneLoginSaml2SpSingleLogoutServiceBinding); return (String) get(m_oneLoginSaml2SpSingleLogoutServiceBinding);

View File

@ -18,6 +18,7 @@
*/ */
package com.arsdigita.ui.login; package com.arsdigita.ui.login;
import com.arsdigita.bebop.BoxPanel;
import com.arsdigita.bebop.Component; import com.arsdigita.bebop.Component;
import com.arsdigita.bebop.ElementComponent; import com.arsdigita.bebop.ElementComponent;
import com.arsdigita.bebop.Label; import com.arsdigita.bebop.Label;
@ -31,6 +32,7 @@ import com.arsdigita.bebop.page.BebopApplicationServlet;
import com.arsdigita.dispatcher.DispatcherConfig; import com.arsdigita.dispatcher.DispatcherConfig;
import com.arsdigita.dispatcher.DispatcherHelper; import com.arsdigita.dispatcher.DispatcherHelper;
import com.arsdigita.kernel.Kernel; import com.arsdigita.kernel.Kernel;
import com.arsdigita.kernel.security.SecurityConfig;
import com.arsdigita.ui.UI; import com.arsdigita.ui.UI;
import com.arsdigita.web.ReturnSignal; import com.arsdigita.web.ReturnSignal;
import com.arsdigita.web.URL; import com.arsdigita.web.URL;
@ -41,15 +43,16 @@ import javax.servlet.http.HttpServletRequest;
import org.apache.log4j.Logger; import org.apache.log4j.Logger;
/** /**
* Login Application Servlet class, central entry point to create and process the Login application * Login Application Servlet class, central entry point to create and process
* UI. * the Login application UI.
* *
* It manages user registration page, new user page, user workspace, logout, and permissions admin * It manages user registration page, new user page, user workspace, logout, and
* pages. * permissions admin pages.
* *
* It just defines a mapping URL <-> various pages and uses the super class to actually server the * It just defines a mapping URL <-> various pages and uses the super class to
* pages. Additionally is provides service methods to expose various properties, especially the * actually server the pages. Additionally is provides service methods to expose
* URL's of public subpages (e.g. logout) and initializes the creation of the UI. * various properties, especially the URL's of public subpages (e.g. logout) and
* initializes the creation of the UI.
* *
* @author Peter Boy <pboy@barkhof.uni-bremen.de> * @author Peter Boy <pboy@barkhof.uni-bremen.de>
* @version $Id: LoginServlet.java 2161 2012-03-15 00:16:13Z pboy $ * @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. // Define various URLs to subpages of Login to manage administrative tasks.
// //////////////////////////////////////////////////////////////////////// // ////////////////////////////////////////////////////////////////////////
/** /**
* PathInfo into the Login application to access the (optional) newUser * page. Ends with "/" * PathInfo into the Login application to access the (optional) newUser *
* because it is a servlet/directory * page. Ends with "/" because it is a servlet/directory
*/ */
public static final String EDIT_USER_PROFILE_PATH_INFO = "/edit-profile/"; public static final String EDIT_USER_PROFILE_PATH_INFO = "/edit-profile/";
/** /**
* PathInfo into the Login application to access the (optional) newUser * page. Ends with "/" * PathInfo into the Login application to access the (optional) newUser *
* because it is a servlet/directory * page. Ends with "/" because it is a servlet/directory
*/ */
public static final String NEW_USER_PATH_INFO = "/new-user/"; public static final String NEW_USER_PATH_INFO = "/new-user/";
/** /**
* PathInfo into the Login application to access the (optional) newUser * page. Ends with "/" * PathInfo into the Login application to access the (optional) newUser *
* because it is a servlet/directory * 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 "/" * PathInfo into the Login application to access the (optional) newUser
* because it is a servlet/directory * 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 "/" * PathInfo into the Login application to access the (optional) newUser
* because it is a servlet/directory * 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 "/" * PathInfo into the Login application to access the (optional) newUser
* because it is a servlet/directory * page. Ends with "/" because it is a servlet/directory
*/ */
public static final String LOGIN_EXPIRED_PATH_INFO = "/login-expired/"; public static final String LOGIN_EXPIRED_PATH_INFO = "/login-expired/";
/** /**
* PathInfo into the Login application to access the (optional) newUser page. Ends with "/" * PathInfo into the Login application to access the (optional) newUser
* because it is a servlet/directory * page. Ends with "/" because it is a servlet/directory
*/ */
public static final String LOGOUT_PATH_INFO = "/logout/"; 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; 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"; 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 * @throws ServletException
*/ */
@ -135,8 +143,7 @@ public class LoginServlet extends BebopApplicationServlet {
* to a NewUserRegistrationForm or to skip. */ * to a NewUserRegistrationForm or to skip. */
put("/", put("/",
buildSimplePage("login.userRegistrationForm.title", buildSimplePage("login.userRegistrationForm.title",
new UserLoginForm(Kernel.getSecurityConfig() buildLogin(),
.isAutoRegistrationOn()),
"login")); "login"));
disableClientCaching("/"); disableClientCaching("/");
@ -159,8 +166,9 @@ public class LoginServlet extends BebopApplicationServlet {
/* Create ExplainPersistentCookiesPage and add to the page map */ /* Create ExplainPersistentCookiesPage and add to the page map */
put(EXPLAIN_PERSISTENT_COOKIES_PATH_INFO, put(EXPLAIN_PERSISTENT_COOKIES_PATH_INFO,
buildSimplePage("login.explainCookiesPage.title", buildSimplePage("login.explainCookiesPage.title",
new ElementComponent("subsite:explainPersistentCookies", new ElementComponent(
SUBSITE_NS_URI), "subsite:explainPersistentCookies",
SUBSITE_NS_URI),
"cookies")); "cookies"));
/* Create ChangeUserPasswordPage and add to the page map */ /* 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 * Check wether a custom base Page class (top-level container for all Bebop
* containersPages) is configured and return the appropriate Page. Here used (only) for * components and containersPages) is configured and return the appropriate
* UserInfo() workspace. * Page. Here used (only) for UserInfo() workspace.
* *
* @return Page to use for top-level container for all Bebop components and containersPage, null * @return Page to use for top-level container for all Bebop components and
* to use default class * containersPage, null to use default class
*/ */
private static Page checkForPageSubClass() { private static Page checkForPageSubClass() {
//check to see if there is subclass of Page defined in Config //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); Class c = Class.forName(pageClass);
p = (Page) c.newInstance(); p = (Page) c.newInstance();
} catch (Exception e) { } 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; return p;
@ -238,7 +247,8 @@ public class LoginServlet extends BebopApplicationServlet {
private static Page buildSimplePage(String title, Component body, String id) { private static Page buildSimplePage(String title, Component body, String id) {
Page page = PageFactory.buildPage(APPLICATION_NAME, Page page = PageFactory.buildPage(APPLICATION_NAME,
new Label(LoginHelper.getMessage(title)), new Label(LoginHelper
.getMessage(title)),
id); id);
page.add(body); page.add(body);
page.lock(); 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) * @return Page (login expired info)
*/ */
@ -256,11 +267,14 @@ public class LoginServlet extends BebopApplicationServlet {
new Label(LoginHelper.getMessage("login.loginExpiredPage.title")) new Label(LoginHelper.getMessage("login.loginExpiredPage.title"))
); );
page.add(new SimpleContainer() { page.add(new SimpleContainer() {
{ // constructor { // constructor
add(new Label(LoginHelper.getMessage("login.loginExpiredPage.before"))); add(new Label(LoginHelper.getMessage(
"login.loginExpiredPage.before")));
add(new DynamicLink("login.loginExpiredPage.link", add(new DynamicLink("login.loginExpiredPage.link",
Login.getLoginPageURL())); Login.getLoginPageURL()));
add(new Label(LoginHelper.getMessage("login.loginExpiredPage.after"))); add(new Label(LoginHelper.getMessage(
"login.loginExpiredPage.after")));
add(new ElementComponent("subsite:explainLoginExpired", add(new ElementComponent("subsite:explainLoginExpired",
SUBSITE_NS_URI)); SUBSITE_NS_URI));
} }
@ -281,6 +295,7 @@ public class LoginServlet extends BebopApplicationServlet {
); );
page.addActionListener(new UserLogoutListener()); page.addActionListener(new UserLogoutListener());
page.addActionListener(new ActionListener() { page.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent event) { public void actionPerformed(ActionEvent event) {
final PageState state = event.getPageState(); final PageState state = event.getPageState();
@ -297,14 +312,37 @@ public class LoginServlet extends BebopApplicationServlet {
return page; 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 * Provides an (absolute) URL to a user profile editig page. It is relative
* without any constant prefix if there is one configured. * 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 * XXX This implementation starts with a leading slash and ends with a
* configurations String urls began without a slash in order to be able to provide a full URL * slash. In previous configurations String urls began without a slash in
* which also contains the context part. Since version 5.2 the context part is handled by (new) * order to be able to provide a full URL which also contains the context
* dispatcher. The leading slash it API change! It's impacts have to be checked. (2011-02) * 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 * @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 * Provides an (absolute URL) to an optional new user registration page
* activated). It is relative to document root without any constant prefix if there is one * (accessible only if activated). It is relative to document root without
* configured. * any constant prefix if there is one configured.
* *
* XXX This implementation starts with a leading slash and ends with a slash. In previous * XXX This implementation starts with a leading slash and ends with a
* configurations String urls began without a slash in order to be able to provide a full URL * slash. In previous configurations String urls began without a slash in
* which also contains the context part. Since version 5.2 the context part is handled by (new) * order to be able to provide a full URL which also contains the context
* dispatcher. The leading slash it API change! It's impacts have to be checked. (2011-02) * 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 * @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 * Provides an absolute URL (leading slash) for a password recovery page. It
* document root without any constant prefix if there is one configured. * 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 * XXX This implementation starts with a leading slash and ends with a
* configurations String urls began without a slash in order to be able to provide a full URL * slash. In previous configurations String urls began without a slash in
* which also contains the context part. Since version 5.2 the context part is handled by (new) * order to be able to provide a full URL which also contains the context
* dispatcher. The leading slash it API change! It's impacts have tp be checked. (2011-02) * 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 * @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 * Provides an absolute URL (leading slash) for a cookie explanation page.
* document root without any constant prefix if there is one configured. * 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 * XXX This implementation starts with a leading slash and ends with a
* configurations String urls began without a slash in order to be able to provide a full URL * slash. In previous configurations String urls began without a slash in
* which also contains the context part. Since version 5.2 the context part is handled by (new) * order to be able to provide a full URL which also contains the context
* dispatcher. The leading slash it API change! It's impacts have tp be checked. (2011-02) * 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 * @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 * Provides an absolute URL (leading slash) for a login expired info page.
* document root without any constant prefix if there is one configured. * 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 * XXX This implementation starts with a leading slash and ends with a
* configurations String urls began without a slash in order to be able to provide a full URL * slash. In previous configurations String urls began without a slash in
* which also contains the context part. Since version 5.2 the context part is handled by (new) * order to be able to provide a full URL which also contains the context
* dispatcher. The leading slash it API change! It's impacts have tp be checked. (2011-02) * 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 * @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 * Provides an absolute URL (leading slash) for the system logout page. It
* document root without any constant prefix if there is one configured. * 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 * XXX This implementation starts with a leading slash and ends with a
* configurations String urls began without a slash in order to be able to provide a full URL * slash. In previous configurations String urls began without a slash in
* which also contains the context part. Since version 5.2 the context part is handled by (new) * order to be able to provide a full URL which also contains the context
* dispatcher. The leading slash it API change! It's impacts have tp be checked. (2011-02) * 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 * @return URL for logout page as String
*/ */

View File

@ -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 <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
*/
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);
}
}
}
}