From 89a729ce7c89b187c1cb16ea88f30bd21d96a496 Mon Sep 17 00:00:00 2001 From: Marco Massenzio Date: Wed, 16 Feb 2022 21:42:06 -0700 Subject: [PATCH] [Fixes #22] Remove all JWT logs --- build.gradle | 2 +- .../java/com/alertavert/opa/Constants.java | 1 + .../jwt/ApiTokenAuthenticationFactory.java | 5 ++- .../opa/jwt/JwtAuthenticationWebFilter.java | 2 +- .../alertavert/opa/jwt/JwtTokenProvider.java | 2 +- .../OpaReactiveAuthorizationManager.java | 7 +-- .../TokenBasedAuthorizationRequestBody.java | 43 +++++++++++++------ .../alertavert/opademo/api/JwtController.java | 8 ++-- .../opademo/api/LoginController.java | 5 ++- .../src/main/resources/application.yaml | 2 +- 10 files changed, 49 insertions(+), 28 deletions(-) diff --git a/build.gradle b/build.gradle index bd5fea6..51890a1 100644 --- a/build.gradle +++ b/build.gradle @@ -46,7 +46,7 @@ task logCoverageRatio { allprojects { group 'com.alertavert' - version '0.7.0' + version '0.7.1' sourceCompatibility = JavaVersion.VERSION_17 diff --git a/jwt-opa/src/main/java/com/alertavert/opa/Constants.java b/jwt-opa/src/main/java/com/alertavert/opa/Constants.java index 68aad04..59e9ce8 100644 --- a/jwt-opa/src/main/java/com/alertavert/opa/Constants.java +++ b/jwt-opa/src/main/java/com/alertavert/opa/Constants.java @@ -136,4 +136,5 @@ public Collection getAuthorities() { @Override public boolean isEnabled() {return false;} }; + public static final int MAX_TOKEN_LEN_LOG = 6; } diff --git a/jwt-opa/src/main/java/com/alertavert/opa/jwt/ApiTokenAuthenticationFactory.java b/jwt-opa/src/main/java/com/alertavert/opa/jwt/ApiTokenAuthenticationFactory.java index 706b5fd..5e28c9f 100644 --- a/jwt-opa/src/main/java/com/alertavert/opa/jwt/ApiTokenAuthenticationFactory.java +++ b/jwt-opa/src/main/java/com/alertavert/opa/jwt/ApiTokenAuthenticationFactory.java @@ -18,6 +18,7 @@ package com.alertavert.opa.jwt; +import com.alertavert.opa.Constants; import com.auth0.jwt.exceptions.JWTVerificationException; import com.auth0.jwt.interfaces.DecodedJWT; import lombok.extern.slf4j.Slf4j; @@ -31,6 +32,8 @@ import java.util.List; +import static com.alertavert.opa.Constants.MAX_TOKEN_LEN_LOG; + /** *

ApiTokenAuthenticationFactory

* @@ -57,7 +60,7 @@ public class ApiTokenAuthenticationFactory { * grant with the {@link JwtTokenProvider#ROLES} carried by the JWT. */ public Mono createAuthentication(String token) { - log.debug("Authenticating token {}...", token.substring(0, Math.min(25, token.length()))); + log.debug("Authenticating token {}...", token.substring(0, Math.min(MAX_TOKEN_LEN_LOG, token.length()))); try { DecodedJWT jwt = provider.decode(token); List authorities = AuthorityUtils.createAuthorityList( diff --git a/jwt-opa/src/main/java/com/alertavert/opa/jwt/JwtAuthenticationWebFilter.java b/jwt-opa/src/main/java/com/alertavert/opa/jwt/JwtAuthenticationWebFilter.java index 9d2492b..5aa5e30 100644 --- a/jwt-opa/src/main/java/com/alertavert/opa/jwt/JwtAuthenticationWebFilter.java +++ b/jwt-opa/src/main/java/com/alertavert/opa/jwt/JwtAuthenticationWebFilter.java @@ -69,7 +69,7 @@ public Mono filter(ServerWebExchange exchange, WebFilterChain chain) { this.authenticationConverter.convert(exchange) .doOnNext(authentication -> { Principal principal = (Principal) authentication.getPrincipal(); - log.debug("---Validated API Token for Principal: `{}`", principal.getName()); + log.debug("Validated API Token for Principal: `{}`", principal.getName()); }) .switchIfEmpty(chain.filter(exchange).then(Mono.empty())) diff --git a/jwt-opa/src/main/java/com/alertavert/opa/jwt/JwtTokenProvider.java b/jwt-opa/src/main/java/com/alertavert/opa/jwt/JwtTokenProvider.java index 125ed27..b79c368 100644 --- a/jwt-opa/src/main/java/com/alertavert/opa/jwt/JwtTokenProvider.java +++ b/jwt-opa/src/main/java/com/alertavert/opa/jwt/JwtTokenProvider.java @@ -80,6 +80,7 @@ public String createToken(String user, List roles) { .withClaim(ROLES, roles) .withIssuedAt(Date.from(now)); + log.debug("Issuing JWT for user = {}, roles = {}", user, roles); if (keyProperties.isShouldExpire()) { Instant expires = now.plusSeconds(keyProperties.getExpiresAfterSec()); log.debug("JWT will expire at {}", expires); @@ -93,7 +94,6 @@ public String createToken(String user, List roles) { } String token = builder.sign(hmac); - log.debug("Issuing JWT: {}", token); return token; } diff --git a/jwt-opa/src/main/java/com/alertavert/opa/security/OpaReactiveAuthorizationManager.java b/jwt-opa/src/main/java/com/alertavert/opa/security/OpaReactiveAuthorizationManager.java index db3af67..3da2999 100644 --- a/jwt-opa/src/main/java/com/alertavert/opa/security/OpaReactiveAuthorizationManager.java +++ b/jwt-opa/src/main/java/com/alertavert/opa/security/OpaReactiveAuthorizationManager.java @@ -120,12 +120,7 @@ public Mono check( return Mono.just(makeRequestBody(auth.getCredentials(), request)); }) .doOnNext(body -> { - try { - log.debug("POSTing OPA Authorization request:\n{}", - mapper.writerWithDefaultPrettyPrinter().writeValueAsString(body)); - } catch (JsonProcessingException e) { - log.error(CANNOT_PARSE_AUTHORIZATION_REQUEST, e.getMessage()); - } + log.debug("POST Authorization request:\n{}", body.prettyPrint()); }) .flatMap(body -> client.post() .accept(MediaType.APPLICATION_JSON) diff --git a/jwt-opa/src/main/java/com/alertavert/opa/security/TokenBasedAuthorizationRequestBody.java b/jwt-opa/src/main/java/com/alertavert/opa/security/TokenBasedAuthorizationRequestBody.java index 2c35d55..5a4ad78 100644 --- a/jwt-opa/src/main/java/com/alertavert/opa/security/TokenBasedAuthorizationRequestBody.java +++ b/jwt-opa/src/main/java/com/alertavert/opa/security/TokenBasedAuthorizationRequestBody.java @@ -18,8 +18,15 @@ package com.alertavert.opa.security; +import com.fasterxml.jackson.annotation.JsonIgnore; import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.ObjectMapper; +import lombok.ToString; import lombok.Value; +import org.springframework.util.StringUtils; + +import static com.alertavert.opa.Constants.MAX_TOKEN_LEN_LOG; /** *

TokenBasedAuthorizationRequestBody

@@ -27,31 +34,42 @@ *

Encapsulates a request body to the OPA server, structured in a way that conforms to the * policy's Rego code's expectations: * - - { - "input": { - "api_token": ".... API Token Base-64 encoded ...", - "resource": { - "path": "/path/to/resource", - "method": "POST" - } - } - } - + * + * { "input": { "api_token": ".... API Token Base-64 encoded ...", "resource": { "path": + * "/path/to/resource", "method": "POST" } } } + * * - * @see OpaReactiveAuthorizationManager * @author M. Massenzio, 2020-11-22 + * @see OpaReactiveAuthorizationManager */ @Value public class TokenBasedAuthorizationRequestBody { + /** * The OPA server requires every POST body to the Data API to be wrapped inside an {@literal * "input"} object, we use this class to simplify the construction of the JSON body. */ @Value public static class RequestBody { + @JsonIgnore + ObjectMapper mapper = new ObjectMapper(); TokenBasedAuthorizationRequestBody input; + + /** + * Pretty-formatted JSON content of this RequestBody, with the API Token (JWT) masked. + * + * @return a printable String, suitable for logging + */ + public String prettyPrint() { + RequestBody body = build(input.token.substring(0, MAX_TOKEN_LEN_LOG) + "...", + input.resource.path, input.resource.method); + try { + return mapper.writerWithDefaultPrettyPrinter().writeValueAsString(body); + } catch (JsonProcessingException e) { + throw new RuntimeException(e); + } + } } @Value @@ -61,6 +79,7 @@ public static class Resource { } @JsonProperty("api_token") + @ToString.Exclude String token; Resource resource; diff --git a/webapp-example/src/main/java/com/alertavert/opademo/api/JwtController.java b/webapp-example/src/main/java/com/alertavert/opademo/api/JwtController.java index 9a16eb6..93d2b2f 100644 --- a/webapp-example/src/main/java/com/alertavert/opademo/api/JwtController.java +++ b/webapp-example/src/main/java/com/alertavert/opademo/api/JwtController.java @@ -39,6 +39,7 @@ import static com.alertavert.opa.Constants.API_TOKEN; import static com.alertavert.opa.Constants.BEARER_TOKEN; +import static com.alertavert.opa.Constants.MAX_TOKEN_LEN_LOG; @Slf4j @RestController @@ -64,7 +65,7 @@ static class ApiToken { @GetMapping(path = "/token/{user}", produces = MimeTypeUtils.APPLICATION_JSON_VALUE) public Mono> getToken(@PathVariable String user) { - log.debug("Refreshing API Token for `{}`", user); + log.debug("Refreshing API Token, user = {}", user); return repository.findByUsername(user) .map(u -> { @@ -72,8 +73,9 @@ public Mono> getToken(@PathVariable String user) { return new ApiToken(user, u.roles(), token); }) .map(ResponseEntity::ok) - .doOnSuccess(response -> log.debug("Returning API Token for user {}: {}", user, - Objects.requireNonNull(response.getBody()).getApiToken())) + .doOnSuccess(response -> log.debug( + "API Token successfully created, user = {}, token = {}...", user, + Objects.requireNonNull(response.getBody()).apiToken.substring(0, MAX_TOKEN_LEN_LOG))) .onErrorReturn(Exception.class, ResponseEntity.badRequest().build()); } diff --git a/webapp-example/src/main/java/com/alertavert/opademo/api/LoginController.java b/webapp-example/src/main/java/com/alertavert/opademo/api/LoginController.java index 6973481..bc700e3 100644 --- a/webapp-example/src/main/java/com/alertavert/opademo/api/LoginController.java +++ b/webapp-example/src/main/java/com/alertavert/opademo/api/LoginController.java @@ -41,6 +41,7 @@ import java.util.UUID; import static com.alertavert.opa.Constants.BASIC_AUTH; +import static com.alertavert.opa.Constants.MAX_TOKEN_LEN_LOG; /** *

LoginController

@@ -80,8 +81,8 @@ Mono login( return new JwtController.ApiToken(u.getUsername(), u.roles(), token); }) .doOnNext(apiToken -> - log.debug("User `{}` authenticated, API Token generated: {}", - apiToken.getUsername(), apiToken.getApiToken())); + log.debug("User authenticated, user = {}, token = {}...", + apiToken.getUsername(), apiToken.getApiToken().substring(0, MAX_TOKEN_LEN_LOG))); } @GetMapping("/reset/{username}") diff --git a/webapp-example/src/main/resources/application.yaml b/webapp-example/src/main/resources/application.yaml index 35865e0..df03a6a 100644 --- a/webapp-example/src/main/resources/application.yaml +++ b/webapp-example/src/main/resources/application.yaml @@ -52,7 +52,7 @@ tokens: # security requirements. should_expire: true # For the demo app, we make the API Token valid for 5 minutes. - expires_after_sec: 30 + expires_after_sec: 3000 # Interval in seconds, after creation, during which the JWT is not valid. # Corresponds to the `nbf` ("not before") claim.