public RequestDetails( String nonce, String signature, String identity, Principal principal, int statusCode) { this.nonce = nonce; this.signature = signature; this.identity = identity; this.principal = principal; this.statusCode = statusCode; responseTimestamp = TimeUtils.formatISOUTCDateTime(new Date()); }
@Override public void filter(ContainerRequestContext requestContext) throws IOException { String nonce = requestContext.getHeaderString(HEADER_NONCE); String identity = requestContext.getHeaderString(HEADER_IDENTITY); try { if (StringUtils.isNotEmpty(identity)) { MDC.put(MDC_IDENTITY, identity); } String timestampStr = requestContext.getHeaderString(HEADER_TIMESTAMP); String signature = requestContext.getHeaderString(HEADER_SIGNATURE); if (!ValidationUtils.notEmpty(nonce, identity, timestampStr, signature)) { logUnauthorizedAccess( "Unauthorized request (missing any of nonce, identify, timestamp, signature)", requestContext); throw new AccessUnauthorizedException(); } URI requestUri = requestContext.getUriInfo().getRequestUri(); StringBuilder path = new StringBuilder(requestUri.getPath()); if (requestUri.getRawQuery() != null) { path.append('?').append(requestUri.getRawQuery()); } RESTRequestSigner restRequestSigner = new RESTRequestSigner( requestContext.getMethod(), path.toString(), nonce, timestampStr, identity); ByteArrayOutputStream content = new ByteArrayOutputStream(); InputStream is = requestContext.getEntityStream(); IOUtils.copy( is, contentMaxSize != null ? new BoundedOutputStream(content, contentMaxSize, true) : content); byte[] contentData = content.toByteArray(); restRequestSigner.setContent(contentData); try { Date timestamp = TimeUtils.parseISOUTCDateTime(timestampStr); if (timestamp.after(new Date(System.currentTimeMillis() + expiry))) { String message = "Unauthorized request (expired timestamp): " + timestampStr; logUnauthorizedAccess(message, requestContext); throw new AccessUnauthorizedException(message); } if (replayAttackValidator.checkNonceReplay(nonce)) { String message = "Unauthorized request (duplicated nonce): " + nonce; logUnauthorizedAccess(message, requestContext); throw new AccessUnauthorizedException(); } requestContext.setEntityStream(new ByteArrayInputStream(contentData)); Principal principal = findUserPrincipal(identity); if (principal == null) { logUnauthorizedAccess( "Unauthorized request (principal not found): " + identity, requestContext); throw new AccessUnauthorizedException(); } if (!verifySignature( principal, restRequestSigner.getDataToSign(), signature, requestContext)) { logUnauthorizedAccess( "Unauthorized request (invalid signature): " + restRequestSigner.toString(), requestContext); throw new AccessUnauthorizedException(); } updateAuthenticatedContext(requestContext, principal); } catch (ParseException e) { logBadRequest("Invalid timestamp: " + timestampStr, e, requestContext); throw new WebApplicationException(BAD_REQUEST); } } finally { try { MDC.remove(MDC_IDENTITY); } catch (IllegalArgumentException e) { // } } }