package org.dcache.webadmin.view.pages.login; import org.apache.wicket.PageReference; import org.apache.wicket.Session; import org.apache.wicket.authentication.IAuthenticationStrategy; import org.apache.wicket.markup.html.WebMarkupContainer; import org.apache.wicket.markup.html.basic.Label; import org.apache.wicket.markup.html.form.Button; import org.apache.wicket.markup.html.form.CheckBox; import org.apache.wicket.markup.html.form.PasswordTextField; import org.apache.wicket.markup.html.form.StatelessForm; import org.apache.wicket.markup.html.form.TextField; import org.apache.wicket.markup.html.panel.FeedbackPanel; import org.apache.wicket.model.CompoundPropertyModel; import org.apache.wicket.protocol.http.servlet.ServletWebRequest; import org.apache.wicket.protocol.https.RequireHttps; import org.apache.wicket.request.cycle.RequestCycle; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import javax.servlet.http.HttpServletRequest; import java.security.cert.X509Certificate; import org.dcache.webadmin.controller.LogInService; import org.dcache.webadmin.controller.exceptions.LogInServiceException; import org.dcache.webadmin.view.beans.LogInBean; import org.dcache.webadmin.view.beans.UserBean; import org.dcache.webadmin.view.beans.WebAdminInterfaceSession; import org.dcache.webadmin.view.pages.basepage.BasePage; import org.dcache.webadmin.view.util.DefaultFocusBehaviour; /** * Contains all the page construction and logic for servicing a login * request, but may be extended to return to a referring page * by overriding the #getReferrer() method. * * @author arossi */ @RequireHttps public class LogIn extends BasePage { private static final String X509_CERTIFICATE_ATTRIBUTE = "javax.servlet.request.X509Certificate"; private static final Logger _log = LoggerFactory.getLogger(LogIn.class); private static final long serialVersionUID = 8902191632839916396L; private class LogInForm extends StatelessForm { private class CertSignInButton extends Button { private static final long serialVersionUID = 7349334961548160283L; public CertSignInButton(String id) { super(id); /* * deactivate checking of formdata for certsignin */ this.setDefaultFormProcessing(false); } @Override public void onSubmit() { try { if (!isSignedIn()) { signInWithCert(getLogInService()); } goToPage(); } catch (IllegalArgumentException ex) { error(getStringResource("noCertError")); _log.debug("no certificate provided"); } catch (LogInServiceException ex) { String cause = "unknown"; if (ex.getMessage() != null) { cause = ex.getMessage(); } error(getStringResource("loginError")); _log.debug("cert sign in error - cause {}", cause); } } } private class LogInButton extends Button { private static final long serialVersionUID = -8852712258475979167L; public LogInButton(String id) { super(id); } @Override public void onSubmit() { IAuthenticationStrategy strategy = getApplication().getSecuritySettings() .getAuthenticationStrategy(); try { if (!isSignedIn()) { signIn(_logInModel, strategy); } goToPage(); } catch (LogInServiceException ex) { strategy.remove(); String cause = "unknown"; if (ex.getMessage() != null) { cause = ex.getMessage(); } error(getStringResource("loginError") + " - cause: " + cause); _log.debug("user/pwd sign in error - cause {}", cause); } } } private static final long serialVersionUID = -1800491058587279179L; private TextField _username; private PasswordTextField _password; private CheckBox _rememberMe; private WebMarkupContainer _rememberMeRow; private LogInBean _logInModel; LogInForm(final String id) { super(id, new CompoundPropertyModel<>(new LogInBean())); _logInModel = (LogInBean) getDefaultModelObject(); _username = new TextField("username"); _username.setRequired(true); add(_username); _password = new PasswordTextField("password"); add(_password); add(new LogInButton("submit")); _rememberMeRow = new WebMarkupContainer("rememberMeRow"); add(_rememberMeRow); _rememberMe = new CheckBox("remembering"); _rememberMeRow.add(_rememberMe); Button certButton = new CertSignInButton("certsignin"); certButton.add(new DefaultFocusBehaviour()); add(certButton); } private LogInService getLogInService() { return getWebadminApplication().getLogInService(); } private boolean isSignedIn() { return getWebadminSession().isSignedIn(); } private void signIn(LogInBean model, IAuthenticationStrategy strategy) throws LogInServiceException { String username; String password; if (model != null) { username = model.getUsername(); password = model.getPassword(); } else { /* * get username and password from persistence store */ String[] data = strategy.load(); if ((data == null) || (data.length <= 1)) { throw new LogInServiceException("no username data saved"); } username = data[0]; password = data[1]; } _log.debug("username sign in, username: {}", username); UserBean user = getLogInService().authenticate(username, password.toCharArray()); getWebadminSession().setUser(user); if (model != null && model.isRemembering()) { strategy.save(username, password); } else { strategy.remove(); } } } /** * Can be overridden to return a reference. */ protected PageReference getReferrer() { return null; } protected void goToPage() { /* * Covers the redirect from admin-authz page, noop in other cases */ continueToOriginalDestination(); PageReference ref = getReferrer(); if (ref != null) { /* * Covers the user-clicking a the "Login" button. * This must be done first. */ setResponsePage(ref.getPage()); } else { /* * Covers case when user somehow jumps to login page directly */ setResponsePage(getWebadminApplication().getHomePage()); } } protected void initialize() { super.initialize(); final FeedbackPanel feedback = new FeedbackPanel("feedback"); add(new Label("dCacheInstanceName", getWebadminApplication().getDcacheName())); add(new Label("dCacheInstanceDescription", getWebadminApplication().getDcacheDescription())); add(feedback); add(new LogInForm("LogInForm")); } public static void signInWithCert(LogInService service) throws IllegalArgumentException, LogInServiceException { X509Certificate[] certChain = getCertChain(); UserBean user = service.authenticate(certChain); WebAdminInterfaceSession session = (WebAdminInterfaceSession) Session.get(); session.setUser(user); } private static X509Certificate[] getCertChain() { ServletWebRequest servletWebRequest = (ServletWebRequest) RequestCycle.get().getRequest(); HttpServletRequest request = servletWebRequest.getContainerRequest(); Object certificate = request.getAttribute(X509_CERTIFICATE_ATTRIBUTE); X509Certificate[] chain; if (certificate instanceof X509Certificate[]) { chain = (X509Certificate[]) certificate; } else { throw new IllegalArgumentException(); } return chain; } }