token enricher should use new access token api

This commit is contained in:
Sebastian Sdorra
2017-01-17 15:33:19 +01:00
parent 2388cfd35d
commit 70d5942250
10 changed files with 68 additions and 70 deletions

View File

@@ -81,6 +81,7 @@ public final class JwtAccessToken implements AccessToken {
}
@Override
@SuppressWarnings("unchecked")
public Optional<Object> getCustom(String key) {
return Optional.ofNullable(claims.get(key));
}

View File

@@ -61,7 +61,6 @@ public final class JwtAccessTokenBuilder implements AccessTokenBuilder {
private final KeyGenerator keyGenerator;
private final SecureKeyResolver keyResolver;
private final Set<TokenClaimsEnricher> enrichers;
private String subject;
private String issuer;
@@ -71,12 +70,9 @@ public final class JwtAccessTokenBuilder implements AccessTokenBuilder {
private final Map<String,Object> custom = Maps.newHashMap();
JwtAccessTokenBuilder(
KeyGenerator keyGenerator, SecureKeyResolver keyResolver, Set<TokenClaimsEnricher> enrichers
) {
JwtAccessTokenBuilder(KeyGenerator keyGenerator, SecureKeyResolver keyResolver) {
this.keyGenerator = keyGenerator;
this.keyResolver = keyResolver;
this.enrichers = enrichers;
}
@Override
@@ -143,11 +139,6 @@ public final class JwtAccessTokenBuilder implements AccessTokenBuilder {
// add scope to custom claims
Scopes.toClaims(customClaims, scope);
// enrich claims with registered enrichers
enrichers.forEach((enricher) -> {
enricher.enrich(customClaims);
});
Date now = new Date();
long expiration = expiresInUnit.toMillis(expiresIn);

View File

@@ -45,11 +45,11 @@ public final class JwtAccessTokenBuilderFactory implements AccessTokenBuilderFac
private final KeyGenerator keyGenerator;
private final SecureKeyResolver keyResolver;
private final Set<TokenClaimsEnricher> enrichers;
private final Set<AccessTokenEnricher> enrichers;
@Inject
public JwtAccessTokenBuilderFactory(
KeyGenerator keyGenerator, SecureKeyResolver keyResolver, Set<TokenClaimsEnricher> enrichers
KeyGenerator keyGenerator, SecureKeyResolver keyResolver, Set<AccessTokenEnricher> enrichers
) {
this.keyGenerator = keyGenerator;
this.keyResolver = keyResolver;
@@ -58,7 +58,14 @@ public final class JwtAccessTokenBuilderFactory implements AccessTokenBuilderFac
@Override
public JwtAccessTokenBuilder create() {
return new JwtAccessTokenBuilder(keyGenerator, keyResolver, enrichers);
JwtAccessTokenBuilder builder = new JwtAccessTokenBuilder(keyGenerator, keyResolver);
// enrich access token builder
enrichers.forEach((enricher) -> {
enricher.enrich(builder);
});
return builder;
}
}

View File

@@ -40,7 +40,7 @@ public final class Xsrf {
static final String HEADER_KEY = "X-XSRF-Token";
static final String CLAIMS_KEY = "xsrf";
static final String TOKEN_KEY = "xsrf";
private Xsrf() {
}

View File

@@ -30,7 +30,7 @@
*/
package sonia.scm.security;
import java.util.Map;
import com.google.common.annotations.VisibleForTesting;
import java.util.UUID;
import javax.inject.Inject;
import javax.inject.Provider;
@@ -42,22 +42,22 @@ import sonia.scm.plugin.Extension;
import sonia.scm.util.HttpUtil;
/**
* Xsrf token claims enricher will add an xsrf protection key to the claims of the jwt token. The enricher will only
* add the xsrf protection key, if the authentication request is issued from the web interface and xsrf protection is
* enabled. The xsrf key will be validated on every request by the {@link XsrfTokenClaimsValidator}. Xsrf protection is
* disabled by default and can be enabled with {@link ScmConfiguration#setEnabledXsrfProtection(boolean)}.
* Xsrf access token enricher will add an xsrf custom field to the access token. The enricher will only
* add the xsrf field, if the authentication request is issued from the web interface and xsrf protection is
* enabled. The xsrf field will be validated on every request by the {@link XsrfTokenClaimsValidator}. Xsrf protection
* can be disabled with {@link ScmConfiguration#setEnabledXsrfProtection(boolean)}.
*
* @see https://bitbucket.org/sdorra/scm-manager/issues/793/json-hijacking-vulnerability-cwe-116-cwe
* @see <a href="https://goo.gl/s67xO3">Issue 793</a>
* @author Sebastian Sdorra
* @since 2.0.0
*/
@Extension
public class XsrfTokenClaimsEnricher implements TokenClaimsEnricher {
public class XsrfAccessTokenEnricher implements AccessTokenEnricher {
/**
* the logger for XsrfTokenClaimsEnricher
* the logger for XsrfAccessTokenEnricher
*/
private static final Logger LOG = LoggerFactory.getLogger(XsrfTokenClaimsEnricher.class);
private static final Logger LOG = LoggerFactory.getLogger(XsrfAccessTokenEnricher.class);
private final ScmConfiguration configuration;
private final Provider<HttpServletRequest> requestProvider;
@@ -69,17 +69,17 @@ public class XsrfTokenClaimsEnricher implements TokenClaimsEnricher {
* @param requestProvider http request provider
*/
@Inject
public XsrfTokenClaimsEnricher(ScmConfiguration configuration, Provider<HttpServletRequest> requestProvider) {
public XsrfAccessTokenEnricher(ScmConfiguration configuration, Provider<HttpServletRequest> requestProvider) {
this.configuration = configuration;
this.requestProvider = requestProvider;
}
@Override
public void enrich(Map<String, Object> claims) {
public void enrich(AccessTokenBuilder builder) {
if (configuration.isEnabledXsrfProtection()) {
if (HttpUtil.isWUIRequest(requestProvider.get())) {
LOG.debug("received wui token claim, enrich jwt with xsrf key");
claims.put(Xsrf.CLAIMS_KEY, createToken());
builder.custom(Xsrf.TOKEN_KEY, createToken());
} else {
LOG.trace("skip xsrf enrichment, because jwt session is started from a non wui client");
}
@@ -88,7 +88,8 @@ public class XsrfTokenClaimsEnricher implements TokenClaimsEnricher {
}
}
private String createToken() {
@VisibleForTesting
String createToken() {
// TODO create interface and use a better method
return UUID.randomUUID().toString();
}

View File

@@ -70,7 +70,7 @@ public class XsrfTokenClaimsValidator implements TokenClaimsValidator {
@Override
public boolean validate(Map<String, Object> claims) {
String xsrfClaimValue = (String) claims.get(Xsrf.CLAIMS_KEY);
String xsrfClaimValue = (String) claims.get(Xsrf.TOKEN_KEY);
if (!Strings.isNullOrEmpty(xsrfClaimValue)) {
String xsrfHeaderValue = requestProvider.get().getHeader(Xsrf.HEADER_KEY);
return xsrfClaimValue.equals(xsrfHeaderValue);