From 993c59bfa6a8cb5c27a610e2fff305ef9681bc1c Mon Sep 17 00:00:00 2001 From: Stephan Richter Date: Sun, 21 Jul 2024 00:46:23 +0200 Subject: [PATCH] improving path handling, working on authorization flow Signed-off-by: Stephan Richter --- .../de/srsoftware/oidc/api/PathHandler.java | 108 +++++++++++++----- .../de/srsoftware/oidc/app/Application.java | 10 +- .../de/srsoftware/oidc/backend/Backend.java | 78 ++++++++----- .../java/de/srsoftware/oidc/web/Forward.java | 6 +- .../de/srsoftware/oidc/web/StaticPages.java | 27 ++--- .../src/main/resources/en/authorization.html | 13 +++ .../src/main/resources/en/authorization.js | 11 ++ .../src/main/resources/en/favicon.ico | Bin 0 -> 15406 bytes .../src/main/resources/en/index.html | 16 ++- .../src/main/resources/en/index.js | 7 -- .../src/main/resources/en/login.html | 15 ++- .../src/main/resources/en/login.js | 33 ++++++ .../src/main/resources/en/newclient.html | 28 +++++ .../src/main/resources/en/user.js | 12 ++ 14 files changed, 271 insertions(+), 93 deletions(-) create mode 100644 de.srsoftware.oidc.web/src/main/resources/en/authorization.html create mode 100644 de.srsoftware.oidc.web/src/main/resources/en/authorization.js create mode 100644 de.srsoftware.oidc.web/src/main/resources/en/favicon.ico delete mode 100644 de.srsoftware.oidc.web/src/main/resources/en/index.js create mode 100644 de.srsoftware.oidc.web/src/main/resources/en/login.js create mode 100644 de.srsoftware.oidc.web/src/main/resources/en/newclient.html create mode 100644 de.srsoftware.oidc.web/src/main/resources/en/user.js diff --git a/de.srsoftware.oidc.api/src/main/java/de/srsoftware/oidc/api/PathHandler.java b/de.srsoftware.oidc.api/src/main/java/de/srsoftware/oidc/api/PathHandler.java index 5ab25ae..83f7aba 100644 --- a/de.srsoftware.oidc.api/src/main/java/de/srsoftware/oidc/api/PathHandler.java +++ b/de.srsoftware.oidc.api/src/main/java/de/srsoftware/oidc/api/PathHandler.java @@ -1,6 +1,7 @@ /* © SRSoftware 2024 */ package de.srsoftware.oidc.api; +import static java.net.HttpURLConnection.HTTP_OK; import static java.nio.charset.StandardCharsets.UTF_8; import com.sun.net.httpserver.HttpExchange; @@ -15,56 +16,103 @@ import org.json.JSONObject; public abstract class PathHandler implements HttpHandler { public static final String CONTENT_TYPE = "Content-Type"; + public static final String GET = "GET"; public static final String JSON = "application/json"; public static final String POST = "POST"; - private String path; + private String[] paths; public class Bond { - Bond(String p) { - path = p; + Bond(String[] paths) { + PathHandler.this.paths = paths; } public HttpServer on(HttpServer server) { - server.createContext(path, PathHandler.this); + for (var path : paths) server.createContext(path, PathHandler.this); return server; } } - public Bond bindPath(String path) { + public Bond bindPath(String... path) { return new Bond(path); } - public String relativePath(HttpExchange ex) { - var path = ex.getRequestURI().toString(); - if (path.startsWith(this.path)) path = path.substring(this.path.length()); - if (path.startsWith("/")) path = path.substring(1); - return path; + public boolean doGet(String path, HttpExchange ex) throws IOException { + return false; } - - /******* begin of static methods *************/ - - public static String body(HttpExchange ex) throws IOException { - return new String(ex.getRequestBody().readAllBytes(), UTF_8); + public boolean doPost(String path, HttpExchange ex) throws IOException { + return false; } - public static Optional getAuthToken(HttpExchange ex) { - return getHeader(ex, "Authorization"); + @Override + public void handle(HttpExchange ex) throws IOException { + String path = relativePath(ex); + String method = ex.getRequestMethod(); + System.out.printf("%s %s\n", method, path); + boolean dummy = switch (method) { + case POST -> doPost(path,ex); + case GET -> doGet(path,ex); + default -> false; + }; + ex.getResponseBody().close(); } - public static Optional getHeader(HttpExchange ex, String key) { - return Optional.ofNullable(ex.getRequestHeaders().get(key)).map(List::stream).map(Stream::findFirst).orElse(Optional.empty()); - } + public String relativePath(HttpExchange ex) { + var requestPath = ex.getRequestURI().toString(); + for (var path : paths){ + if (requestPath.startsWith(path)) { + requestPath = requestPath.substring(path.length()); + break; + } + } + if (!requestPath.startsWith("/")) requestPath = "/" + requestPath; + var pos = requestPath.indexOf("?"); + if (pos >= 0) requestPath = requestPath.substring(0, pos); + return requestPath; + } - public static JSONObject json(HttpExchange ex) throws IOException { - return new JSONObject(body(ex)); - } + /******* begin of static methods *************/ - public static Optional language(HttpExchange ex) { - return getHeader(ex, "Accept-Language").map(s -> Arrays.stream(s.split(","))).map(Stream::findFirst).orElse(Optional.empty()); - } + public static String body(HttpExchange ex) throws IOException { + return new String(ex.getRequestBody().readAllBytes(), UTF_8); + } - public static void sendEmptyResponse(int statusCode, HttpExchange ex) throws IOException { - ex.sendResponseHeaders(statusCode, 0); - ex.getResponseBody().close(); + public static Optional getAuthToken(HttpExchange ex) { + return getHeader(ex, "Authorization"); + } + + public static Optional getHeader(HttpExchange ex, String key) { + return Optional.ofNullable(ex.getRequestHeaders().get(key)).map(List::stream).map(Stream::findFirst).orElse(Optional.empty()); + } + + public static boolean isPost(String method) { + return POST.equals(method); + } + + public static JSONObject json(HttpExchange ex) throws IOException { + return new JSONObject(body(ex)); + } + + public static Optional language(HttpExchange ex) { + return getHeader(ex, "Accept-Language").map(s -> Arrays.stream(s.split(","))).map(Stream::findFirst).orElse(Optional.empty()); + } + + + public static String prefix(HttpExchange ex) { + return "http://%s".formatted(ex.getRequestHeaders().getFirst("Host")); + } + + public static boolean sendEmptyResponse(int statusCode, HttpExchange ex) throws IOException { + ex.sendResponseHeaders(statusCode, 0); + return false; + } + + public static boolean sendContent(HttpExchange ex, byte[] bytes) throws IOException { + ex.sendResponseHeaders(HTTP_OK, bytes.length); + ex.getResponseBody().write(bytes); + return true; + } + + public static boolean sendContent(HttpExchange ex, Object o) throws IOException { + return sendContent(ex, o.toString().getBytes(UTF_8)); + } } -} diff --git a/de.srsoftware.oidc.app/src/main/java/de/srsoftware/oidc/app/Application.java b/de.srsoftware.oidc.app/src/main/java/de/srsoftware/oidc/app/Application.java index 75eca43..9823706 100644 --- a/de.srsoftware.oidc.app/src/main/java/de/srsoftware/oidc/app/Application.java +++ b/de.srsoftware.oidc.app/src/main/java/de/srsoftware/oidc/app/Application.java @@ -18,7 +18,11 @@ import java.util.*; import java.util.concurrent.Executors; public class Application { + public static final String BACKEND = "/api"; + private static final String FAVICON = "/favicon.ico"; + public static final String ROOT = "/"; public static final String STATIC_PATH = "/web"; + private static final String WELL_KNOWN = "/.well-known"; public static final String FIRST_USER = "admin"; public static final String FIRST_USER_PASS = "admin"; public static final String FIRST_UUID = UUID.randomUUID().toString(); @@ -36,9 +40,9 @@ public class Application { UserService userService = fileStore; SessionService sessionService = fileStore; HttpServer server = HttpServer.create(new InetSocketAddress(8080), 0); - new StaticPages(basePath).bindPath(STATIC_PATH).on(server); - new Forward(INDEX).bindPath("/").on(server); - new Backend(sessionService, userService).bindPath("/api").on(server); + new StaticPages(basePath).bindPath(STATIC_PATH, FAVICON).on(server); + new Forward(INDEX).bindPath(ROOT).on(server); + new Backend(sessionService, userService).bindPath(BACKEND, WELL_KNOWN).on(server); server.setExecutor(Executors.newCachedThreadPool()); server.start(); } diff --git a/de.srsoftware.oidc.backend/src/main/java/de/srsoftware/oidc/backend/Backend.java b/de.srsoftware.oidc.backend/src/main/java/de/srsoftware/oidc/backend/Backend.java index 7d3afd2..690e77c 100644 --- a/de.srsoftware.oidc.backend/src/main/java/de/srsoftware/oidc/backend/Backend.java +++ b/de.srsoftware.oidc.backend/src/main/java/de/srsoftware/oidc/backend/Backend.java @@ -15,6 +15,8 @@ import java.util.Optional; import org.json.JSONObject; public class Backend extends PathHandler { + private static final String CLIENT_ID = "client_id"; + private static final String REDIRECT_URI = "redirect_uri"; private final SessionService sessions; private final UserService users; @@ -23,57 +25,81 @@ public class Backend extends PathHandler { users = userService; } - private void doLogin(HttpExchange ex) throws IOException { + private boolean authorize(HttpExchange ex, Session session) throws IOException { + var json = json(ex); + var clientId = json.getString(CLIENT_ID); + var redirect = json.getString(REDIRECT_URI); + System.out.println(json); + return sendEmptyResponse(HTTP_NOT_FOUND,ex); + } + + private boolean doLogin(HttpExchange ex) throws IOException { var body = json(ex); var username = body.has(USERNAME) ? body.getString(USERNAME) : null; var password = body.has(PASSWORD) ? body.getString(PASSWORD) : null; Optional user = users.load(username, password); - if (user.isPresent()) { - var session = sessions.createSession(user.get()); - sendUserAndCookie(ex, session); - return; - } - sendEmptyResponse(HTTP_UNAUTHORIZED, ex); + if (user.isPresent()) return sendUserAndCookie(ex, sessions.createSession(user.get())); + return sendEmptyResponse(HTTP_UNAUTHORIZED, ex); } @Override - public void handle(HttpExchange ex) throws IOException { - String path = relativePath(ex); - String method = ex.getRequestMethod(); - System.out.printf("%s %s…", method, path); - - var session = getSession(ex); - if ("login".equals(path) && POST.equals(method)) { - doLogin(ex); // TODO: prevent brute force - return; + public boolean doGet(String path, HttpExchange ex) throws IOException { + System.out.printf("GET %s…\n", path); + switch (path) { + case "/openid-configuration": + return openidConfig(ex); } - if (session.isEmpty()) { - sendEmptyResponse(HTTP_UNAUTHORIZED, ex); - System.err.println("unauthorized"); - return; + return sendEmptyResponse(HTTP_NOT_FOUND, ex); + } + + @Override + public boolean doPost(String path, HttpExchange ex) throws IOException { + System.out.printf("POST %s…\n", path); + + // pre-login paths + switch (path) { + case "/login": + return doLogin(ex); } + var optSession = getSession(ex); + if (optSession.isEmpty()) return sendEmptyResponse(HTTP_UNAUTHORIZED, ex); + + // post-login paths + var session = optSession.get(); switch (path) { - case "user": - sendUserAndCookie(ex, session.get()); - return; + case "/authorize": + return authorize(ex,session); + case "/user": + return sendUserAndCookie(ex, session); } System.err.println("not implemented"); - sendEmptyResponse(HTTP_NOT_FOUND, ex); + return sendEmptyResponse(HTTP_NOT_FOUND, ex); } private Optional getSession(HttpExchange ex) { return SessionToken.from(ex).map(SessionToken::sessionId).flatMap(sessions::retrieve); } - private void sendUserAndCookie(HttpExchange ex, Session session) throws IOException { + private boolean openidConfig(HttpExchange ex) throws IOException { + var uri = ex.getRequestURI().toString(); + JSONObject json = new JSONObject(); + + json.put("authorization_endpoint", prefix(ex) + "/web/authorization.html"); + return sendContent(ex, json); + } + + + private boolean sendUserAndCookie(HttpExchange ex, Session session) throws IOException { var bytes = new JSONObject(session.user().map(false)).toString().getBytes(UTF_8); var headers = ex.getResponseHeaders(); headers.add(CONTENT_TYPE, JSON); new SessionToken(session.id()).addTo(headers); ex.sendResponseHeaders(200, bytes.length); - ex.getResponseBody().write(bytes); + var out = ex.getResponseBody(); + out.write(bytes); + return true; } } diff --git a/de.srsoftware.oidc.web/src/main/java/de/srsoftware/oidc/web/Forward.java b/de.srsoftware.oidc.web/src/main/java/de/srsoftware/oidc/web/Forward.java index aa915ab..f9136e3 100644 --- a/de.srsoftware.oidc.web/src/main/java/de/srsoftware/oidc/web/Forward.java +++ b/de.srsoftware.oidc.web/src/main/java/de/srsoftware/oidc/web/Forward.java @@ -14,10 +14,10 @@ public class Forward extends PathHandler { } @Override - public void handle(HttpExchange ex) throws IOException { - System.out.printf("Forwarding (%d) %s to %s…\n", CODE, ex.getRequestURI(), toPath); + public boolean doGet(String path, HttpExchange ex) throws IOException { + System.out.printf("Forwarding (%d) %s to %s…\n", CODE, path, toPath); ex.getResponseHeaders().add("Location", toPath); ex.sendResponseHeaders(CODE, 0); - ex.getResponseBody().close(); + return true; } } diff --git a/de.srsoftware.oidc.web/src/main/java/de/srsoftware/oidc/web/StaticPages.java b/de.srsoftware.oidc.web/src/main/java/de/srsoftware/oidc/web/StaticPages.java index 84e14ed..ea0c9c0 100644 --- a/de.srsoftware.oidc.web/src/main/java/de/srsoftware/oidc/web/StaticPages.java +++ b/de.srsoftware.oidc.web/src/main/java/de/srsoftware/oidc/web/StaticPages.java @@ -1,11 +1,12 @@ /* © SRSoftware 2024 */ package de.srsoftware.oidc.web; +import static java.net.HttpURLConnection.HTTP_NOT_FOUND; + import com.sun.net.httpserver.HttpExchange; import de.srsoftware.oidc.api.PathHandler; import java.io.FileNotFoundException; import java.io.IOException; -import java.io.OutputStream; import java.net.MalformedURLException; import java.net.URL; import java.nio.file.Files; @@ -14,6 +15,7 @@ import java.util.Optional; public class StaticPages extends PathHandler { private static final String DEFAULT_LANGUAGE = "en"; + private static final String FAVICON = "favicon.ico"; private final Optional base; private ClassLoader loader; @@ -27,27 +29,22 @@ public class StaticPages extends PathHandler { private static final String INDEX = "en/index.html"; @Override - public void handle(HttpExchange ex) throws IOException { - String relativePath = relativePath(ex); - String lang = language(ex).orElse(DEFAULT_LANGUAGE); - String method = ex.getRequestMethod(); - - if (relativePath.isBlank()) relativePath = INDEX; - System.out.printf("%s %s: ", method, ex.getRequestURI()); + public boolean doGet(String relativePath, HttpExchange ex) throws IOException { + String lang = language(ex).orElse(DEFAULT_LANGUAGE); + if (relativePath.startsWith("/")) relativePath = relativePath.substring(1); + if (relativePath.isBlank()) { + relativePath = ex.getRequestURI().toString().endsWith(FAVICON) ? FAVICON : INDEX; + } try { - System.out.printf("Loading %s for lagnuage %s…", relativePath, lang); + System.out.printf("Loading %s for language %s…", relativePath, lang); Response response = loadFile(lang, relativePath).orElseThrow(() -> new FileNotFoundException()); ex.getResponseHeaders().add(CONTENT_TYPE, response.contentType); - ex.sendResponseHeaders(200, response.content.length); - OutputStream os = ex.getResponseBody(); - os.write(response.content); - os.close(); System.out.println("success."); + return sendContent(ex, response.content); } catch (FileNotFoundException fnf) { - ex.sendResponseHeaders(404, 0); - ex.getResponseBody().close(); System.err.println("failed!"); + return sendEmptyResponse(HTTP_NOT_FOUND, ex); } } diff --git a/de.srsoftware.oidc.web/src/main/resources/en/authorization.html b/de.srsoftware.oidc.web/src/main/resources/en/authorization.html new file mode 100644 index 0000000..e6f76e7 --- /dev/null +++ b/de.srsoftware.oidc.web/src/main/resources/en/authorization.html @@ -0,0 +1,13 @@ + + + + Light OIDC + + + + + +

Authorization!

+Not implemented, yet! + + \ No newline at end of file diff --git a/de.srsoftware.oidc.web/src/main/resources/en/authorization.js b/de.srsoftware.oidc.web/src/main/resources/en/authorization.js new file mode 100644 index 0000000..d8d1816 --- /dev/null +++ b/de.srsoftware.oidc.web/src/main/resources/en/authorization.js @@ -0,0 +1,11 @@ +var params = new URLSearchParams(window.location.search) +var json = Object.fromEntries(params); + +fetch(api+"/authorize",{ + method: 'POST', + body: JSON.stringify(json), + headers: { + 'Content-Type': 'application/json' + } +}) + diff --git a/de.srsoftware.oidc.web/src/main/resources/en/favicon.ico b/de.srsoftware.oidc.web/src/main/resources/en/favicon.ico new file mode 100644 index 0000000000000000000000000000000000000000..bc646058ccb11116b06849f851192a4680a072d5 GIT binary patch literal 15406 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 + Light OIDC - +

Welcome!

+

Connected sites

+ These are sites that are connected with your account: + + + + + + + + +
SiteActions
+ +
\ No newline at end of file diff --git a/de.srsoftware.oidc.web/src/main/resources/en/index.js b/de.srsoftware.oidc.web/src/main/resources/en/index.js deleted file mode 100644 index 5b558c9..0000000 --- a/de.srsoftware.oidc.web/src/main/resources/en/index.js +++ /dev/null @@ -1,7 +0,0 @@ -const UNAUTHORIZED = 401; - -function handleUser(response){ - console.log(response); -} - -fetch(api+"/user").then(handleUser); \ No newline at end of file diff --git a/de.srsoftware.oidc.web/src/main/resources/en/login.html b/de.srsoftware.oidc.web/src/main/resources/en/login.html index 81a4195..b50619f 100644 --- a/de.srsoftware.oidc.web/src/main/resources/en/login.html +++ b/de.srsoftware.oidc.web/src/main/resources/en/login.html @@ -1,25 +1,24 @@ + Light OIDC - +

Login

-
-
- User credentials +
+ User credentials -
- +
\ No newline at end of file diff --git a/de.srsoftware.oidc.web/src/main/resources/en/login.js b/de.srsoftware.oidc.web/src/main/resources/en/login.js new file mode 100644 index 0000000..48f35e5 --- /dev/null +++ b/de.srsoftware.oidc.web/src/main/resources/en/login.js @@ -0,0 +1,33 @@ +async function handleLogin(response){ + if (response.ok){ + var body = await response.json(); + + setTimeout(doRedirect,100); + } + return false; +} + +function doRedirect(){ + let params = new URL(document.location.toString()).searchParams; + let redirect = params.get("return_to") || 'index.html'; + window.location.href = redirect,true; + return false; +} + +function tryLogin(){ + document.getElementById("error").innerHTML = ""; + var username = document.getElementById('username').value; + var password = document.getElementById('password').value; + fetch(api+"/login",{ + method: 'POST', + headers: { + Accept: 'application/json', + 'Content-Type': 'application/json' + }, + body: JSON.stringify({ + username : username, + password : password + }) + }).then(handleLogin); + return false; +} \ No newline at end of file diff --git a/de.srsoftware.oidc.web/src/main/resources/en/newclient.html b/de.srsoftware.oidc.web/src/main/resources/en/newclient.html new file mode 100644 index 0000000..0e5f512 --- /dev/null +++ b/de.srsoftware.oidc.web/src/main/resources/en/newclient.html @@ -0,0 +1,28 @@ + + + + Light OIDC + + + + +

Add new client

+
+ Settings + + + + + + + + + + + + + +
client name
client secret
redirect urls
+
+ + \ No newline at end of file diff --git a/de.srsoftware.oidc.web/src/main/resources/en/user.js b/de.srsoftware.oidc.web/src/main/resources/en/user.js new file mode 100644 index 0000000..c92a9ef --- /dev/null +++ b/de.srsoftware.oidc.web/src/main/resources/en/user.js @@ -0,0 +1,12 @@ +const UNAUTHORIZED = 401; + +async function handleUser(response){ + if (response.status == UNAUTHORIZED) { + window.location.href = 'login.html?return_to='+encodeURI(window.location.href); + return; + } + var user = await response.json(); + // TODO: load navigation +} + +fetch(api+"/user",{method:'POST'}).then(handleUser); \ No newline at end of file