From ef680a9e6bf4a9f676b38f2eb5c4208bfef80f3f Mon Sep 17 00:00:00 2001 From: Elizio Marcelino Date: Thu, 16 Apr 2015 14:20:24 -0400 Subject: [PATCH] Adds basic authentication handling while performing REST actions Returns HTTP code 401 with the WWW-Authenticate header whenever the checkAccess method throw an ERXBasicAuthenticationException. --- .../rest/ERXBasicAuthenticationException.java | 78 +++++++++++++++++++ .../er/rest/routes/ERXRouteController.java | 6 ++ 2 files changed, 84 insertions(+) create mode 100644 Frameworks/EOF/ERRest/Sources/er/rest/ERXBasicAuthenticationException.java diff --git a/Frameworks/EOF/ERRest/Sources/er/rest/ERXBasicAuthenticationException.java b/Frameworks/EOF/ERRest/Sources/er/rest/ERXBasicAuthenticationException.java new file mode 100644 index 00000000000..75ebb67ad9a --- /dev/null +++ b/Frameworks/EOF/ERRest/Sources/er/rest/ERXBasicAuthenticationException.java @@ -0,0 +1,78 @@ +package er.rest; + + +/** + * Basic Authentication Exception. + * + *

+ * This class responsible for exception when use Basic Authentication. + * + * This exception can be used with checkAcces method of ERXRouteController class. + *

+ * + * Example + * + *
+ * protected void checkAccess() throws SecurityException {
+ *     throw new ERXBasicAuthenticationException("invalid credentials");
+ * }
+ * 
+ */ +public class ERXBasicAuthenticationException extends SecurityException { + + private final String basicRealm; + + /** + * Creates a ERXBasicAuthenticationException with the specified + * detail message and cause. + * + * For @param basicRealm use default 'application'. + * + * @param message the detail message (which is saved for later retrieval + * by the {@link #getMessage()} method). + */ + public ERXBasicAuthenticationException(String message) { + this(message, "application"); + } + + /** + * Creates a ERXBasicAuthenticationException with the specified + * detail message and cause. + * + * @param message the detail message (which is saved for later retrieval + * by the {@link #getMessage()} method). + * @param basicRealm message about server authentication requested for user. + */ + public ERXBasicAuthenticationException(String message, String basicRealm) { + super(message); + + this.basicRealm = basicRealm; + } + + /** + * Creates a ERXBasicAuthenticationException with the specified + * detail message and cause. + * + * @param message the detail message (which is saved for later retrieval + * by the {@link #getMessage()} method). + * @param cause the cause (which is saved for later retrieval by the + * {@link #getCause()} method). (A null value is permitted, + * and indicates that the cause is nonexistent or unknown.) + * @param basicRealm message about server authentication requested for user. + */ + public ERXBasicAuthenticationException(String message, Throwable cause, String basicRealm) { + super(message, cause); + + this.basicRealm = basicRealm; + } + + /** + * Message about server authentication. + * + * @return basicRealm message + */ + public String basicRealm() { + return basicRealm; + } + +} \ No newline at end of file diff --git a/Frameworks/EOF/ERRest/Sources/er/rest/routes/ERXRouteController.java b/Frameworks/EOF/ERRest/Sources/er/rest/routes/ERXRouteController.java index b67ffaf5460..d7fb5a31909 100644 --- a/Frameworks/EOF/ERRest/Sources/er/rest/routes/ERXRouteController.java +++ b/Frameworks/EOF/ERRest/Sources/er/rest/routes/ERXRouteController.java @@ -48,6 +48,7 @@ import er.extensions.foundation.ERXStringUtilities; import er.extensions.localization.ERXLocalizer; import er.extensions.validation.ERXValidationException; +import er.rest.ERXBasicAuthenticationException; import er.rest.ERXNotAllowedException; import er.rest.ERXRequestFormValues; import er.rest.ERXRestClassDescriptionFactory; @@ -1589,6 +1590,11 @@ protected WOActionResults performActionNamedWithError(String actionName, Throwab if (meaningfulThrowble instanceof ObjectNotAvailableException || meaningfulThrowble instanceof FileNotFoundException || meaningfulThrowble instanceof NoSuchElementException) { results = errorResponse(meaningfulThrowble, ERXHttpStatusCodes.NOT_FOUND); } + else if (meaningfulThrowble instanceof ERXBasicAuthenticationException) { + WOResponse response = (WOResponse) errorResponse(meaningfulThrowble, ERXHttpStatusCodes.UNAUTHORIZED); + response.setHeader("Basic realm=\"" + ((ERXBasicAuthenticationException) meaningfulThrowble).basicRealm() + "\"", "WWW-Authenticate"); + results = response; + } else if (meaningfulThrowble instanceof SecurityException) { results = errorResponse(meaningfulThrowble, ERXHttpStatusCodes.STATUS_FORBIDDEN); }