Added basic command-line example

This commit is contained in:
Stian Thorgersen 2014-03-06 11:26:21 +00:00
parent b543e22eee
commit 12978a4343
3 changed files with 348 additions and 0 deletions

View file

@ -0,0 +1,91 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<parent>
<artifactId>keycloak-parent</artifactId>
<groupId>org.keycloak</groupId>
<version>1.0-alpha-3-SNAPSHOT</version>
<relativePath>../../../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
<groupId>org.keycloak.example.demo</groupId>
<artifactId>customer-portal-cli-example</artifactId>
<packaging>war</packaging>
<name>Customer Portal CLI</name>
<description/>
<repositories>
<repository>
<id>jboss</id>
<name>jboss repo</name>
<url>http://repository.jboss.org/nexus/content/groups/public/</url>
</repository>
</repositories>
<dependencies>
<dependency>
<groupId>org.keycloak</groupId>
<artifactId>keycloak-core</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.keycloak</groupId>
<artifactId>keycloak-social-core</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.keycloak</groupId>
<artifactId>keycloak-services</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.json</groupId>
<artifactId>json</artifactId>
</dependency>
<dependency>
<groupId>net.iharder</groupId>
<artifactId>base64</artifactId>
</dependency>
<dependency>
<groupId>org.codehaus.jackson</groupId>
<artifactId>jackson-core-asl</artifactId>
</dependency>
<dependency>
<groupId>org.codehaus.jackson</groupId>
<artifactId>jackson-mapper-asl</artifactId>
</dependency>
</dependencies>
<build>
<finalName>customer-portal</finalName>
<plugins>
<plugin>
<groupId>org.jboss.as.plugins</groupId>
<artifactId>jboss-as-maven-plugin</artifactId>
<version>7.4.Final</version>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-deploy-plugin</artifactId>
<configuration>
<skip>true</skip>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>1.6</source>
<target>1.6</target>
</configuration>
</plugin>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>exec-maven-plugin</artifactId>
<configuration>
<mainClass>org.keycloak.example.CustomerCli</mainClass>
</configuration>
</plugin>
</plugins>
</build>
</project>

View file

@ -0,0 +1,256 @@
package org.keycloak.example;
import org.json.JSONObject;
import org.keycloak.jose.jws.JWSInput;
import org.keycloak.services.managers.ApplicationManager;
import org.keycloak.social.utils.SimpleHttp;
import org.keycloak.util.JsonSerialization;
import java.awt.*;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.URI;
import java.net.URLEncoder;
import java.util.UUID;
/**
* @author <a href="mailto:sthorger@redhat.com">Stian Thorgersen</a>
*/
public class CustomerCli {
private static String authServerUrl;
private static String realm;
private static String clientId;
private static String accessToken;
private static BufferedReader br;
public static void main(String[] args) throws Exception {
try {
String f = args.length > 0 ? args[0] : "keycloak.json";
ApplicationManager.InstallationAdapterConfig config = JsonSerialization.readValue(new FileInputStream(new File(f)), ApplicationManager.InstallationAdapterConfig.class);
authServerUrl = config.getAuthServerUrl();
realm = config.getRealm();
clientId = config.getResource();
} catch (Throwable t) {
System.err.println("Failed to load config:");
t.printStackTrace();
System.exit(1);
}
br = new BufferedReader(new InputStreamReader(System.in));
printHelp();
for (String s = br.readLine(); s != null; s = br.readLine()) {
if (s.equals("login")) {
login();
} else if (s.equals("login-desktop")) {
loginDesktop();
} else if (s.equals("login-manual")) {
loginManual();
} else if (s.equals("profile")) {
profile();
} else if (s.equals("token")) {
token();
} else if (s.equals("exit")) {
System.exit(0);
} else {
printHelp();
}
}
}
public static void printHelp() {
System.out.println("Commands:");
System.out.println(" login - login with desktop browser if available, otherwise do manual login");
System.out.println(" login-manual - manual login");
System.out.println(" login-desktop - desktop login");
System.out.println(" profile - retrieve user profile");
System.out.println(" token - show token details");
System.out.println(" exit - exit");
}
public static void login() {
try {
if (Desktop.isDesktopSupported()) {
loginDesktop();
} else {
loginManual();
}
} catch (Throwable e) {
System.err.println("Failed to log in user: " + e.getMessage());
}
}
public static void loginDesktop() {
try {
CallbackListener callback = new CallbackListener();
callback.start();
String redirectUri = URLEncoder.encode("http://localhost:" + callback.getPort(), "utf-8");
String state = UUID.randomUUID().toString();
String loginUrl = authServerUrl + "/rest/realms/" + realm + "/tokens/login?" +
"client_id=" + clientId +
"&redirect_uri=" + redirectUri +
"&state=" + state;
Desktop.getDesktop().browse(new URI(loginUrl));
callback.join();
if (!state.equals(callback.getStateParam())) {
System.err.println("Invalid state received");
return;
}
if (callback.getError() != null) {
System.err.println("Failed to login: " + callback.getError());
return;
}
System.out.println("User logged in");
String tokenUrl = authServerUrl + "/rest/realms/" + realm + "/tokens/access/codes";
JSONObject response = SimpleHttp.doPost(tokenUrl).param("client_id", clientId).param("code", callback.getCode()).asJson();
accessToken = response.getString("access_token");
System.out.println("Access token received");
return;
} catch (Throwable e) {
System.err.println("Failed to log in user: " + e.getMessage());
}
}
public static void loginManual() {
try {
CallbackListener callback = new CallbackListener();
callback.start();
String redirectUri = URLEncoder.encode("urn:ietf:wg:oauth:2.0:oob", "utf-8");
String loginUrl = authServerUrl + "/rest/realms/" + realm + "/tokens/login?" +
"client_id=" + clientId +
"&redirect_uri=" + redirectUri;
System.out.println("Open the following URL in a browser and paste the code back:");
System.out.println(loginUrl);
System.out.print("code: ");
String code = br.readLine().trim();
String tokenUrl = authServerUrl + "/rest/realms/" + realm + "/tokens/access/codes";
JSONObject response = SimpleHttp.doPost(tokenUrl).param("client_id", clientId).param("code", code).asJson();
accessToken = response.getString("access_token");
System.out.println("Access token received");
return;
} catch (Throwable e) {
System.err.println("Failed to log in user: " + e.getMessage());
}
}
public static void profile() {
try {
String profileUrl = authServerUrl + "/rest/realms/" + realm + "/account";
JSONObject profile = SimpleHttp.doGet(profileUrl).header("Accept", "application/json").header("Authorization", "Bearer " + accessToken).asJson();
System.out.println(profile.toString(2));
} catch (Throwable e) {
System.err.println("Failed: " + e.getMessage());
}
}
public static void token() {
try {
JWSInput jws = new JWSInput(accessToken);
System.out.println(new JSONObject(new String(jws.getContent())).toString(2));
} catch (Throwable e) {
System.err.println("Failed to log in user: " + e.getMessage());
}
}
public static class CallbackListener extends Thread {
private String code;
private String error;
private String state;
private final ServerSocket server;
public CallbackListener() throws IOException {
server = new ServerSocket(0);
}
public int getPort() {
return server.getLocalPort();
}
@Override
public void run() {
try {
Socket socket = server.accept();
System.out.println("Request received");
BufferedReader br = new BufferedReader(new InputStreamReader(socket.getInputStream()));
String request = br.readLine();
System.out.println(request);
String[] params = request.split(" ")[1].substring(2).split("&");
System.out.println(params.length);
for (String param : params) {
String[] p = param.split("=");
System.out.println(p[0]);
if (p[0].equals("code")) {
code = p[1];
} else if (p[0].equals("error")) {
error = p[1];
} else if (p[0].equals("state")) {
state = p[1];
}
}
PrintWriter pw = new PrintWriter(new OutputStreamWriter(socket.getOutputStream()));
pw.println("Please close and return to application");
pw.flush();
socket.close();
} catch (IOException e) {
error = "Local error: " + e.getMessage();
}
try {
server.close();
} catch (IOException e) {
}
}
public String getCode() throws InterruptedException {
return code;
}
public String getError() {
return error;
}
public String getStateParam() {
return state;
}
}
}

View file

@ -36,6 +36,7 @@
<modules>
<!-- <module>server</module> -->
<module>customer-app</module>
<module>customer-app-cli</module>
<module>customer-app-js</module>
<module>product-app</module>
<module>database-service</module>