Skip to content

Commit

Permalink
Merge pull request #23 from massenz/jwt_log
Browse files Browse the repository at this point in the history
[Fixes #22] Remove all JWT logs
  • Loading branch information
massenz authored Feb 17, 2022
2 parents f226b89 + 89a729c commit fdcb43e
Show file tree
Hide file tree
Showing 10 changed files with 49 additions and 28 deletions.
2 changes: 1 addition & 1 deletion build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ task logCoverageRatio {

allprojects {
group 'com.alertavert'
version '0.7.0'
version '0.7.1'

sourceCompatibility = JavaVersion.VERSION_17

Expand Down
1 change: 1 addition & 0 deletions jwt-opa/src/main/java/com/alertavert/opa/Constants.java
Original file line number Diff line number Diff line change
Expand Up @@ -136,4 +136,5 @@ public Collection<? extends GrantedAuthority> getAuthorities() {
@Override
public boolean isEnabled() {return false;}
};
public static final int MAX_TOKEN_LEN_LOG = 6;
}
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -31,6 +32,8 @@

import java.util.List;

import static com.alertavert.opa.Constants.MAX_TOKEN_LEN_LOG;

/**
* <h2>ApiTokenAuthenticationFactory</h2>
*
Expand All @@ -57,7 +60,7 @@ public class ApiTokenAuthenticationFactory {
* grant with the {@link JwtTokenProvider#ROLES} carried by the JWT.
*/
public Mono<Authentication> 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<? extends GrantedAuthority> authorities = AuthorityUtils.createAuthorityList(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ public Mono<Void> 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()))

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,7 @@ public String createToken(String user, List<String> 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);
Expand All @@ -93,7 +94,6 @@ public String createToken(String user, List<String> roles) {
}

String token = builder.sign(hmac);
log.debug("Issuing JWT: {}", token);
return token;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -120,12 +120,7 @@ public Mono<AuthorizationDecision> 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)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,40 +18,58 @@

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;

/**
* <h2>TokenBasedAuthorizationRequestBody</h2>
*
* <p>Encapsulates a request body to the OPA server, structured in a way that conforms to the
* policy's Rego code's expectations:
*
<code>
{
"input": {
"api_token": ".... API Token Base-64 encoded ...",
"resource": {
"path": "/path/to/resource",
"method": "POST"
}
}
}
</code>
* <code>
* { "input": { "api_token": ".... API Token Base-64 encoded ...", "resource": { "path":
* "/path/to/resource", "method": "POST" } } }
* </code>
*
* @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
Expand All @@ -61,6 +79,7 @@ public static class Resource {
}

@JsonProperty("api_token")
@ToString.Exclude
String token;
Resource resource;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -64,16 +65,17 @@ static class ApiToken {

@GetMapping(path = "/token/{user}", produces = MimeTypeUtils.APPLICATION_JSON_VALUE)
public Mono<ResponseEntity<ApiToken>> getToken(@PathVariable String user) {
log.debug("Refreshing API Token for `{}`", user);
log.debug("Refreshing API Token, user = {}", user);

return repository.findByUsername(user)
.map(u -> {
String token = provider.createToken(u.getUsername(), u.roles());
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());
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;

/**
* <h2>LoginController</h2>
Expand Down Expand Up @@ -80,8 +81,8 @@ Mono<JwtController.ApiToken> 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}")
Expand Down
2 changes: 1 addition & 1 deletion webapp-example/src/main/resources/application.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down

0 comments on commit fdcb43e

Please sign in to comment.