From fba2b09e04269d9e24a7c05a7a28a405ee8872a1 Mon Sep 17 00:00:00 2001 From: Robert von Burg Date: Fri, 4 Dec 2015 15:10:52 +0100 Subject: [PATCH] [New] Also write a cookie when authenticating - and of course allow the user to authenticate using the cookie --- .../strolch/rest/RestfulStrolchComponent.java | 18 ++++++-- .../strolch/rest/StrolchRestfulConstants.java | 1 + .../rest/endpoint/AuthenticationService.java | 10 ++++- .../filters/AuthenicationRequestFilter.java | 41 +++++++++++++------ 4 files changed, 52 insertions(+), 18 deletions(-) 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 899dc2554..09572d252 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 @@ -17,6 +17,9 @@ package li.strolch.rest; import java.text.MessageFormat; +import org.glassfish.jersey.server.ServerProperties; + +import ch.eitchnet.utils.dbc.DBC; import li.strolch.agent.api.ComponentContainer; import li.strolch.agent.api.StrolchAgent; import li.strolch.agent.api.StrolchComponent; @@ -25,10 +28,6 @@ import li.strolch.rest.filters.HttpCacheResponseFilter; import li.strolch.runtime.configuration.ComponentConfiguration; import li.strolch.service.api.ServiceHandler; -import org.glassfish.jersey.server.ServerProperties; - -import ch.eitchnet.utils.dbc.DBC; - /** * @author Robert von Burg */ @@ -39,6 +38,7 @@ public class RestfulStrolchComponent extends StrolchComponent { private static final String PARAM_REST_LOGGING = "restLogging"; //$NON-NLS-1$ private static final String PARAM_REST_LOGGING_ENTITY = "restLoggingEntity"; //$NON-NLS-1$ private static final String PARAM_HTTP_CACHE_MODE = "httpCacheMode"; //$NON-NLS-1$ + private static final String PARAM_SECURE_COOKIE = "secureCookie"; //$NON-NLS-1$ /** * Allowed values: @@ -74,6 +74,7 @@ public class RestfulStrolchComponent extends StrolchComponent { private boolean restLogging; private boolean restLoggingEntity; private String cacheMode; + private boolean secureCookie; /** * @param container @@ -125,6 +126,13 @@ public class RestfulStrolchComponent extends StrolchComponent { return this.restLoggingEntity; } + /** + * @return the secureCookie + */ + public boolean isSecureCookie() { + return this.secureCookie; + } + @Override public void initialize(ComponentConfiguration configuration) throws Exception { @@ -150,6 +158,8 @@ public class RestfulStrolchComponent extends StrolchComponent { this.cacheMode = configuration.getString(PARAM_HTTP_CACHE_MODE, HttpCacheResponseFilter.NO_CACHE); logger.info("HTTP header cache mode is set to {}", cacheMode); + this.secureCookie = configuration.getBoolean(PARAM_SECURE_COOKIE, true); + super.initialize(configuration); } diff --git a/li.strolch.rest/src/main/java/li/strolch/rest/StrolchRestfulConstants.java b/li.strolch.rest/src/main/java/li/strolch/rest/StrolchRestfulConstants.java index c05b3ac6c..84d814bbe 100644 --- a/li.strolch.rest/src/main/java/li/strolch/rest/StrolchRestfulConstants.java +++ b/li.strolch.rest/src/main/java/li/strolch/rest/StrolchRestfulConstants.java @@ -21,4 +21,5 @@ package li.strolch.rest; public class StrolchRestfulConstants { public static final String STROLCH_CERTIFICATE = "strolch.certificate"; //$NON-NLS-1$ + public static final String STROLCH_AUTHORIZATION = "strolch.authorization"; //$NON-NLS-1$ } diff --git a/li.strolch.rest/src/main/java/li/strolch/rest/endpoint/AuthenticationService.java b/li.strolch.rest/src/main/java/li/strolch/rest/endpoint/AuthenticationService.java index bf5cadc65..d14b6fc58 100644 --- a/li.strolch.rest/src/main/java/li/strolch/rest/endpoint/AuthenticationService.java +++ b/li.strolch.rest/src/main/java/li/strolch/rest/endpoint/AuthenticationService.java @@ -19,6 +19,7 @@ import java.text.MessageFormat; import java.util.ArrayList; import java.util.List; import java.util.Set; +import java.util.concurrent.TimeUnit; import javax.ws.rs.Consumes; import javax.ws.rs.DELETE; @@ -30,6 +31,7 @@ import javax.ws.rs.Produces; import javax.ws.rs.core.Context; import javax.ws.rs.core.HttpHeaders; import javax.ws.rs.core.MediaType; +import javax.ws.rs.core.NewCookie; import javax.ws.rs.core.Response; import javax.ws.rs.core.Response.Status; @@ -48,6 +50,7 @@ import ch.eitchnet.privilege.model.PrivilegeContext; import ch.eitchnet.utils.helper.StringHelper; import li.strolch.exception.StrolchException; import li.strolch.rest.RestfulStrolchComponent; +import li.strolch.rest.StrolchRestfulConstants; import li.strolch.rest.StrolchSessionHandler; import li.strolch.rest.model.Login; import li.strolch.rest.model.LoginResult; @@ -112,9 +115,12 @@ public class AuthenticationService { } loginResult.setPrivileges(privileges); + NewCookie cookie = new NewCookie(StrolchRestfulConstants.STROLCH_AUTHORIZATION, certificate.getAuthToken(), + "/", null, "Authorization header", (int) TimeUnit.DAYS.toSeconds(1), + restfulStrolchComponent.isSecureCookie()); + return Response.ok().entity(loginResult)// - .header(HttpHeaders.AUTHORIZATION, certificate.getAuthToken())// - .build(); + .header(HttpHeaders.AUTHORIZATION, certificate.getAuthToken()).cookie(cookie).build(); } catch (InvalidCredentialsException e) { logger.error(e.getMessage(), e); diff --git a/li.strolch.rest/src/main/java/li/strolch/rest/filters/AuthenicationRequestFilter.java b/li.strolch.rest/src/main/java/li/strolch/rest/filters/AuthenicationRequestFilter.java index 2baa336ce..75095c390 100644 --- a/li.strolch.rest/src/main/java/li/strolch/rest/filters/AuthenicationRequestFilter.java +++ b/li.strolch.rest/src/main/java/li/strolch/rest/filters/AuthenicationRequestFilter.java @@ -22,19 +22,20 @@ import java.util.List; import javax.ws.rs.container.ContainerRequestContext; import javax.ws.rs.container.ContainerRequestFilter; +import javax.ws.rs.core.Cookie; import javax.ws.rs.core.HttpHeaders; import javax.ws.rs.core.MediaType; import javax.ws.rs.core.Response; import javax.ws.rs.ext.Provider; -import li.strolch.rest.RestfulStrolchComponent; -import li.strolch.rest.StrolchSessionHandler; - import org.slf4j.Logger; import org.slf4j.LoggerFactory; import ch.eitchnet.privilege.model.Certificate; import ch.eitchnet.utils.helper.StringHelper; +import li.strolch.rest.RestfulStrolchComponent; +import li.strolch.rest.StrolchRestfulConstants; +import li.strolch.rest.StrolchSessionHandler; /** * @author Reto Breitenmoser @@ -57,22 +58,38 @@ public class AuthenicationRequestFilter implements ContainerRequestFilter { String sessionId = requestContext.getHeaderString(HttpHeaders.AUTHORIZATION); if (StringHelper.isEmpty(sessionId)) { - logger.error("No SessionID on request to URL " + requestContext.getUriInfo().getPath()); - requestContext.abortWith(Response.status(Response.Status.FORBIDDEN) - .header(HttpHeaders.CONTENT_TYPE, MediaType.TEXT_PLAIN).entity("Missing Authorization!").build()); //$NON-NLS-1$ - return; + + 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; + } + + 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; + } } try { - StrolchSessionHandler sessionHandler = RestfulStrolchComponent.getInstance().getComponent( - StrolchSessionHandler.class); + StrolchSessionHandler sessionHandler = RestfulStrolchComponent.getInstance() + .getComponent(StrolchSessionHandler.class); Certificate certificate = sessionHandler.validate(sessionId); requestContext.setProperty(STROLCH_CERTIFICATE, certificate); } catch (Exception e) { logger.error(e.getMessage(), e); - requestContext.abortWith(Response.status(Response.Status.FORBIDDEN) - .header(HttpHeaders.CONTENT_TYPE, MediaType.TEXT_PLAIN) - .entity("User cannot access the resource.").build()); //$NON-NLS-1$ + requestContext.abortWith( + Response.status(Response.Status.FORBIDDEN).header(HttpHeaders.CONTENT_TYPE, MediaType.TEXT_PLAIN) + .entity("User cannot access the resource.").build()); //$NON-NLS-1$ } } }