Commit b50ac6fc authored by benjamin.ertl's avatar benjamin.ertl

spring boot app

parent 417dc715
......@@ -14,86 +14,38 @@
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.2</version>
<configuration>
<source>${java.version}</source>
<target>${java.version}</target>
<encoding>UTF-8</encoding>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>2.6</version>
<configuration>
<archive>
<manifest>
<addClasspath>true</addClasspath>
<classpathPrefix>lib/</classpathPrefix>
<mainClass>edu.kit.scc.Main</mainClass>
</manifest>
</archive>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-resources-plugin</artifactId>
<version>2.7</version>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<version>2.10</version>
<executions>
<execution>
<id>copy-dependencies</id>
<phase>prepare-package</phase>
<goals>
<goal>copy-dependencies</goal>
</goals>
<configuration>
<outputDirectory>
${project.build.directory}
</outputDirectory>
<overWriteReleases>false</overWriteReleases>
<overWriteSnapshots>false</overWriteSnapshots>
<overWriteIfNewer>true</overWriteIfNewer>
</configuration>
</execution>
</executions>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.3.1.RELEASE</version>
</parent>
<dependencies>
<!-- Spring -->
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
<version>4.1</version>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- Spring -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>4.2.4.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>4.2.4.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-beans</artifactId>
<version>4.2.4.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-commons</artifactId>
<version>1.11.2.RELEASE</version>
</dependency>
<!-- LDAP -->
......@@ -132,13 +84,6 @@
<dependency>
<groupId>org.json</groupId>
<artifactId>json</artifactId>
<version>20151123</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
<version>1.7.13</version>
</dependency>
</dependencies>
</project>
\ No newline at end of file
package edu.kit.scc;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class Application {
private static final Logger log = LoggerFactory.getLogger(Application.class);
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
package edu.kit.scc;
import java.io.ByteArrayInputStream;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.io.RandomAccessFile;
import java.io.StringWriter;
import java.nio.charset.StandardCharsets;
import java.security.KeyFactory;
import java.security.NoSuchAlgorithmException;
import java.security.PrivateKey;
import java.security.cert.Certificate;
import java.security.cert.CertificateException;
import java.security.cert.CertificateFactory;
import java.security.cert.X509Certificate;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.PKCS8EncodedKeySpec;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.xml.transform.Result;
import javax.xml.transform.Source;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerConfigurationException;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import org.apache.commons.httpclient.UsernamePasswordCredentials;
import org.apache.commons.httpclient.auth.AuthScope;
import org.apache.commons.ssl.X509CertificateChainBuilder;
import org.joda.time.DateTime;
import org.opensaml.DefaultBootstrap;
import org.opensaml.common.SAMLVersion;
import org.opensaml.saml2.core.AttributeQuery;
import org.opensaml.saml2.core.Issuer;
import org.opensaml.saml2.core.NameID;
import org.opensaml.saml2.core.Response;
import org.opensaml.saml2.core.Subject;
import org.opensaml.ws.soap.client.BasicSOAPMessageContext;
import org.opensaml.ws.soap.client.http.HttpClientBuilder;
import org.opensaml.ws.soap.client.http.HttpSOAPClient;
import org.opensaml.ws.soap.common.SOAPException;
import org.opensaml.ws.soap.soap11.Body;
import org.opensaml.ws.soap.soap11.Envelope;
import org.opensaml.xml.Configuration;
import org.opensaml.xml.ConfigurationException;
import org.opensaml.xml.XMLObject;
import org.opensaml.xml.XMLObjectBuilderFactory;
import org.opensaml.xml.io.Marshaller;
import org.opensaml.xml.io.MarshallerFactory;
import org.opensaml.xml.io.MarshallingException;
import org.opensaml.xml.parse.BasicParserPool;
import org.opensaml.xml.security.SecurityException;
import org.opensaml.xml.security.SecurityHelper;
import org.opensaml.xml.security.keyinfo.KeyInfoGenerator;
import org.opensaml.xml.security.x509.BasicX509Credential;
import org.opensaml.xml.security.x509.X509KeyInfoGeneratorFactory;
import org.opensaml.xml.signature.KeyInfo;
import org.opensaml.xml.signature.Signature;
import org.opensaml.xml.signature.SignatureConstants;
import org.opensaml.xml.util.XMLHelper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.xml.XmlBeanFactory;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.support.AbstractApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.Resource;
import org.springframework.ldap.core.ContextSource;
import org.springframework.ldap.core.LdapTemplate;
import org.springframework.ldap.core.support.LdapContextSource;
import org.w3c.dom.Element;
import edu.kit.scc.dao.UserDAO;
import edu.kit.scc.dto.UserDTO;
import edu.kit.scc.http.HttpClient;
import edu.kit.scc.http.HttpResponse;
import edu.kit.scc.ldap.LDAPUserDAO;
import edu.kit.scc.saml.HttpSignableSoapClient;
import edu.kit.scc.saml.SamlClient;
public class Main {
private static final Logger log = LoggerFactory.getLogger(Main.class);
// private static String authorizationCode =
// "997fc6c123b3224b3ade247ea8376164";
// private static String accessToken = "88e3bd6a549e385926378129b330c";
@Bean
LdapContextSource contextSource() {
LdapContextSource ldapContextSource = new LdapContextSource();
ldapContextSource.setUrl("ldap://192.168.122.202:10389");
ldapContextSource.setBase("o=sshService");
ldapContextSource.setUserDn("uid=admin,ou=system");
ldapContextSource.setPassword("secret");
return ldapContextSource;
}
@Bean
LdapTemplate ldapTemplate(LdapContextSource contextSource) {
return new LdapTemplate(contextSource);
}
@Bean
LDAPUserDAO ldapUser(LdapTemplate ldapTemplate) {
LDAPUserDAO ldapUserDAO = new LDAPUserDAO();
ldapUserDAO.setLdapTemplate(ldapTemplate);
return ldapUserDAO;
}
public static void main(String[] args) throws ConfigurationException, MarshallingException, TransformerException,
CertificateException, javax.security.cert.CertificateException, IOException, NoSuchAlgorithmException,
InvalidKeySpecException, SecurityException, SOAPException {
// OidcClient oidcClient = new OidcClient(clientId, clientSecret,
// redirectUri, oidcTokenEndpoint,
// oidcUserInfoEndpoint);
//
// Tokens tokens = oidcClient.requestTokens(authorizationCode);
//
// oidcClient.requestUserInfo(tokens.getAccessToken().getValue());
// Utils.printProperties();
// ScimClient scimClient = new ScimClient();
// scimClient.getUsers("admin", "admin");
// scimClient.getGroups("admin", "admin");
// Utils.printProperties();
// HttpClient client = new HttpClient();
// HttpResponse response =
// client.makeHTTPPostRequest("password=password",
// "http://localhost:50070");
// log.debug(response.toString());
// client.makePOST("localhost", 50070, "user", "password",
// "http://localhost:50070");
// Resource resource = new ClassPathResource("springldap.xml");
// BeanFactory factory = new XmlBeanFactory(resource);
// ApplicationContext ctx = new
// ClassPathXmlApplicationContext("springldap.xml");
// ApplicationContext ctx = new
// AnnotationConfigApplicationContext(Main.class);
// UserDAO ldapUser = (LDAPUserDAO) ctx.getBean("ldapUser");
// List<UserDTO> userList = ldapUser.getAllUserNames();
// for (int i = 0; i < userList.size(); i++)
// log.info("User name {}", ((UserDTO)
// userList.get(i)).getCommonName());
// List<UserDTO> userDetails = ldapUser.getUserDetails("John Smith",
// "Smith");
// for (int i = 0; i < userDetails.size(); i++)
// log.info("Description {}", ((UserDTO)
// userDetails.get(i)).getDescription());
//
// UserDTO newUser = new UserDTO();
// newUser.setCommonName("me");
// newUser.setLastName("too");
// ldapUser.insertUser(newUser);
//
// ((AbstractApplicationContext) ctx).close();
SamlClient client = new SamlClient();
client.attributeQuery("ym0762", "oo22-.22", "MdWhcFYwml0vPFMscox33AYkkgs=", "https://ldf.data.kit.edu/sp");
}
}
package edu.kit.scc;
import org.apache.commons.codec.binary.Base64;
import org.json.JSONObject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestHeader;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseStatus;
import org.springframework.web.bind.annotation.RestController;
import edu.kit.scc.http.HttpClient;
import edu.kit.scc.http.HttpResponse;
import edu.kit.scc.ldap.LdapClient;
import edu.kit.scc.oidc.OidcClient;
import edu.kit.scc.scim.ScimClient;
@RestController
@RequestMapping("/rest")
public class RestServiceController {
private static Logger log = LoggerFactory.getLogger(RestServiceController.class);
@Value("${regapp.serviceUsername}")
private String restUser;
@Value("${regapp.servicePassword}")
private String restPassword;
@Value("${regapp.serviceUrl}")
private String serviceUrl;
@Autowired
private HttpClient httpClient;
@Autowired
private OidcClient oidcClient;
@Autowired
private ScimClient scimClient;
@Autowired
private LdapClient ldapClient;
// expected body e.g.
// password=password
// password=https%3A%2F%2F512eebd9%3Fk%3D49806e48a5cd2941604eb9dfe321c3bc
// password=3D49806e48a5cd2941604eb9dfe321c3bc
@RequestMapping(path = "/ecp/{regId}", method = RequestMethod.POST)
public void ecpAuthentication(@PathVariable String regId, @RequestHeader("Authorization") String basicAuthorization,
@RequestBody String body) {
String encodedCredentials = basicAuthorization.split(" ")[1];
String[] credentials = new String(Base64.decodeBase64(encodedCredentials)).split(":");
if (!credentials[0].equals(restUser) || !credentials[1].equals(restPassword)) {
log.error("Wrong credentials {} {}", credentials[0], credentials[1]);
throw new UnauthorizedException();
}
log.debug(body);
// REG-APP
HttpResponse response = httpClient.makeHttpPostRequest(restUser, restPassword, body, serviceUrl + regId);
if (response != null && response.statusCode == 200) {
log.debug("Reg-app authentication success");
return;
}
// OIDC
JSONObject oidcJson = null;
try {
String token = body.split("=")[1];
oidcJson = oidcClient.requestUserInfo(token);
} catch (ArrayIndexOutOfBoundsException e) {
throw new UnauthorizedException();
}
if (oidcJson != null && !oidcJson.isNull("error")) {
throw new UnauthorizedException(oidcJson.optString("error_description"));
}
// SCIM
String name = oidcJson.optString("name");
JSONObject scimJson = scimClient.getUser(name);
// we are looking for "roles" in the SCIM response and sync with LDAP
}
@ResponseStatus(value = HttpStatus.UNAUTHORIZED)
public class UnauthorizedException extends RuntimeException {
private static final long serialVersionUID = 6396195910009296687L;
public UnauthorizedException() {
super();
}
public UnauthorizedException(String message) {
super(message);
}
public UnauthorizedException(Throwable e) {
super(e);
}
}
}
package edu.kit.scc;
import java.io.IOException;
import java.io.InputStream;
import java.util.Map.Entry;
import java.util.Properties;
import org.apache.commons.codec.binary.Base64;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public final class Utils {
private static final Logger log = LoggerFactory.getLogger(Utils.class);
private Utils() {
}
public static String encodeBase64(String string) {
return new String(Base64.encodeBase64(string.getBytes()));
}
public static Properties loadProperties() {
InputStream in = null;
Properties properties = new Properties();
try {
// load properties from configuration.properties file
in = Main.class.getClassLoader().getResourceAsStream("config.properties");
if (in != null) {
properties.load(in);
log.debug("loaded properties from {} file", "config.properties");
}
// load properties from System.getProperty, overwrite
// configuration.properties
if (System.getProperty("registerApp.serviceUrl") != null)
properties.put("regapp.serviceUrl", System.getProperty("registerApp.serviceUrl"));
if (System.getProperty("registerApp.serviceUsername") != null)
properties.put("regapp.serviceUsername", System.getProperty("registerApp.serviceUsername"));
if (System.getProperty("registerApp.servicePassword") != null)
properties.put("regapp.servicePassword", System.getProperty("registerApp.servicePassword"));
if (System.getProperty("registerApp.checkCert") != null)
properties.put("regapp.checkCert", System.getProperty("registerApp.serviceUrl"));
} catch (IOException e) {
// e.printStackTrace();
log.error(e.getMessage());
} finally {
if (in != null) {
try {
in.close();
} catch (IOException e) {
// e.printStackTrace();
log.error(e.getMessage());
}
}
}
return properties;
}
public static void printProperties() {
Properties properties = loadProperties();
for (Entry<Object, Object> e : properties.entrySet())
log.info("{}: {}", new Object[] { e.getKey(), e.getValue() });
}
}
......@@ -20,6 +20,7 @@ import javax.net.ssl.X509TrustManager;
public final class CustomSSLContext {
@SuppressWarnings("unused")
private static final String cert = "-----BEGIN CERTIFICATE-----\n"
+ "MIICNTCCAZ6gAwIBAgIES343gjANBgkqhkiG9w0BAQUFADBVMQswCQYDVQQGEwJV"
+ "UzELMAkGA1UECAwCQ0ExFjAUBgNVBAcMDU1vdW50YWluIFZpZXcxDTALBgNVBAoM"
......
......@@ -21,7 +21,7 @@ public final class CustomUrlConnection {
public static HttpsURLConnection getSecureHttpConnection(boolean checkCertificate, String url) {
HttpsURLConnection urlConnection = null;
try {
log.debug("parse url {}", url);
log.debug("Try url {}", url);
URL uri = new URL(url);
SSLContext sslContext = null;
......@@ -51,7 +51,7 @@ public final class CustomUrlConnection {
public static HttpURLConnection getHttpConnection(String url) {
HttpURLConnection urlConnection = null;
try {
log.debug("parse url {}", url);
log.debug("Try url {}", url);
URL uri = new URL(url);
urlConnection = (HttpURLConnection) uri.openConnection();
......
......@@ -3,51 +3,23 @@ package edu.kit.scc.http;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.UnsupportedEncodingException;
import java.net.HttpURLConnection;
import java.security.KeyManagementException;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import java.security.cert.X509Certificate;
import java.util.ArrayList;
import java.util.List;
import javax.net.ssl.SSLContext;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;
import org.apache.http.HttpResponse;
import org.apache.http.HttpStatus;
import org.apache.http.NameValuePair;
import org.apache.http.ParseException;
import org.apache.http.auth.AuthScope;
import org.apache.http.auth.UsernamePasswordCredentials;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.conn.ClientConnectionManager;
import org.apache.http.conn.scheme.Scheme;
import org.apache.http.conn.scheme.SchemeRegistry;
import org.apache.http.conn.ssl.AllowAllHostnameVerifier;
import org.apache.http.conn.ssl.SSLSocketFactory;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.impl.conn.SingleClientConnManager;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.protocol.HTTP;
import org.apache.http.util.EntityUtils;
import org.apache.commons.codec.binary.Base64;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import org.springframework.web.bind.annotation.RequestMethod;
import com.google.common.io.ByteStreams;
import edu.kit.scc.Utils;
/**
* HTTP client implementation.
*
* @author benjamin
*
*/
@Component
public class HttpClient {
private static final Logger log = LoggerFactory.getLogger(HttpClient.class);
......@@ -61,8 +33,8 @@ public class HttpClient {
* response code and response stream as {@link byte[]}
*
*/
public edu.kit.scc.http.HttpResponse makeHTTPGetRequest(String url) {
return makeHTTPGetRequest(null, null, url);
public HttpResponse makeHttpGetRequest(String url) {
return makeHttpGetRequest(null, null, url);
}
/**
......@@ -77,46 +49,73 @@ public class HttpClient {
* @return a {@link edu.kit.scc.http.HttpResponse} with the request's
* response code and response stream as {@link byte[]}
*/
public edu.kit.scc.http.HttpResponse makeHTTPGetRequest(String user, String password, String url) {
edu.kit.scc.http.HttpResponse response = null;
InputStream in = null;
try {
HttpURLConnection urlConnection = CustomUrlConnection.getHttpConnection(url);
urlConnection.setRequestMethod("GET");
urlConnection.setRequestProperty("Accept", "*/*");
public HttpResponse makeHttpGetRequest(String user, String password, String url) {
return makeRequest(CustomUrlConnection.getHttpConnection(url), user, password, null, RequestMethod.GET);
}
if (user != null && !user.isEmpty()) {
String value = Utils.encodeBase64(user + ":" + password);
log.debug("Authorization: Basic {}", value);
urlConnection.setRequestProperty("Authorization", "Basic " + value);
}
/**
* Makes a HTTP POST request.
*
* @param body
* the body for the HTTP POST request
* @param url
* the URL for the request
* @return a {@link edu.kit.scc.http.HttpResponse} with the request's
* response code and response stream as {@link byte[]}