Compare commits
8 Commits
baa7a0af4e
...
4d7b3faf3f
Author | SHA1 | Date |
---|---|---|
Robert von Burg | 4d7b3faf3f | |
Robert von Burg | dc93800fd1 | |
Robert von Burg | 4b78b30600 | |
Robert von Burg | 3edcec4d08 | |
Robert von Burg | cf4ae20d0b | |
Robert von Burg | 68bd3dd6d6 | |
Robert von Burg | c4ac21ec98 | |
Robert von Burg | a45475f783 |
|
@ -6,7 +6,7 @@
|
|||
<parent>
|
||||
<groupId>li.strolch</groupId>
|
||||
<artifactId>strolch</artifactId>
|
||||
<version>2.2.0-SNAPSHOT</version>
|
||||
<version>2.3.0-SNAPSHOT</version>
|
||||
<relativePath>../pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
<parent>
|
||||
<groupId>li.strolch</groupId>
|
||||
<artifactId>strolch</artifactId>
|
||||
<version>2.2.0-SNAPSHOT</version>
|
||||
<version>2.3.0-SNAPSHOT</version>
|
||||
<relativePath>../pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
<parent>
|
||||
<groupId>li.strolch</groupId>
|
||||
<artifactId>strolch</artifactId>
|
||||
<version>2.2.0-SNAPSHOT</version>
|
||||
<version>2.3.0-SNAPSHOT</version>
|
||||
<relativePath>../pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
<parent>
|
||||
<groupId>li.strolch</groupId>
|
||||
<artifactId>strolch</artifactId>
|
||||
<version>2.2.0-SNAPSHOT</version>
|
||||
<version>2.3.0-SNAPSHOT</version>
|
||||
<relativePath>../pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
|
|
2
pom.xml
2
pom.xml
|
@ -5,7 +5,7 @@
|
|||
|
||||
<groupId>li.strolch</groupId>
|
||||
<artifactId>strolch</artifactId>
|
||||
<version>2.2.0-SNAPSHOT</version>
|
||||
<version>2.3.0-SNAPSHOT</version>
|
||||
|
||||
<name>strolch</name>
|
||||
<description>Module build for strolch</description>
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
<parent>
|
||||
<groupId>li.strolch</groupId>
|
||||
<artifactId>strolch</artifactId>
|
||||
<version>2.2.0-SNAPSHOT</version>
|
||||
<version>2.3.0-SNAPSHOT</version>
|
||||
<relativePath>../pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
<parent>
|
||||
<groupId>li.strolch</groupId>
|
||||
<artifactId>strolch</artifactId>
|
||||
<version>2.2.0-SNAPSHOT</version>
|
||||
<version>2.3.0-SNAPSHOT</version>
|
||||
<relativePath>../pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
<parent>
|
||||
<groupId>li.strolch</groupId>
|
||||
<artifactId>strolch</artifactId>
|
||||
<version>2.2.0-SNAPSHOT</version>
|
||||
<version>2.3.0-SNAPSHOT</version>
|
||||
<relativePath>../pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
<parent>
|
||||
<groupId>li.strolch</groupId>
|
||||
<artifactId>strolch</artifactId>
|
||||
<version>2.2.0-SNAPSHOT</version>
|
||||
<version>2.3.0-SNAPSHOT</version>
|
||||
<relativePath>../pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
<parent>
|
||||
<groupId>li.strolch</groupId>
|
||||
<artifactId>strolch</artifactId>
|
||||
<version>2.2.0-SNAPSHOT</version>
|
||||
<version>2.3.0-SNAPSHOT</version>
|
||||
<relativePath>../pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
<parent>
|
||||
<groupId>li.strolch</groupId>
|
||||
<artifactId>strolch</artifactId>
|
||||
<version>2.2.0-SNAPSHOT</version>
|
||||
<version>2.3.0-SNAPSHOT</version>
|
||||
<relativePath>../pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
<parent>
|
||||
<groupId>li.strolch</groupId>
|
||||
<artifactId>strolch</artifactId>
|
||||
<version>2.2.0-SNAPSHOT</version>
|
||||
<version>2.3.0-SNAPSHOT</version>
|
||||
<relativePath>../pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
|
|
|
@ -52,6 +52,17 @@ public class ExceptionHelper {
|
|||
.orElse("UnknownClass.unknownMethod!");
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the message of the root cause of the given exception
|
||||
*
|
||||
* @param e the exception for which to get the root cause
|
||||
*
|
||||
* @return the message of the root cause of the given exception
|
||||
*/
|
||||
public static String getRootCauseExceptionMessage(Throwable e) {
|
||||
return getExceptionMessage(getRootCause(e), false);
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* Returns a message for the given {@link Throwable}
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
<parent>
|
||||
<groupId>li.strolch</groupId>
|
||||
<artifactId>strolch</artifactId>
|
||||
<version>2.2.0-SNAPSHOT</version>
|
||||
<version>2.3.0-SNAPSHOT</version>
|
||||
<relativePath>../pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
|
|
|
@ -204,14 +204,12 @@ public class RestfulStrolchComponent extends StrolchComponent {
|
|||
|
||||
@Override
|
||||
public void start() throws Exception {
|
||||
DBC.PRE.assertNull("Instance is already set! This component is a singleton resource!", instance);
|
||||
instance = this;
|
||||
super.start();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void stop() throws Exception {
|
||||
instance = null;
|
||||
super.stop();
|
||||
}
|
||||
|
||||
|
|
|
@ -13,6 +13,7 @@ import java.io.IOException;
|
|||
|
||||
import static li.strolch.rest.StrolchRestfulConstants.STROLCH_REMOTE_IP;
|
||||
import static li.strolch.rest.StrolchRestfulConstants.STROLCH_REQUEST_URL;
|
||||
import static li.strolch.rest.helper.ServletRequestHelper.logRequest;
|
||||
|
||||
@PreMatching
|
||||
public class LogRequestFilter implements ContainerRequestFilter {
|
||||
|
@ -31,5 +32,7 @@ public class LogRequestFilter implements ContainerRequestFilter {
|
|||
this.request.setAttribute(STROLCH_REMOTE_IP, remoteIp);
|
||||
this.request.setAttribute(STROLCH_REQUEST_URL,
|
||||
requestContext.getMethod() + " " + requestContext.getUriInfo().getRequestUri());
|
||||
|
||||
logRequest(this.request);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,6 +3,7 @@ package li.strolch.rest.helper;
|
|||
import jakarta.ws.rs.core.Response;
|
||||
import li.strolch.exception.StrolchAccessDeniedException;
|
||||
import li.strolch.exception.StrolchNotAuthenticatedException;
|
||||
import li.strolch.privilege.base.InvalidCredentialsException;
|
||||
import li.strolch.privilege.model.Certificate;
|
||||
import li.strolch.privilege.model.Usage;
|
||||
import li.strolch.runtime.sessions.StrolchSessionHandler;
|
||||
|
@ -12,13 +13,15 @@ import org.slf4j.LoggerFactory;
|
|||
import java.util.Base64;
|
||||
|
||||
import static java.nio.charset.StandardCharsets.UTF_8;
|
||||
import static li.strolch.utils.helper.ExceptionHelper.getRootCause;
|
||||
import static li.strolch.utils.helper.ExceptionHelper.getRootCauseExceptionMessage;
|
||||
import static li.strolch.utils.helper.StringHelper.isEmpty;
|
||||
|
||||
public class BasicAuth {
|
||||
|
||||
private static final Logger logger = LoggerFactory.getLogger(BasicAuth.class);
|
||||
|
||||
private StrolchSessionHandler sessionHandler;
|
||||
private final StrolchSessionHandler sessionHandler;
|
||||
|
||||
public BasicAuth(StrolchSessionHandler sessionHandler) {
|
||||
this.sessionHandler = sessionHandler;
|
||||
|
@ -26,9 +29,9 @@ public class BasicAuth {
|
|||
|
||||
public Certificate doBasicAuth(String authorization, String remoteIp) throws BasicAuthFailure {
|
||||
if (isEmpty(authorization))
|
||||
throw new BasicAuthFailure(Response.Status.UNAUTHORIZED, "Missing auth!");
|
||||
throw new BasicAuthFailure(Response.Status.UNAUTHORIZED, "No authentication!");
|
||||
if (!authorization.startsWith("Basic "))
|
||||
throw new BasicAuthFailure(Response.Status.BAD_REQUEST, "Bad request!");
|
||||
throw new BasicAuthFailure(Response.Status.BAD_REQUEST, "Invalid basic auth request!");
|
||||
|
||||
try {
|
||||
String auth = new String(Base64.getDecoder().decode(authorization.substring(6)), UTF_8);
|
||||
|
@ -38,15 +41,33 @@ public class BasicAuth {
|
|||
|
||||
return this.sessionHandler.authenticate(username, password.toCharArray(), remoteIp, Usage.SINGLE, false);
|
||||
|
||||
} catch (StrolchNotAuthenticatedException e) {
|
||||
} catch (StrolchNotAuthenticatedException | InvalidCredentialsException e) {
|
||||
logger.error(e.getMessage());
|
||||
throw new BasicAuthFailure(Response.Status.UNAUTHORIZED, "Not authenticated!", e);
|
||||
throw new BasicAuthFailure(Response.Status.UNAUTHORIZED, "Authentication failed", e);
|
||||
} catch (StrolchAccessDeniedException e) {
|
||||
logger.error(e.getMessage());
|
||||
throw new BasicAuthFailure(Response.Status.UNAUTHORIZED, "User is not authorized!", e);
|
||||
throw new BasicAuthFailure(Response.Status.FORBIDDEN, "User is not authorized!", e);
|
||||
} catch (Exception e) {
|
||||
logger.error(e.getMessage());
|
||||
throw new BasicAuthFailure(Response.Status.INTERNAL_SERVER_ERROR, "Internal error", e);
|
||||
Response.Status status;
|
||||
String msg;
|
||||
Throwable rootCause = getRootCause(e);
|
||||
if (rootCause instanceof StrolchNotAuthenticatedException
|
||||
|| rootCause instanceof InvalidCredentialsException) {
|
||||
status = Response.Status.UNAUTHORIZED;
|
||||
msg = "Authentication failed";
|
||||
} else if (rootCause instanceof StrolchAccessDeniedException) {
|
||||
status = Response.Status.FORBIDDEN;
|
||||
msg = "User is not authorized!";
|
||||
} else {
|
||||
status = Response.Status.INTERNAL_SERVER_ERROR;
|
||||
msg = "Internal error";
|
||||
}
|
||||
|
||||
if (status == Response.Status.INTERNAL_SERVER_ERROR)
|
||||
logger.error(e.getMessage(), e);
|
||||
else
|
||||
logger.error("Basic Auth failed: {}", getRootCauseExceptionMessage(e));
|
||||
throw new BasicAuthFailure(status, msg, e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,111 @@
|
|||
package li.strolch.rest.helper;
|
||||
|
||||
import jakarta.servlet.http.Cookie;
|
||||
import jakarta.servlet.http.HttpServletRequest;
|
||||
import li.strolch.rest.RestfulStrolchComponent;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.util.Enumeration;
|
||||
|
||||
import static li.strolch.utils.helper.StringHelper.*;
|
||||
|
||||
public class ServletRequestHelper {
|
||||
|
||||
private static final Logger logger = LoggerFactory.getLogger(ServletRequestHelper.class);
|
||||
|
||||
private static final int PADDING = 30;
|
||||
private static final int PADDING_SHORT = 27;
|
||||
|
||||
public static void logRequest(HttpServletRequest request) {
|
||||
if (!RestfulStrolchComponent.getInstance().isRestLogging())
|
||||
return;
|
||||
|
||||
try {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb
|
||||
.append("\n")
|
||||
.append(pad("REQUEST URL:"))
|
||||
.append(request.getMethod())
|
||||
.append(" ")
|
||||
.append(request.getRequestURL())
|
||||
.append("\n");
|
||||
sb
|
||||
.append(pad("REQUEST:"))
|
||||
.append(request.getMethod())
|
||||
.append(" ")
|
||||
.append(request.getRequestURI())
|
||||
.append("\n");
|
||||
|
||||
sb.append(pad("QUERY:")).append('?').append(string(request.getQueryString())).append("\n");
|
||||
|
||||
String from = request.getRemoteAddr();
|
||||
sb.append(pad("REMOTE:")).append(from);
|
||||
if (!from.equals(request.getRemoteHost()))
|
||||
sb.append("/").append(request.getRemoteHost());
|
||||
sb.append(":").append(request.getRemotePort()).append("\n");
|
||||
|
||||
Enumeration<String> headerNames = request.getHeaderNames();
|
||||
if (!headerNames.hasMoreElements()) {
|
||||
sb.append("HEADERS: (none)!\n");
|
||||
} else {
|
||||
sb.append("HEADERS: \n");
|
||||
while (headerNames.hasMoreElements()) {
|
||||
String headerName = headerNames.nextElement();
|
||||
String headerValue = request.getHeader(headerName);
|
||||
sb.append(" ").append(padShort(headerName)).append(" = ").append(headerValue).append("\n");
|
||||
}
|
||||
}
|
||||
|
||||
Cookie[] cookies = request.getCookies();
|
||||
if (cookies == null) {
|
||||
sb.append("COOKIES: (none)!\n");
|
||||
} else {
|
||||
sb.append("COOKIES: \n");
|
||||
for (Cookie cookie : cookies) {
|
||||
sb
|
||||
.append(" ")
|
||||
.append(padShort(cookie.getName()))
|
||||
.append(" = ")
|
||||
.append(cookie.getValue())
|
||||
.append("\n");
|
||||
}
|
||||
}
|
||||
|
||||
sb.append(pad("AuthType:")).append(string(request.getAuthType())).append("\n");
|
||||
sb.append(pad("User-Principal:")).append(string(request.getUserPrincipal())).append("\n");
|
||||
sb.append(pad("Remote User:")).append(string(request.getRemoteUser())).append("\n");
|
||||
sb.append(pad("Requested SessionID:")).append(string(request.getRequestedSessionId())).append("\n");
|
||||
sb.append(pad("Protocol:")).append(string(request.getProtocol())).append("\n");
|
||||
sb.append(pad("RequestId:")).append(string(request.getRequestId())).append("\n");
|
||||
sb.append(pad("DispatcherType:")).append(string(request.getDispatcherType())).append("\n");
|
||||
sb.append(pad("CharacterEncoding:")).append(string(request.getCharacterEncoding())).append("\n");
|
||||
sb.append(pad("ContentType:")).append(string(request.getContentType())).append("\n");
|
||||
sb.append(pad("ContentLength:")).append(request.getContentLengthLong()).append("\n");
|
||||
|
||||
logger.info(sb.toString());
|
||||
} catch (Exception e) {
|
||||
logger.error("Failed to log request", e);
|
||||
}
|
||||
}
|
||||
|
||||
private static String pad(String string) {
|
||||
return normalizeLength(string, PADDING, false, ' ');
|
||||
}
|
||||
|
||||
private static String padShort(String string) {
|
||||
return normalizeLength(string, PADDING_SHORT, false, ' ');
|
||||
}
|
||||
|
||||
private static String string(String string) {
|
||||
return isEmpty(string) ? "(none)" : string;
|
||||
}
|
||||
|
||||
private static String string(Enum<?> e) {
|
||||
return e == null ? "(none)" : e.name();
|
||||
}
|
||||
|
||||
private static String string(Object o) {
|
||||
return o == null ? "(none)" : o.toString();
|
||||
}
|
||||
}
|
|
@ -6,7 +6,7 @@
|
|||
<parent>
|
||||
<groupId>li.strolch</groupId>
|
||||
<artifactId>strolch</artifactId>
|
||||
<version>2.2.0-SNAPSHOT</version>
|
||||
<version>2.3.0-SNAPSHOT</version>
|
||||
<relativePath>../pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
<parent>
|
||||
<groupId>li.strolch</groupId>
|
||||
<artifactId>strolch</artifactId>
|
||||
<version>2.2.0-SNAPSHOT</version>
|
||||
<version>2.3.0-SNAPSHOT</version>
|
||||
<relativePath>../pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
|
|
Loading…
Reference in New Issue