diff --git a/de.srsoftware.oidc.api/src/main/java/de/srsoftware/oidc/api/Constants.java b/de.srsoftware.oidc.api/src/main/java/de/srsoftware/oidc/api/Constants.java index 521b10a..76e15c5 100644 --- a/de.srsoftware.oidc.api/src/main/java/de/srsoftware/oidc/api/Constants.java +++ b/de.srsoftware.oidc.api/src/main/java/de/srsoftware/oidc/api/Constants.java @@ -12,18 +12,25 @@ public class Constants { public static final String CLIENT_ID = "client_id"; public static final String CLIENT_SECRET = "client_secret"; public static final String CODE = "code"; + public static final String ERROR = "error"; public static final String CONFIG_PATH = "LIGHTOIDC_CONFIG_PATH"; public static final String CONFIRMED = "confirmed"; public static final String DAYS = "days"; + public static final String ERROR_DESCRIPTION = "error_description"; public static final String EXPIRATION = "expiration"; public static final String EXPIRES_IN = "expires_in"; public static final String GRANT_TYPE = "grant_type"; public static final String ID_TOKEN = "id_token"; + public static final String INVALID_REDIRECT_URI = "invalid_request_uri"; + public static final String INVALID_REQUEST = "invalid_request"; + public static final String INVALID_REQUEST_OBJECT = "invalid_request_object"; + public static final String INVALID_SCOPE = "invalid_scope"; public static final String NAME = "name"; public static final String NONCE = "nonce"; public static final String OPENID = "openid"; public static final String REDIRECT_URI = "redirect_uri"; public static final String REDIRECT_URIS = "redirect_uris"; + public static final String REQUEST_NOT_SUPPORTED = "request_not_supported"; public static final String RESPONSE_TYPE = "response_type"; public static final String SCOPE = "scope"; public static final String SECRET = "secret"; diff --git a/de.srsoftware.oidc.backend/src/main/java/de/srsoftware/oidc/backend/ClientController.java b/de.srsoftware.oidc.backend/src/main/java/de/srsoftware/oidc/backend/ClientController.java index a73b237..647a2f3 100644 --- a/de.srsoftware.oidc.backend/src/main/java/de/srsoftware/oidc/backend/ClientController.java +++ b/de.srsoftware.oidc.backend/src/main/java/de/srsoftware/oidc/backend/ClientController.java @@ -25,36 +25,45 @@ public class ClientController extends Controller { clients = clientService; } + private boolean authorizationError(HttpExchange ex, String errorCode, String description, String state) throws IOException { + var map = new HashMap(); + map.put(ERROR,errorCode); + if (description != null) map.put(ERROR_DESCRIPTION,description); + if (state != null) map.put(STATE,state); + return badRequest(ex,map); + } private boolean authorize(HttpExchange ex, Session session) throws IOException { var user = session.user(); var json = json(ex); - for (String param : List.of(SCOPE, RESPONSE_TYPE, CLIENT_ID, REDIRECT_URI)) { - if (!json.has(param)) return badRequest(ex, "Missing required parameter \"%s\"!".formatted(param)); + var state = json.has(STATE) ? json.getString(STATE) : null; + if (!json.has(CLIENT_ID)) return authorizationError(ex, INVALID_REQUEST,"Missing required parameter \"%s\"!".formatted(CLIENT_ID),state); + var clientId = json.getString(CLIENT_ID); + var optClient = clients.getClient(clientId); + if (optClient.isEmpty()) return authorizationError(ex,INVALID_REQUEST_OBJECT,"unknown client: %s".formatted(clientId),state); + + for (String param : List.of(SCOPE, RESPONSE_TYPE, REDIRECT_URI)) { + if (!json.has(param)) return authorizationError(ex,INVALID_REQUEST,"Missing required parameter \"%s\"!".formatted(param),state); } var scopes = toList(json, SCOPE); - if (!scopes.contains(OPENID)) return badRequest(ex, "This is an OpenID Provider. You should request \"openid\" scope!"); + if (!scopes.contains(OPENID)) return authorizationError(ex,INVALID_SCOPE,"This is an OpenID Provider. You should request \"openid\" scope!",state); var responseTypes = toList(json, RESPONSE_TYPE); for (var responseType : responseTypes) { switch (responseType) { case ID_TOKEN: case TOKEN: - return sendContent(ex, HTTP_NOT_IMPLEMENTED, "Response type \"%s\" currently not supported".formatted(responseType)); + return authorizationError(ex, REQUEST_NOT_SUPPORTED, "Response type \"%s\" currently not supported".formatted(responseType),state); case CODE: break; default: - return badRequest(ex, "Unknown response type \"%s\"".formatted(responseType)); + return authorizationError(ex,INVALID_REQUEST_OBJECT,"Unknown response type \"%s\"".formatted(responseType),state); } } - if (!responseTypes.contains(CODE)) return badRequest(ex, "Sorry, at the moment I can only handle \"%s\" response type".formatted(CODE)); + if ( !responseTypes.contains(CODE)) return authorizationError(ex, REQUEST_NOT_SUPPORTED, "Sorry, at the moment I can only handle \"%s\" response type".formatted(CODE),state); - var clientId = json.getString(CLIENT_ID); - var optClient = clients.getClient(clientId); - if (optClient.isEmpty()) return badRequest(ex, Map.of(CAUSE, "unknown client", CLIENT_ID, clientId)); var client = optClient.get(); var redirect = json.getString(REDIRECT_URI); - if (!client.redirectUris().contains(redirect)) return badRequest(ex, Map.of(CAUSE, "unknown redirect uri", REDIRECT_URI, redirect)); - var state = json.has(STATE) ? json.getString(STATE) : null; + if (!client.redirectUris().contains(redirect)) authorizationError(ex, INVALID_REDIRECT_URI, "unknown redirect uri: %s".formatted(redirect),state); client.nonce(json.has(NONCE) ? json.getString(NONCE) : null); if (json.has(AUTHORZED)) { @@ -69,9 +78,9 @@ public class ClientController extends Controller { if (!authResult.unauthorizedScopes().isEmpty()) { return sendContent(ex, Map.of("unauthorized_scopes", authResult.unauthorizedScopes(), "rp", client.name())); } - var authoriedScopes = authResult.authorizedScopes().stream().map(AuthorizedScope::scope).collect(Collectors.joining(" ")); + var authorizedScopes = authResult.authorizedScopes().stream().map(AuthorizedScope::scope).collect(Collectors.joining(" ")); var result = new HashMap(); - result.put(SCOPE, authoriedScopes); + result.put(SCOPE, authorizedScopes); result.put(CODE, authResult.authCode()); if (state != null) result.put(STATE, state); return sendContent(ex, result); diff --git a/de.srsoftware.oidc.web/src/main/resources/de/clients.html b/de.srsoftware.oidc.web/src/main/resources/de/clients.html index d7f7a4d..7642134 100644 --- a/de.srsoftware.oidc.web/src/main/resources/de/clients.html +++ b/de.srsoftware.oidc.web/src/main/resources/de/clients.html @@ -2,9 +2,9 @@ Light OIDC - - - + + + diff --git a/de.srsoftware.oidc.web/src/main/resources/de/navigation.html b/de.srsoftware.oidc.web/src/main/resources/de/navigation.html index e2edea2..75f6d98 100644 --- a/de.srsoftware.oidc.web/src/main/resources/de/navigation.html +++ b/de.srsoftware.oidc.web/src/main/resources/de/navigation.html @@ -1,5 +1,6 @@ Übersicht Clients Benutzer +Spec Einstellungen Ausloggen diff --git a/de.srsoftware.oidc.web/src/main/resources/en/authorization.html b/de.srsoftware.oidc.web/src/main/resources/en/authorization.html index 3ca0571..0a8bf95 100644 --- a/de.srsoftware.oidc.web/src/main/resources/en/authorization.html +++ b/de.srsoftware.oidc.web/src/main/resources/en/authorization.html @@ -2,9 +2,9 @@ Light OIDC - - - + + + diff --git a/de.srsoftware.oidc.web/src/main/resources/en/clients.html b/de.srsoftware.oidc.web/src/main/resources/en/clients.html index 9887835..7cdf32d 100644 --- a/de.srsoftware.oidc.web/src/main/resources/en/clients.html +++ b/de.srsoftware.oidc.web/src/main/resources/en/clients.html @@ -2,9 +2,9 @@ Light OIDC - - - + + + diff --git a/de.srsoftware.oidc.web/src/main/resources/en/edit_client.html b/de.srsoftware.oidc.web/src/main/resources/en/edit_client.html index 0c63311..0563937 100644 --- a/de.srsoftware.oidc.web/src/main/resources/en/edit_client.html +++ b/de.srsoftware.oidc.web/src/main/resources/en/edit_client.html @@ -2,9 +2,9 @@ Light OIDC - - - + + + diff --git a/de.srsoftware.oidc.web/src/main/resources/en/index.html b/de.srsoftware.oidc.web/src/main/resources/en/index.html index 59912f4..124754f 100644 --- a/de.srsoftware.oidc.web/src/main/resources/en/index.html +++ b/de.srsoftware.oidc.web/src/main/resources/en/index.html @@ -2,8 +2,8 @@ Light OIDC - - + + 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 29245ba..41e948e 100644 --- a/de.srsoftware.oidc.web/src/main/resources/en/login.html +++ b/de.srsoftware.oidc.web/src/main/resources/en/login.html @@ -2,8 +2,8 @@ Light OIDC - - + + diff --git a/de.srsoftware.oidc.web/src/main/resources/en/logout.html b/de.srsoftware.oidc.web/src/main/resources/en/logout.html index 0a33e49..f0cbbcf 100644 --- a/de.srsoftware.oidc.web/src/main/resources/en/logout.html +++ b/de.srsoftware.oidc.web/src/main/resources/en/logout.html @@ -2,8 +2,8 @@ Light OIDC - - + + diff --git a/de.srsoftware.oidc.web/src/main/resources/en/navigation.html b/de.srsoftware.oidc.web/src/main/resources/en/navigation.html index 3d85631..e978097 100644 --- a/de.srsoftware.oidc.web/src/main/resources/en/navigation.html +++ b/de.srsoftware.oidc.web/src/main/resources/en/navigation.html @@ -1,5 +1,6 @@ Dashboard Clients Users +Spec Settings Logout diff --git a/de.srsoftware.oidc.web/src/main/resources/en/new_client.html b/de.srsoftware.oidc.web/src/main/resources/en/new_client.html index a0290b5..97c4db6 100644 --- a/de.srsoftware.oidc.web/src/main/resources/en/new_client.html +++ b/de.srsoftware.oidc.web/src/main/resources/en/new_client.html @@ -2,9 +2,9 @@ Light OIDC - - - + + + diff --git a/de.srsoftware.oidc.web/src/main/resources/en/authorization.js b/de.srsoftware.oidc.web/src/main/resources/en/scripts/authorization.js similarity index 78% rename from de.srsoftware.oidc.web/src/main/resources/en/authorization.js rename to de.srsoftware.oidc.web/src/main/resources/en/scripts/authorization.js index b319459..c71fe12 100644 --- a/de.srsoftware.oidc.web/src/main/resources/en/authorization.js +++ b/de.srsoftware.oidc.web/src/main/resources/en/scripts/authorization.js @@ -39,14 +39,19 @@ async function handleResponse(response){ } show('missing_scopes'); } else { - console.log(response); + console.log("handleResponse(…) ← ",response); if (response.status == 401){ login(); return; } - var text = await response.text(); - setText('error',"Error:
"+text); + var json = await response.json(); + setText('error',"Error:
"+json.error_description); show('error'); + if (json.error != "invalid_request_uri"){ + var url = params.get('redirect_uri') + '?' + new URLSearchParams(json).toString(); + console.log('redirecting to '+url); + redirect(url); + } } } @@ -56,7 +61,7 @@ function grantAutorization(days){ } function denyAutorization(){ - redirect(params.get('redirect_uri')+"?error=access denied"); + redirect(params.get('redirect_uri')+"?error=consent_required"); } function backendAutorization(){ diff --git a/de.srsoftware.oidc.web/src/main/resources/en/clients.js b/de.srsoftware.oidc.web/src/main/resources/en/scripts/clients.js similarity index 100% rename from de.srsoftware.oidc.web/src/main/resources/en/clients.js rename to de.srsoftware.oidc.web/src/main/resources/en/scripts/clients.js diff --git a/de.srsoftware.oidc.web/src/main/resources/en/common.js b/de.srsoftware.oidc.web/src/main/resources/en/scripts/common.js similarity index 100% rename from de.srsoftware.oidc.web/src/main/resources/en/common.js rename to de.srsoftware.oidc.web/src/main/resources/en/scripts/common.js diff --git a/de.srsoftware.oidc.web/src/main/resources/en/edit_client.js b/de.srsoftware.oidc.web/src/main/resources/en/scripts/edit_client.js similarity index 100% rename from de.srsoftware.oidc.web/src/main/resources/en/edit_client.js rename to de.srsoftware.oidc.web/src/main/resources/en/scripts/edit_client.js diff --git a/de.srsoftware.oidc.web/src/main/resources/en/login.js b/de.srsoftware.oidc.web/src/main/resources/en/scripts/login.js similarity index 100% rename from de.srsoftware.oidc.web/src/main/resources/en/login.js rename to de.srsoftware.oidc.web/src/main/resources/en/scripts/login.js diff --git a/de.srsoftware.oidc.web/src/main/resources/en/logout.js b/de.srsoftware.oidc.web/src/main/resources/en/scripts/logout.js similarity index 100% rename from de.srsoftware.oidc.web/src/main/resources/en/logout.js rename to de.srsoftware.oidc.web/src/main/resources/en/scripts/logout.js diff --git a/de.srsoftware.oidc.web/src/main/resources/en/new_client.js b/de.srsoftware.oidc.web/src/main/resources/en/scripts/new_client.js similarity index 100% rename from de.srsoftware.oidc.web/src/main/resources/en/new_client.js rename to de.srsoftware.oidc.web/src/main/resources/en/scripts/new_client.js diff --git a/de.srsoftware.oidc.web/src/main/resources/en/settings.js b/de.srsoftware.oidc.web/src/main/resources/en/scripts/settings.js similarity index 100% rename from de.srsoftware.oidc.web/src/main/resources/en/settings.js rename to de.srsoftware.oidc.web/src/main/resources/en/scripts/settings.js diff --git a/de.srsoftware.oidc.web/src/main/resources/en/user.js b/de.srsoftware.oidc.web/src/main/resources/en/scripts/user.js similarity index 100% rename from de.srsoftware.oidc.web/src/main/resources/en/user.js rename to de.srsoftware.oidc.web/src/main/resources/en/scripts/user.js diff --git a/de.srsoftware.oidc.web/src/main/resources/en/settings.html b/de.srsoftware.oidc.web/src/main/resources/en/settings.html index 116f7b5..0485d4f 100644 --- a/de.srsoftware.oidc.web/src/main/resources/en/settings.html +++ b/de.srsoftware.oidc.web/src/main/resources/en/settings.html @@ -2,9 +2,9 @@ Light OIDC - - - + + +