diff --git a/li.strolch.rest/src/main/java/li/strolch/rest/RestfulStrolchComponent.java b/li.strolch.rest/src/main/java/li/strolch/rest/RestfulStrolchComponent.java index f943a78b3..d2ff43497 100644 --- a/li.strolch.rest/src/main/java/li/strolch/rest/RestfulStrolchComponent.java +++ b/li.strolch.rest/src/main/java/li/strolch/rest/RestfulStrolchComponent.java @@ -43,6 +43,7 @@ public class RestfulStrolchComponent extends StrolchComponent { private static final String PARAM_HTTP_CACHE_MODE = "httpCacheMode"; //$NON-NLS-1$ private static final String PARAM_SECURE_COOKIE = "secureCookie"; //$NON-NLS-1$ private static final String PARAM_COOKIE_MAX_AGE = "cookieMaxAge"; //$NON-NLS-1$ + private static final String PARAM_BASIC_AUTH_ENABLED = "basicAuthEnabled"; //$NON-NLS-1$ /** * Allowed values: @@ -79,6 +80,7 @@ public class RestfulStrolchComponent extends StrolchComponent { private boolean restLoggingEntity; private boolean secureCookie; private int cookieMaxAge; + private boolean basicAuthEnabled; private String webPath; @@ -150,6 +152,13 @@ public class RestfulStrolchComponent extends StrolchComponent { return this.cookieMaxAge; } + /** + * @return the basicAuthEnabled + */ + public boolean isBasicAuthEnabled() { + return this.basicAuthEnabled; + } + @Override public void initialize(ComponentConfiguration configuration) throws Exception { @@ -177,6 +186,7 @@ public class RestfulStrolchComponent extends StrolchComponent { this.secureCookie = configuration.getBoolean(PARAM_SECURE_COOKIE, true); this.cookieMaxAge = configuration.getInt(PARAM_COOKIE_MAX_AGE, (int) TimeUnit.DAYS.toSeconds(1)); + this.basicAuthEnabled = configuration.getBoolean(PARAM_BASIC_AUTH_ENABLED, true); logger.info( "Cookie max age is " + this.cookieMaxAge + "s and is " + (this.secureCookie ? "secure" : "not secure")); diff --git a/li.strolch.rest/src/main/java/li/strolch/rest/filters/AuthenticationRequestFilter.java b/li.strolch.rest/src/main/java/li/strolch/rest/filters/AuthenticationRequestFilter.java index bbdc7c10c..51c117aac 100644 --- a/li.strolch.rest/src/main/java/li/strolch/rest/filters/AuthenticationRequestFilter.java +++ b/li.strolch.rest/src/main/java/li/strolch/rest/filters/AuthenticationRequestFilter.java @@ -17,6 +17,7 @@ package li.strolch.rest.filters; import static li.strolch.rest.StrolchRestfulConstants.STROLCH_CERTIFICATE; import static li.strolch.rest.StrolchRestfulConstants.STROLCH_REQUEST_SOURCE; +import static li.strolch.utils.helper.StringHelper.isEmpty; import static li.strolch.utils.helper.StringHelper.isNotEmpty; import javax.annotation.Priority; @@ -39,7 +40,6 @@ import li.strolch.privilege.model.Usage; import li.strolch.rest.RestfulStrolchComponent; import li.strolch.rest.StrolchRestfulConstants; import li.strolch.rest.StrolchSessionHandler; -import li.strolch.utils.helper.StringHelper; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -155,41 +155,66 @@ public class AuthenticationRequestFilter implements ContainerRequestFilter { protected Certificate validateSession(ContainerRequestContext requestContext, String remoteIp) { String authorization = requestContext.getHeaderString(HttpHeaders.AUTHORIZATION); - if (StringHelper.isEmpty(authorization)) { + authorization = authorization.trim(); - Cookie cookie = requestContext.getCookies().get(StrolchRestfulConstants.STROLCH_AUTHORIZATION); - if (cookie == null) { - logger.error( - "No Authorization header or cookie on request to URL " + requestContext.getUriInfo().getPath()); - requestContext.abortWith(Response.status(Response.Status.FORBIDDEN) - .header(HttpHeaders.CONTENT_TYPE, MediaType.TEXT_PLAIN) - .entity("Missing Authorization!") //$NON-NLS-1$ - .build()); - return null; - } - - String sessionId = cookie.getValue(); - if (StringHelper.isEmpty(sessionId)) { - logger.error("Authorization Cookie value missing on request to URL " + requestContext.getUriInfo() - .getPath()); - requestContext.abortWith(Response.status(Response.Status.FORBIDDEN) - .header(HttpHeaders.CONTENT_TYPE, MediaType.TEXT_PLAIN) - .entity("Missing Authorization!") //$NON-NLS-1$ - .build()); - return null; - } - - return validateCertificate(requestContext, sessionId, remoteIp); + if (isEmpty(authorization) || (authorization.startsWith("Basic ") && !getRestful().isBasicAuthEnabled())) { + return validateCookie(requestContext, remoteIp); } - authorization = authorization.trim(); - if (authorization.startsWith("Basic ")) { - return authenticateBasic(requestContext, authorization, remoteIp); + boolean basicAuth = authorization.startsWith("Basic "); + if (basicAuth) { + + // do basic auth, if enabled + if (getRestful().isBasicAuthEnabled()) + return authenticateBasic(requestContext, authorization, remoteIp); + + // otherwise see if we can do cookie auth + String sessionId = getSessionIdFromCookie(requestContext); + if (!sessionId.isEmpty()) + return validateCertificate(requestContext, sessionId, remoteIp); + + logger.error("Basic Auth not enabled. Can not process URL " + requestContext.getUriInfo().getPath()); + requestContext.abortWith( + Response.status(Response.Status.FORBIDDEN).header(HttpHeaders.CONTENT_TYPE, MediaType.TEXT_PLAIN) + .entity("Basic Auth not enabled") //$NON-NLS-1$ + .build()); + return null; } return validateCertificate(requestContext, authorization, remoteIp); } + private String getSessionIdFromCookie(ContainerRequestContext requestContext) { + Cookie cookie = requestContext.getCookies().get(StrolchRestfulConstants.STROLCH_AUTHORIZATION); + if (cookie == null) + return ""; + + String sessionId = cookie.getValue(); + if (sessionId == null) + return ""; + + return sessionId.trim(); + } + + private Certificate validateCookie(ContainerRequestContext requestContext, String remoteIp) { + String sessionId = getSessionIdFromCookie(requestContext); + if (isEmpty(sessionId)) { + logger.error( + "No Authorization header or cookie on request to URL " + requestContext.getUriInfo().getPath()); + requestContext.abortWith( + Response.status(Response.Status.FORBIDDEN).header(HttpHeaders.CONTENT_TYPE, MediaType.TEXT_PLAIN) + .entity("Missing Authorization!") //$NON-NLS-1$ + .build()); + return null; + } + + return validateCertificate(requestContext, sessionId, remoteIp); + } + + private RestfulStrolchComponent getRestful() { + return RestfulStrolchComponent.getInstance(); + } + private Certificate authenticateBasic(ContainerRequestContext requestContext, String authorization, String remoteIp) { String basicAuth = authorization.substring("Basic ".length()); @@ -204,8 +229,9 @@ public class AuthenticationRequestFilter implements ContainerRequestFilter { } logger.info("Performing basic auth for user " + parts[0] + "..."); - StrolchSessionHandler sessionHandler = RestfulStrolchComponent.getInstance().getSessionHandler(); - Certificate certificate = sessionHandler.authenticate(parts[0], parts[1].toCharArray(), remoteIp, Usage.SINGLE, false); + StrolchSessionHandler sessionHandler = getSessionHandler(); + Certificate certificate = sessionHandler + .authenticate(parts[0], parts[1].toCharArray(), remoteIp, Usage.SINGLE, false); requestContext.setProperty(STROLCH_CERTIFICATE, certificate); requestContext.setProperty(STROLCH_REQUEST_SOURCE, remoteIp); @@ -213,8 +239,12 @@ public class AuthenticationRequestFilter implements ContainerRequestFilter { return certificate; } + private StrolchSessionHandler getSessionHandler() { + return getRestful().getSessionHandler(); + } + private Certificate validateCertificate(ContainerRequestContext requestContext, String sessionId, String remoteIp) { - StrolchSessionHandler sessionHandler = RestfulStrolchComponent.getInstance().getSessionHandler(); + StrolchSessionHandler sessionHandler = getSessionHandler(); Certificate certificate = sessionHandler.validate(sessionId, remoteIp); requestContext.setProperty(STROLCH_CERTIFICATE, certificate);