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 8d46db7..fd13ee2 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 @@ -3,63 +3,69 @@ package de.srsoftware.oidc.api; public class Constants { - public static final String ACCESS_TOKEN = "access_token"; - public static final String APP_NAME = "LightOIDC"; - public static final String AT_HASH = "at_hash"; - public static final String ATTEMPTS = "attempts"; - public static final String AUTH_CODE = "authorization_code"; - public static final String AUTHORZED = "authorized"; - public static final String BEARER = "Bearer"; - public static final String CAUSE = "cause"; - 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 EMAIL = "email"; - 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 ENCRYPTION_KEY = "encryption_key"; - public static final String ERROR_DESCRIPTION = "error_description"; - public static final String ERROR_LOCKED = "error_locked"; - public static final String ERROR_LOGIN_FAILED = "error_login_failed"; - public static final String ERROR_NO_USERNAME = "error_no_username"; - 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_CLIENT = "invalid_client"; - public static final String INVALID_GRANT = "invalid_grant"; - 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 LANDING_PAGE = "landing_page"; - public static final String MAILCONFIG = "mail_config"; - public static final String NAME = "name"; - public static final String NONCE = "nonce"; - public static final String PERMISSION = "permission"; - 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 RELEASE = "release"; - public static final String REQUEST_NOT_SUPPORTED = "request_not_supported"; - public static final String RESPONSE_TYPE = "response_type"; - public static final String SALT = "salt"; - public static final String SCOPE = "scope"; - public static final String SECRET = "secret"; - public static final String SESSION_DURATION = "session_duration"; - public static final String SMTP_USER = "smtp_user"; - public static final String SMTP_PASSWORD = "smtp_pass"; - public static final String SMTP_AUTH = "smtp_auth"; - public static final String SMTP_HOST = "smtp_host"; - public static final String SMTP_PORT = "smtp_port"; - public static final String STATE = "state"; - public static final String START_TLS = "start_tls"; - public static final String TOKEN = "token"; - public static final String TOKEN_TYPE = "token_type"; - public static final String TRUST = "trust"; - public static final String UNAUTHORIZED_CLIENT = "unauthorized_client"; - public static final String USER = "user"; - public static final String USER_ID = "user_id"; + public static final String ACCESS_TOKEN = "access_token"; + public static final String APP_NAME = "LightOIDC"; + public static final String AT_HASH = "at_hash"; + public static final String ATTEMPTS = "attempts"; + public static final String AUTH_CODE = "authorization_code"; + public static final String AUTHORZED = "authorized"; + public static final String BEARER = "Bearer"; + public static final String CAUSE = "cause"; + 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 EMAIL = "email"; + 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 ENCRYPTION_KEY = "encryption_key"; + public static final String ERROR_DESCRIPTION = "error_description"; + public static final String ERROR_INVALID_REDIRECT = "error_invalid_redirect"; + public static final String ERROR_LOCKED = "error_locked"; + public static final String ERROR_LOGIN_FAILED = "error_login_failed"; + public static final String ERROR_MISSING_PARAMETER = "error_missing_parameter"; + public static final String ERROR_MISSONG_CODE_RESPONSE_TYPE = "error_missing_code"; + public static final String ERROR_NO_USERNAME = "error_no_username"; + public static final String ERROR_UNKNOWN_CLIENT = "error_unknown_client"; + public static final String ERROR_UNSUPPORTED_RESPONSE_TYPE = "error_unsupported_response_type"; + 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_CLIENT = "invalid_client"; + public static final String INVALID_GRANT = "invalid_grant"; + 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 LANDING_PAGE = "landing_page"; + public static final String MAILCONFIG = "mail_config"; + public static final String NAME = "name"; + public static final String NONCE = "nonce"; + public static final String PARAM = "parameter"; + public static final String PERMISSION = "permission"; + 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 RELEASE = "release"; + public static final String REQUEST_NOT_SUPPORTED = "request_not_supported"; + public static final String RESPONSE_TYPE = "response_type"; + public static final String SALT = "salt"; + public static final String SCOPE = "scope"; + public static final String SECRET = "secret"; + public static final String SESSION_DURATION = "session_duration"; + public static final String SMTP_USER = "smtp_user"; + public static final String SMTP_PASSWORD = "smtp_pass"; + public static final String SMTP_AUTH = "smtp_auth"; + public static final String SMTP_HOST = "smtp_host"; + public static final String SMTP_PORT = "smtp_port"; + public static final String STATE = "state"; + public static final String START_TLS = "start_tls"; + public static final String TOKEN = "token"; + public static final String TOKEN_TYPE = "token_type"; + public static final String TRUST = "trust"; + public static final String UNAUTHORIZED_CLIENT = "unauthorized_client"; + public static final String USER = "user"; + public static final String USER_ID = "user_id"; } 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 7770695..eff94a9 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 @@ -3,7 +3,6 @@ package de.srsoftware.oidc.backend; import static de.srsoftware.oidc.api.Constants.*; import static de.srsoftware.oidc.api.data.Permission.MANAGE_CLIENTS; -import static de.srsoftware.utils.Optionals.emptyIfBlank; import static java.net.HttpURLConnection.*; import com.sun.net.httpserver.HttpExchange; @@ -12,6 +11,7 @@ import de.srsoftware.oidc.api.data.AuthorizedScopes; import de.srsoftware.oidc.api.data.Client; import de.srsoftware.oidc.api.data.Session; import de.srsoftware.oidc.api.data.User; +import de.srsoftware.utils.Error; import de.srsoftware.utils.Optionals; import java.io.IOException; import java.time.Instant; @@ -32,13 +32,6 @@ public class ClientController extends Controller { users = userService; } - private boolean authorizationError(HttpExchange ex, String errorCode, String description, String state) throws IOException { - var map = new HashMap(); - map.put(ERROR, errorCode); - emptyIfBlank(description).ifPresent(d -> map.put(ERROR_DESCRIPTION, d)); - emptyIfBlank(state).ifPresent(s -> map.put(STATE, s)); - return badRequest(ex, map); - } private boolean authorize(HttpExchange ex, Session session) throws IOException { var optUser = users.load(session.userId()); @@ -46,34 +39,30 @@ public class ClientController extends Controller { var user = optUser.get(); var json = json(ex); 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); + if (!json.has(CLIENT_ID)) return badRequest(ex, Error.message(ERROR_MISSING_PARAMETER, PARAM, CLIENT_ID, STATE, 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); - + if (optClient.isEmpty()) return badRequest(ex, Error.message(ERROR_UNKNOWN_CLIENT, CLIENT_ID, clientId, STATE, 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); + if (!json.has(param)) return badRequest(ex, Error.message(ERROR_MISSING_PARAMETER, PARAM, param, STATE, state)); } var scopes = toList(json, SCOPE); - if (!scopes.contains(OPENID)) return authorizationError(ex, INVALID_SCOPE, "This is an OpenID Provider. You should request \"openid\" scope!", state); + if (!scopes.contains(OPENID)) return badRequest(ex, Error.message(ERROR_MISSING_PARAMETER, PARAM, "Scope: openid", STATE, state)); var responseTypes = toList(json, RESPONSE_TYPE); for (var responseType : responseTypes) { switch (responseType) { - case ID_TOKEN: - case TOKEN: - return authorizationError(ex, REQUEST_NOT_SUPPORTED, "Response type \"%s\" currently not supported".formatted(responseType), state); case CODE: break; default: - return authorizationError(ex, INVALID_REQUEST_OBJECT, "Unknown response type \"%s\"".formatted(responseType), state); + return badRequest(ex, Error.message(ERROR_UNSUPPORTED_RESPONSE_TYPE, RESPONSE_TYPE, responseType, STATE, state)); } } - if (!responseTypes.contains(CODE)) return authorizationError(ex, REQUEST_NOT_SUPPORTED, "Sorry, at the moment I can only handle \"%s\" response type".formatted(CODE), state); + if (!responseTypes.contains(CODE)) return badRequest(ex, Error.message(ERROR_MISSONG_CODE_RESPONSE_TYPE, STATE, state)); var client = optClient.get(); var redirect = json.getString(REDIRECT_URI); - if (!client.redirectUris().contains(redirect)) authorizationError(ex, INVALID_REDIRECT_URI, "unknown redirect uri: %s".formatted(redirect), state); + if (!client.redirectUris().contains(redirect)) return badRequest(ex, Error.message(ERROR_INVALID_REDIRECT, REDIRECT_URI, redirect, STATE, state)); if (json.has(AUTHORZED)) { // user did consent var authorized = json.getJSONObject(AUTHORZED); 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 72b7c54..847d20d 100644 --- a/de.srsoftware.oidc.web/src/main/resources/en/authorization.html +++ b/de.srsoftware.oidc.web/src/main/resources/en/authorization.html @@ -22,7 +22,21 @@ - +
+ Request does not contain required parameter ""! +
+
+ Client "" unknown to backend! +
+
+ Response type "" not supported! +
+
+ Missing response type: code +
+
+ invalid redirect: +
\ No newline at end of file diff --git a/de.srsoftware.oidc.web/src/main/resources/en/scripts/authorization.js b/de.srsoftware.oidc.web/src/main/resources/en/scripts/authorization.js index 918de18..d88c4b9 100644 --- a/de.srsoftware.oidc.web/src/main/resources/en/scripts/authorization.js +++ b/de.srsoftware.oidc.web/src/main/resources/en/scripts/authorization.js @@ -18,6 +18,7 @@ function showScope(response,scope){ } function handleResponse(response){ + hideAll('error'); if (response.ok){ response.json().then(json => { if (json.rp) { @@ -43,19 +44,23 @@ function handleResponse(response){ }); } else { console.log("handleResponse(…) ← ",response); - if (response.status == 401){ + if (response.status == 401){ // unauthorized login(); return; } response.json().then(json => { - setText('error',"Error:
"+json.error_description); - show('error'); + console.log("handleResponse → error",json); + if (json.error) show(json.error); + if (json.metadata.client_id) setText('client_id',json.metadata.client_id); + if (json.metadata.parameter) setText('parameter',json.metadata.parameter); + if (json.metadata.redirect_uri) setText('redirect_uri',json.metadata.redirect_uri); + if (json.metadata.response_type)setText('response_type',json.metadata.response_type) }); - if (json.error != "invalid_request_uri"){ + /*if (json.error != "invalid_request_uri"){ var url = params.get('redirect_uri') + '?' + new URLSearchParams(json).toString(); console.log('redirecting to '+url); redirect(url); - } + }*/ } }