Skip to content

Commit

Permalink
initial
Browse files Browse the repository at this point in the history
  • Loading branch information
patriot1burke committed Jul 2, 2013
1 parent 503cede commit 7a1c825
Show file tree
Hide file tree
Showing 59 changed files with 6,260 additions and 0 deletions.
32 changes: 32 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
# Intellij
###################
.idea
*.iml

# Compiled source #
###################
*.com
*.class
*.dll
*.exe
*.o
*.so

# Packages #
############
# it's better to unpack these files and commit the raw source
# git has its own built in compression methods
*.7z
*.dmg
*.gz
*.iso
*.jar
*.rar
*.tar
*.zip

# Logs and databases #
######################
*.log


60 changes: 60 additions & 0 deletions core/pom.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
<?xml version="1.0"?>
<project>
<parent>
<artifactId>keycloak-parent</artifactId>
<groupId>org.keycloak</groupId>
<version>1.0-alpha-1</version>
<relativePath>../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>

<artifactId>keycloak-core</artifactId>
<name>Keycloak Core</name>
<description/>

<dependencies>
<dependency>
<groupId>org.jboss.resteasy</groupId>
<artifactId>resteasy-jaxrs</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.jboss.resteasy</groupId>
<artifactId>resteasy-client</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.jboss.resteasy</groupId>
<artifactId>jose-jwt</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>servlet-api</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.jboss.resteasy</groupId>
<artifactId>tjws</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>1.6</source>
<target>1.6</target>
</configuration>
</plugin>
</plugins>
</build>

</project>
162 changes: 162 additions & 0 deletions core/src/main/java/org/keycloak/AbstractOAuthClient.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,162 @@
package org.keycloak;

import org.jboss.resteasy.client.jaxrs.ResteasyClientBuilder;
import org.keycloak.representations.AccessTokenResponse;
import org.jboss.resteasy.util.BasicAuthHelper;

import javax.ws.rs.BadRequestException;
import javax.ws.rs.InternalServerErrorException;
import javax.ws.rs.client.Client;
import javax.ws.rs.client.Entity;
import javax.ws.rs.core.Form;
import javax.ws.rs.core.HttpHeaders;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.UriBuilder;
import java.security.KeyStore;
import java.util.UUID;
import java.util.concurrent.atomic.AtomicLong;

/**
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
* @version $Revision: 1 $
*/
public class AbstractOAuthClient
{
protected String clientId;
protected String password;
protected KeyStore truststore;
protected String authUrl;
protected String codeUrl;
protected String stateCookieName = "OAuth_Token_Request_State";
protected Client client;
protected final AtomicLong counter = new AtomicLong();

protected String getStateCode()
{
return counter.getAndIncrement() + "/" + UUID.randomUUID().toString();
}

public void start()
{
if (client == null)
{
client = new ResteasyClientBuilder().trustStore(truststore)
.hostnameVerification(ResteasyClientBuilder.HostnameVerificationPolicy.ANY)
.connectionPoolSize(10)
.build();
}
}

public void stop()
{
client.close();
}

public String getClientId()
{
return clientId;
}

public void setClientId(String clientId)
{
this.clientId = clientId;
}

public String getPassword()
{
return password;
}

public void setPassword(String password)
{
this.password = password;
}

public KeyStore getTruststore()
{
return truststore;
}

public void setTruststore(KeyStore truststore)
{
this.truststore = truststore;
}

public String getAuthUrl()
{
return authUrl;
}

public void setAuthUrl(String authUrl)
{
this.authUrl = authUrl;
}

public String getCodeUrl()
{
return codeUrl;
}

public void setCodeUrl(String codeUrl)
{
this.codeUrl = codeUrl;
}

public String getStateCookieName()
{
return stateCookieName;
}

public void setStateCookieName(String stateCookieName)
{
this.stateCookieName = stateCookieName;
}

public Client getClient()
{
return client;
}

public void setClient(Client client)
{
this.client = client;
}

public String resolveBearerToken(String redirectUri, String code)
{
redirectUri = stripOauthParametersFromRedirect(redirectUri);
String authHeader = BasicAuthHelper.createHeader(clientId, password);
Form codeForm = new Form()
.param("grant_type", "authorization_code")
.param("code", code)
.param("redirect_uri", redirectUri);
Response res = client.target(codeUrl).request().header(HttpHeaders.AUTHORIZATION, authHeader).post(Entity.form(codeForm));
try
{
if (res.getStatus() == 400)
{
throw new BadRequestException();
}
else if (res.getStatus() != 200)
{
throw new InternalServerErrorException(new Exception("Unknown error when getting acess token"));
}
AccessTokenResponse tokenResponse = res.readEntity(AccessTokenResponse.class);
return tokenResponse.getToken();
}
finally
{
res.close();
}
}

protected String stripOauthParametersFromRedirect(String uri)
{
System.out.println("******************** redirect_uri: " + uri);
UriBuilder builder = UriBuilder.fromUri(uri)
.replaceQueryParam("code", null)
.replaceQueryParam("state", null);
return builder.build().toString();
}

}
22 changes: 22 additions & 0 deletions core/src/main/java/org/keycloak/BouncyIntegration.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
package org.keycloak;

import org.bouncycastle.jce.provider.BouncyCastleProvider;

import java.security.Security;

/**
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
* @version $Revision: 1 $
*/
public class BouncyIntegration
{
static
{
if (Security.getProvider("BC") == null) Security.addProvider(new BouncyCastleProvider());
}

public static void init()
{
// empty, the static class does it
}
}
68 changes: 68 additions & 0 deletions core/src/main/java/org/keycloak/DerUtils.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
package org.keycloak;

import java.io.DataInputStream;
import java.io.InputStream;
import java.security.KeyFactory;
import java.security.NoSuchAlgorithmException;
import java.security.NoSuchProviderException;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.cert.CertificateFactory;
import java.security.cert.X509Certificate;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;

/**
* Extract PrivateKey, PublicKey, and X509Certificate from a DER encoded byte array or file. Usually
* generated from openssl
*
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
* @version $Revision: 1 $
*/
public class DerUtils
{
static
{
BouncyIntegration.init();
}

public static PrivateKey decodePrivateKey(InputStream is)
throws Exception
{

DataInputStream dis = new DataInputStream(is);
byte[] keyBytes = new byte[dis.available()];
dis.readFully(keyBytes);
dis.close();

PKCS8EncodedKeySpec spec =
new PKCS8EncodedKeySpec(keyBytes);
KeyFactory kf = KeyFactory.getInstance("RSA", "BC");
return kf.generatePrivate(spec);
}

public static PublicKey decodePublicKey(byte[] der) throws NoSuchAlgorithmException, InvalidKeySpecException, NoSuchProviderException
{
X509EncodedKeySpec spec =
new X509EncodedKeySpec(der);
KeyFactory kf = KeyFactory.getInstance("RSA", "BC");
return kf.generatePublic(spec);
}

public static X509Certificate decodeCertificate(InputStream is) throws Exception
{
CertificateFactory cf = CertificateFactory.getInstance("X.509", "BC");
X509Certificate cert = (X509Certificate) cf.generateCertificate(is);
is.close();
return cert;
}

public static PrivateKey decodePrivateKey(byte[] der) throws NoSuchAlgorithmException, InvalidKeySpecException, NoSuchProviderException
{
PKCS8EncodedKeySpec spec =
new PKCS8EncodedKeySpec(der);
KeyFactory kf = KeyFactory.getInstance("RSA", "BC");
return kf.generatePrivate(spec);
}
}
36 changes: 36 additions & 0 deletions core/src/main/java/org/keycloak/EnvUtil.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
package org.keycloak;

import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
* @version $Revision: 1 $
*/
public class EnvUtil
{
private static final Pattern p = Pattern.compile("[$][{]([^}]+)[}]");

/**
* Replaces any ${} strings with their corresponding environent variable.
*
* @param val
* @return
*/
public static String replace(String val)
{
Matcher matcher = p.matcher(val);
StringBuffer buf = new StringBuffer();
while (matcher.find())
{
String envVar = matcher.group(1);
String envVal = System.getProperty(envVar);
if (envVal == null) envVal = "NOT-SPECIFIED";
matcher.appendReplacement(buf, envVal.replace("\\", "\\\\"));
}
matcher.appendTail(buf);
return buf.toString();
}
}


Loading

0 comments on commit 7a1c825

Please sign in to comment.