Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Fixes #22] Remove all JWT logs #23

Merged
merged 1 commit into from
Feb 17, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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