diff options
-rw-r--r-- | dozentenmodul/pom.xml | 202 | ||||
-rw-r--r-- | dozentenmodul/src/main/java/gui/intro/Login_GUI.java | 216 | ||||
-rw-r--r-- | dozentenmodul/src/main/java/util/ShibbolethECP.java | 108 |
3 files changed, 365 insertions, 161 deletions
diff --git a/dozentenmodul/pom.xml b/dozentenmodul/pom.xml index f10f830f..21be6768 100644 --- a/dozentenmodul/pom.xml +++ b/dozentenmodul/pom.xml @@ -21,7 +21,7 @@ <name>mltk repo</name> <url>http://mltk-services.ruf.uni-freiburg.de:8081/nexus/content/repositories/snapshots/</url> </repository> - </repositories> + </repositories> <build> <plugins> @@ -77,16 +77,47 @@ <exclude>META-INF/*.RSA</exclude> </excludes> </filter> - <filter> - <artifact>log4j:*</artifact> - <includes> - <include>**</include> - </includes> - </filter> + <filter> + <artifact>log4j:*</artifact> + <includes> + <include>**</include> + </includes> + </filter> + <filter> + <artifact>commons-logging:*</artifact> + <includes> + <include>**</include> + </includes> + </filter> + <filter> + <artifact>org.opensaml:*</artifact> + <includes> + <include>**</include> + </includes> + </filter> + <filter> + <artifact>xml-apis:*</artifact> + <includes> + <include>**</include> + </includes> + </filter> + <filter> + <artifact>xalan:*</artifact> + <includes> + <include>**</include> + </includes> + </filter> + <filter> + <artifact>xerces:*</artifact> + <includes> + <include>**</include> + </includes> + </filter> </filters> <minimizeJar>true</minimizeJar> <transformers> - <transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer"> + <transformer + implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer"> <mainClass>App</mainClass> <manifestEntries> <Version-Timestamp>${maven.build.timestamp}</Version-Timestamp> @@ -98,74 +129,74 @@ </executions> </plugin> </plugins> - <resources> - <resource> - <directory>src/main/resources</directory> - <includes> - <include>**</include> - </includes> - </resource> - <resource> - <directory>src/main/properties</directory> - <includes> - <include>**/*.properties</include> - </includes> - </resource> - </resources> + <resources> + <resource> + <directory>src/main/resources</directory> + <includes> + <include>**</include> + </includes> + </resource> + <resource> + <directory>src/main/properties</directory> + <includes> + <include>**/*.properties</include> + </includes> + </resource> + </resources> </build> <profiles> - <profile> - <id>mac</id> - <activation> - <os> - <name>mac os x</name> - </os> - </activation> - <properties> - <swt.groupId>org.eclipse.swt.carbon</swt.groupId> - <swt.artifactId>macosx</swt.artifactId> - </properties> - </profile> - <profile> - <id>windows</id> - <activation> - <os> - <family>windows</family> - </os> - </activation> - <properties> - <swt.groupId>org.eclipse.swt.org.eclipse.swt.win32.win32.x86.4.3.swt</swt.groupId> - <swt.artifactId>org.eclipse.swt.win32.win32.x86</swt.artifactId> - </properties> - </profile> - <profile> - <id>linux_64</id> - <activation> - <os> - <name>linux</name> - <arch>amd64</arch> - </os> - </activation> - <properties> - <swt.groupId>org.eclipse.swt.org.eclipse.swt.gtk.linux.x86_64.4.3.swt</swt.groupId> - <swt.artifactId>org.eclipse.swt.gtk.linux.x86_64</swt.artifactId> - </properties> - </profile> - <profile> - <id>linux_32</id> - <activation> - <os> - <name>linux</name> - <arch>i386</arch> - </os> - </activation> - <properties> - <swt.groupId>org.eclipse.swt.org.eclipse.swt.gtk.linux.x86.4.3.swt</swt.groupId> - <swt.artifactId>org.eclipse.swt.gtk.linux.x86</swt.artifactId> - </properties> - </profile> - </profiles> + <profile> + <id>mac</id> + <activation> + <os> + <name>mac os x</name> + </os> + </activation> + <properties> + <swt.groupId>org.eclipse.swt.carbon</swt.groupId> + <swt.artifactId>macosx</swt.artifactId> + </properties> + </profile> + <profile> + <id>windows</id> + <activation> + <os> + <family>windows</family> + </os> + </activation> + <properties> + <swt.groupId>org.eclipse.swt.org.eclipse.swt.win32.win32.x86.4.3.swt</swt.groupId> + <swt.artifactId>org.eclipse.swt.win32.win32.x86</swt.artifactId> + </properties> + </profile> + <profile> + <id>linux_64</id> + <activation> + <os> + <name>linux</name> + <arch>amd64</arch> + </os> + </activation> + <properties> + <swt.groupId>org.eclipse.swt.org.eclipse.swt.gtk.linux.x86_64.4.3.swt</swt.groupId> + <swt.artifactId>org.eclipse.swt.gtk.linux.x86_64</swt.artifactId> + </properties> + </profile> + <profile> + <id>linux_32</id> + <activation> + <os> + <name>linux</name> + <arch>i386</arch> + </os> + </activation> + <properties> + <swt.groupId>org.eclipse.swt.org.eclipse.swt.gtk.linux.x86.4.3.swt</swt.groupId> + <swt.artifactId>org.eclipse.swt.gtk.linux.x86</swt.artifactId> + </properties> + </profile> + </profiles> <dependencies> <dependency> @@ -174,6 +205,11 @@ <version>3.5.0</version> </dependency> <dependency> + <groupId>org.apache.httpcomponents</groupId> + <artifactId>httpclient</artifactId> + <version>4.3</version> + </dependency> + <dependency> <groupId>org.apache.thrift</groupId> <artifactId>libthrift</artifactId> <version>0.9.1</version> @@ -204,14 +240,14 @@ <scope>compile</scope> </dependency> <dependency> - <groupId>${swt.groupId}</groupId> - <artifactId>${swt.artifactId}</artifactId> - <version>4.3</version> - </dependency> + <groupId>${swt.groupId}</groupId> + <artifactId>${swt.artifactId}</artifactId> + <version>4.3</version> + </dependency> <dependency> <groupId>log4j</groupId> <artifactId>log4j</artifactId> - <version>1.2.17</version> + <version>[1.2.10,1.2.20]</version> <scope>compile</scope> </dependency> <dependency> @@ -243,6 +279,16 @@ <version>3.8.1</version> <scope>test</scope> </dependency> + <dependency> + <groupId>de.tudarmstadt.ukp.shibhttpclient</groupId> + <artifactId>shib-http-client</artifactId> + <version>1.1.0-SNAPSHOT</version> + </dependency> + <dependency> + <groupId>xerces</groupId> + <artifactId>xercesImpl</artifactId> + <version>2.11.0</version> + </dependency> </dependencies> </project> diff --git a/dozentenmodul/src/main/java/gui/intro/Login_GUI.java b/dozentenmodul/src/main/java/gui/intro/Login_GUI.java index 035710e8..593c5e60 100644 --- a/dozentenmodul/src/main/java/gui/intro/Login_GUI.java +++ b/dozentenmodul/src/main/java/gui/intro/Login_GUI.java @@ -1,6 +1,6 @@ package gui.intro; -import java.awt.CardLayout; +import java.awt.Choice; import java.awt.Color; import java.awt.Component; import java.awt.Image; @@ -10,21 +10,27 @@ import java.awt.event.ActionListener; import java.awt.event.WindowAdapter; import java.awt.event.WindowEvent; import java.util.Arrays; +import java.util.List; +import java.util.concurrent.ExecutionException; import javax.swing.ButtonGroup; import javax.swing.ImageIcon; import javax.swing.JButton; import javax.swing.JCheckBox; +import javax.swing.JComboBox; import javax.swing.JFrame; import javax.swing.JLabel; import javax.swing.JOptionPane; import javax.swing.JPanel; import javax.swing.JPasswordField; +import javax.swing.JRadioButton; import javax.swing.JTextField; import javax.swing.SwingConstants; +import javax.swing.SwingWorker; import javax.swing.UIManager; import javax.swing.UnsupportedLookAndFeelException; import javax.swing.border.EmptyBorder; +import javax.swing.border.TitledBorder; import models.SessionData; import models.person; @@ -38,13 +44,9 @@ import thrift.MasterThriftConnection; import thrift.ThriftConnection; import util.GuiOrganizer; import util.ResourceLoader; +import util.ShibbolethECP; import config.Config; -import java.awt.Choice; - -import javax.swing.border.TitledBorder; -import javax.swing.JRadioButton; - @SuppressWarnings("serial") public class Login_GUI extends JFrame { @@ -81,7 +83,7 @@ public class Login_GUI extends JFrame { private ActionListener loginTypeActionListener; // bwIDM label and dropdown - private Choice choice; + private JComboBox<String> choice; private JLabel lblIdp; // Satellite IP label and text field @@ -217,8 +219,9 @@ public class Login_GUI extends JFrame { lblSatIP.setBounds(135, 110, 237, 20); lblSatIP.setToolTipText("Bitte geben Sie die IP-Adresse des Satelliten ein."); //panel.add(lblSatIP); - - choice = new Choice(); + + String organisations[] = { "https://testidp3-dev.aai.dfn.de/idp/profile/SAML2/SOAP/ECP" }; + choice = new JComboBox<String>(organisations); choice.setBounds(135, 35, 237, 20); //panel.add(choice); @@ -247,14 +250,14 @@ public class Login_GUI extends JFrame { // group radio button for the login type together bgLoginType = new ButtonGroup(); - rdbtnBwIDM = new JRadioButton("bwIDM"); + rdbtnBwIDM = new JRadioButton("Zugang über bwIDM"); rdbtnBwIDM.setBounds(32, 35, 244, 23); rdbtnBwIDM.setActionCommand(LOGIN_TYPE_BWIDM); rdbtnBwIDM.addActionListener(loginTypeActionListener); bgLoginType.add(rdbtnBwIDM); panel_1.add(rdbtnBwIDM); - rdbtnMasterserver = new JRadioButton("bwLehrpool-Masterserver"); + rdbtnMasterserver = new JRadioButton("Test-Zugang mit festem Benutzer"); rdbtnMasterserver.setSelected(true); rdbtnMasterserver.setActionCommand(LOGIN_TYPE_BWLEHRPOOL); rdbtnMasterserver.addActionListener(loginTypeActionListener); @@ -262,7 +265,7 @@ public class Login_GUI extends JFrame { bgLoginType.add(rdbtnMasterserver); panel_1.add(rdbtnMasterserver); - rdbtnDirekteVerbindung = new JRadioButton("Lokales Satellit"); + rdbtnDirekteVerbindung = new JRadioButton("Direkte Verbindung zum Satelliten"); rdbtnDirekteVerbindung.setBounds(32, 85, 244, 23); rdbtnDirekteVerbindung.setActionCommand(LOGIN_TYPE_SATLLITE); rdbtnDirekteVerbindung.addActionListener(loginTypeActionListener); @@ -281,82 +284,125 @@ public class Login_GUI extends JFrame { // Versuche den Benutzer einzuloggen public void performLogin(final String loginType) { LOGGER.info("Trying login of type: " + loginType); - org.openslx.imagemaster.thrift.iface.SessionData result = null; - // Connect to Master - MasterThriftConnection thrift = new MasterThriftConnection(); - Client client = thrift.getMasterThriftConnection(); - - if (client == null) { - // Thrift connection to master could not be established - setStatus(Color.red, "Fehler: Masterserver nicht erreichbar.", null); - LOGGER.info("Thrift client could not be initialized, is the masterserver up and running?"); - return; - } - - String passText = new String(lblpass.getPassword()); - UserInfo user = null; - // Log user in - try { - setStatus(Color.black, - "Authentifiziere - warte auf Antwort von Server...", null); - result = client.authenticate(lblusername.getText(), passText); - - // Sanity checks - if (result.authToken == null || result.sessionId == null) { - setStatus(Color.red, "Antwort des Masterservers korrupt.", null); - LOGGER.info("Antwort des Masterservers korrupt"); + if (loginType == LOGIN_TYPE_BWLEHRPOOL) { + // start the authentication process against the masterserver + org.openslx.imagemaster.thrift.iface.SessionData result = null; + // Connect to Master + MasterThriftConnection thrift = new MasterThriftConnection(); + Client client = thrift.getMasterThriftConnection(); + + if (client == null) { + // Thrift connection to master could not be established + setStatus(Color.red, "Fehler: Masterserver nicht erreichbar.", null); + LOGGER.info("Thrift client could not be initialized, is the masterserver up and running?"); return; } - // User-Info - LOGGER.info("Authentifizierung von '" + lblusername.getText() + "' erfolgreich."); - user = client.getUserFromToken(result.authToken); - - } catch (org.openslx.imagemaster.thrift.iface.AuthenticationException e) { - setStatus( - Color.red, - "Fehler: Zugangsdaten nicht akzeptiert.", - "Benutzeranmeldung fehlgeschlagen: Bitte Benutzername und Passwort überprüfen.\n" - + e.message); - e.printStackTrace(); - return; - } catch (TException e) { - setStatus(Color.red, - "Kommunikation mit Masterserver fehlgeschlagen.", - Arrays.toString(e.getStackTrace())); - return; - } - - // set Information - SessionData.session.setAuthToken(result.authToken); - SessionData.session.setSessionID(result.sessionId); - SessionData.session.setServerAdress(result.serverAddress); - - // Satellite-Connection - setStatus(Color.black, "Hole Verbindungsdaten von Server...", null); - // set connection to bwLehrpoolSuiteServer - ThriftConnection bwthrift = new ThriftConnection(); - server.generated.Server.Client bwClient = bwthrift.getThriftConnection(); - models.Client.clientcon.setClient(bwClient); - - // User-Info - LOGGER.debug("Session-ID: " + result.sessionId); - LOGGER.debug("Token: " + result.authToken); - setStatus(Color.green, "Daten erhalten.", null); + String passText = new String(lblpass.getPassword()); + UserInfo user = null; + // Log user in + try { + setStatus(Color.black, + "Authentifiziere - warte auf Antwort von Server...", null); + + result = client.authenticate(lblusername.getText(), passText); + + // Sanity checks + if (result.authToken == null || result.sessionId == null) { + setStatus(Color.red, "Antwort des Masterservers korrupt.", null); + LOGGER.info("Antwort des Masterservers korrupt"); + return; + } + + // User-Info + LOGGER.info("Authentifizierung von '" + lblusername.getText() + "' erfolgreich."); + user = client.getUserFromToken(result.authToken); + + } catch (org.openslx.imagemaster.thrift.iface.AuthenticationException e) { + setStatus( + Color.red, + "Fehler: Zugangsdaten nicht akzeptiert.", + "Benutzeranmeldung fehlgeschlagen: Bitte Benutzername und Passwort überprüfen.\n" + + e.message); + e.printStackTrace(); + return; + } catch (TException e) { + setStatus(Color.red, + "Kommunikation mit Masterserver fehlgeschlagen.", + Arrays.toString(e.getStackTrace())); + return; + } - String hochschule = user.eMail.substring(user.eMail.indexOf("@") + 1); + // set Information + SessionData.session.setAuthToken(result.authToken); + SessionData.session.setSessionID(result.sessionId); + SessionData.session.setServerAdress(result.serverAddress); - person.verantwortlicher.setUsername(lblusername.getText().trim()); - person.verantwortlicher.setUserID(lblusername.getText().trim()); - person.verantwortlicher.setName(user.lastName); - person.verantwortlicher.setVorname(user.firstName); - person.verantwortlicher.setEMail(user.eMail); - person.verantwortlicher.setHochschule(hochschule); + // Satellite-Connection + setStatus(Color.black, "Hole Verbindungsdaten von Server...", null); + // set connection to bwLehrpoolSuiteServer + ThriftConnection bwthrift = new ThriftConnection(); + server.generated.Server.Client bwClient = bwthrift.getThriftConnection(); + models.Client.clientcon.setClient(bwClient); - // Spaeter ueber result.getRole zum Beispiel die Rolle holen - person.verantwortlicher.setRole("Dozent"); + // User-Info + LOGGER.debug("Session-ID: " + result.sessionId); + LOGGER.debug("Token: " + result.authToken); + setStatus(Color.green, "Daten erhalten.", null); + + String hochschule = user.eMail.substring(user.eMail.indexOf("@") + 1); + + person.verantwortlicher.setUsername(lblusername.getText().trim()); + person.verantwortlicher.setUserID(lblusername.getText().trim()); + person.verantwortlicher.setName(user.lastName); + person.verantwortlicher.setVorname(user.firstName); + person.verantwortlicher.setEMail(user.eMail); + person.verantwortlicher.setHochschule(hochschule); + + // Spaeter ueber result.getRole zum Beispiel die Rolle holen + person.verantwortlicher.setRole("Dozent"); + } // end bwLehrpool-Login + + if (loginType == LOGIN_TYPE_BWIDM) { + // try the shibbo login in its own SwingWorker to avoid GUI lockups + SwingWorker<Boolean, String> worker = new SwingWorker<Boolean, String>(){ + @Override + protected Boolean doInBackground() throws Exception { + publish("Info: Initialisiere Shibboleth-Client ..."); + ShibbolethECP.init(choice.getSelectedItem().toString()); + publish("Info: Überprüfe Zugangdaten über bwIDM ..."); + return ShibbolethECP.doLogin(lblusername.getText().trim(), String.valueOf(lblpass.getPassword())); + } + protected void done() { + try { + if (get()) { + setStatus(Color.green, "Info: bwIDM-Login erfolgreich.", null); + // TODO: call showNextStep() + //showMainMenu(); + JOptionPane.showMessageDialog(c, "Der Shibboleth-Login war erfolgreich! Der Rest ist noch in Entwicklung :)", + "bwIDM-Login erfolgreich", JOptionPane.PLAIN_MESSAGE); + } else { + setStatus(Color.red, "Fehler: bwIDM-Login fehlgeschlagen!", null); + } + } catch (InterruptedException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } catch (ExecutionException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + } + @Override + protected void process(List<String> msgs) { + String currentMessage = msgs.get(msgs.size()-1); + setStatus(Color.black, currentMessage, null); + } + }; + worker.execute(); + } + // always save to user's config file. if (chckbxBenutzernameSpeichern.isSelected()) { Config.setUsername(lblusername.getText()); Config.setSaveUsername(true); @@ -364,9 +410,14 @@ public class Login_GUI extends JFrame { Config.setUsername(""); Config.setSaveUsername(false); } - // speichern + // save it to local disk Config.store(); + // all done, show main menu + showMainMenu(); + }// end performLogin + + private void showMainMenu() { // Pruefe ob Bills Of Rights schon akzeptiert wurden, // wenn nicht zeige diese an if (!Config.getBillOfRights()) { @@ -390,8 +441,7 @@ public class Login_GUI extends JFrame { setVisible(false); } } - - }// end performLogin + } /** * Set connection status message, optionally show message box. diff --git a/dozentenmodul/src/main/java/util/ShibbolethECP.java b/dozentenmodul/src/main/java/util/ShibbolethECP.java new file mode 100644 index 00000000..374e3a6e --- /dev/null +++ b/dozentenmodul/src/main/java/util/ShibbolethECP.java @@ -0,0 +1,108 @@ +package util; + +import java.io.IOException; + +import org.apache.http.HttpEntity; +import org.apache.http.HttpResponse; +import org.apache.http.client.ClientProtocolException; +import org.apache.http.client.HttpClient; +import org.apache.http.client.ResponseHandler; +import org.apache.http.client.methods.HttpGet; +import org.apache.http.util.EntityUtils; +import org.apache.log4j.Logger; +import org.opensaml.DefaultBootstrap; +import org.opensaml.xml.ConfigurationException; + +import de.tudarmstadt.ukp.shibhttpclient.ShibHttpClient; + + +public class ShibbolethECP { + + // Logger + private final static Logger LOGGER = Logger.getLogger(ShibbolethECP.class); + + // IdP URL + private static String identityProviderUrl; + + public static void setIdentityProviderUrl(String identityProviderUrl) { + ShibbolethECP.identityProviderUrl = identityProviderUrl; + } + + public static boolean init(String idpUrl) { + try { + DefaultBootstrap.bootstrap(); + } catch (ConfigurationException ce) { + ce.printStackTrace(); + LOGGER.error("OpenSAML wrongly configured."); + return false; + } + + if (idpUrl != null) { + // TODO sanity check on the URL? + setIdentityProviderUrl(idpUrl); + } else { + // no IdP given + return false; + } + + // everything fine, return true + return true; + } + + public static Boolean doLogin(final String user, final String pass) { + + // first lets do some sanity checks + if (user == null) { + LOGGER.error("No username given, aborting..."); + return false; + } + + if (pass == null) { + LOGGER.error("No password given, aborting..."); + return false; + } + + if (identityProviderUrl == null) { + LOGGER.error("Identity provider is not set, did you initialize this class correctly?"); + return false; + } + + // The last argument indicates to accept any certificate + HttpClient client = new ShibHttpClient(identityProviderUrl, user, pass, true); + HttpGet req = new HttpGet("https://bwlp-masterserver.ruf.uni-freiburg.de/secure-all/test.php"); + String res = null; + ResponseHandler<String> respHandler = new ResponseHandler<String>() { + public String handleResponse(final HttpResponse response) throws ClientProtocolException, IOException { + int status = response.getStatusLine().getStatusCode(); + if (status == 200 || status == 302) { + HttpEntity entity = response.getEntity(); + return entity != null ? EntityUtils.toString(entity) : null; + } else { + throw new ClientProtocolException("Unexpected response status: " + status); + } + } + }; + try { + res = client.execute(req, respHandler); + } catch (ClientProtocolException e) { + // this is thrown on http return code not 200 or 302, indicates wrong login + // TODO handle this with possible error causes: creds wrong, etc... + LOGGER.error("Fatal error requesting '" + req.getURI() + "':", e); + return false; + } catch (IOException e) { + LOGGER.error("Fatal protocol error requesting '" + req.getURI() + "':", e); + return false; + } + + // did we get a response? + if (res != null) { + LOGGER.info(res); + // return true, to signal a successful login + return true; + } else { + // we shouldn't actually reach this code... + LOGGER.error("Seems like the request worked, but the response is empty. Something is very wrong..."); + return false; + } + } +} |