Repository: syncope Updated Branches: refs/heads/2_0_X 02b6d4eb6 -> 6fd572119 refs/heads/master 9a7afc0ce -> 24f789932
[SYNCOPE-1301] Reworking logic to avoid conficts Project: http://git-wip-us.apache.org/repos/asf/syncope/repo Commit: http://git-wip-us.apache.org/repos/asf/syncope/commit/6fd57211 Tree: http://git-wip-us.apache.org/repos/asf/syncope/tree/6fd57211 Diff: http://git-wip-us.apache.org/repos/asf/syncope/diff/6fd57211 Branch: refs/heads/2_0_X Commit: 6fd572119b1a91029962a7b36ca7f372ad2204a5 Parents: 02b6d4e Author: Francesco Chicchiriccò <ilgro...@apache.org> Authored: Fri Apr 13 09:04:17 2018 +0200 Committer: Francesco Chicchiriccò <ilgro...@apache.org> Committed: Fri Apr 13 09:04:17 2018 +0200 ---------------------------------------------------------------------- .../persistence/jpa/entity/JPAAccessToken.java | 2 +- .../api/data/AccessTokenDataBinder.java | 6 +- .../java/data/AccessTokenDataBinderImpl.java | 83 ++++++++++---------- .../apache/syncope/core/logic/SAML2SPLogic.java | 20 +++-- 4 files changed, 53 insertions(+), 58 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/syncope/blob/6fd57211/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPAAccessToken.java ---------------------------------------------------------------------- diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPAAccessToken.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPAAccessToken.java index 4ddaed1..e3bc873 100644 --- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPAAccessToken.java +++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPAAccessToken.java @@ -44,7 +44,7 @@ public class JPAAccessToken extends AbstractProvidedKeyEntity implements AccessT @Temporal(TemporalType.TIMESTAMP) private Date expiryTime; - @Column(nullable = true) + @Column(unique = true) private String owner; @Lob http://git-wip-us.apache.org/repos/asf/syncope/blob/6fd57211/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/data/AccessTokenDataBinder.java ---------------------------------------------------------------------- diff --git a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/data/AccessTokenDataBinder.java b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/data/AccessTokenDataBinder.java index 4bb64aa..d50fc22 100644 --- a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/data/AccessTokenDataBinder.java +++ b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/data/AccessTokenDataBinder.java @@ -21,16 +21,14 @@ package org.apache.syncope.core.provisioning.api.data; import java.util.Date; import java.util.Map; import org.apache.commons.lang3.tuple.Pair; -import org.apache.commons.lang3.tuple.Triple; import org.apache.syncope.common.lib.to.AccessTokenTO; import org.apache.syncope.core.persistence.api.entity.AccessToken; public interface AccessTokenDataBinder { - Triple<String, String, Date> generateJWT(String subject, long duration, Map<String, Object> claims); + Pair<String, Date> generateJWT(String tokenId, String subject, long duration, Map<String, Object> claims); - Pair<String, Date> create( - String subject, Map<String, Object> claims, byte[] authorities, boolean replaceExisting); + Pair<String, Date> create(String subject, Map<String, Object> claims, byte[] authorities, boolean replace); Pair<String, Date> update(AccessToken accessToken, byte[] authorities); http://git-wip-us.apache.org/repos/asf/syncope/blob/6fd57211/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/AccessTokenDataBinderImpl.java ---------------------------------------------------------------------- diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/AccessTokenDataBinderImpl.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/AccessTokenDataBinderImpl.java index 350f1ed..0b2e4b6 100644 --- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/AccessTokenDataBinderImpl.java +++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/AccessTokenDataBinderImpl.java @@ -24,7 +24,6 @@ import java.util.Date; import java.util.Map; import javax.annotation.Resource; import org.apache.commons.lang3.tuple.Pair; -import org.apache.commons.lang3.tuple.Triple; import org.apache.cxf.rs.security.jose.common.JoseType; import org.apache.cxf.rs.security.jose.jws.JwsHeaders; import org.apache.cxf.rs.security.jose.jws.JwsJwtCompactConsumer; @@ -46,8 +45,6 @@ import org.springframework.stereotype.Component; @Component public class AccessTokenDataBinderImpl implements AccessTokenDataBinder { - private static final String[] IGNORE_PROPERTIES = { "owner" }; - private static final RandomBasedGenerator UUID_GENERATOR = Generators.randomBasedGenerator(); @Resource(name = "adminUser") @@ -72,8 +69,11 @@ public class AccessTokenDataBinderImpl implements AccessTokenDataBinder { private DefaultCredentialChecker credentialChecker; @Override - public Triple<String, String, Date> generateJWT( - final String subject, final long duration, final Map<String, Object> claims) { + public Pair<String, Date> generateJWT( + final String tokenId, + final String subject, + final long duration, + final Map<String, Object> claims) { credentialChecker.checkIsDefaultJWSKeyInUse(); @@ -81,7 +81,7 @@ public class AccessTokenDataBinderImpl implements AccessTokenDataBinder { long expiryTime = currentTime + 60L * duration; JwtClaims jwtClaims = new JwtClaims(); - jwtClaims.setTokenId(UUID_GENERATOR.generate().toString()); + jwtClaims.setTokenId(tokenId); jwtClaims.setSubject(subject); jwtClaims.setIssuedAt(currentTime); jwtClaims.setIssuer(jwtIssuer); @@ -97,52 +97,52 @@ public class AccessTokenDataBinderImpl implements AccessTokenDataBinder { String signed = producer.signWith(jwsSignatureProvider); - return Triple.of(jwtClaims.getTokenId(), signed, new Date(expiryTime * 1000L)); + return Pair.of(signed, new Date(expiryTime * 1000L)); } - @Override - public Pair<String, Date> create( + private AccessToken replace( final String subject, final Map<String, Object> claims, final byte[] authorities, - final boolean replaceExisting) { - - String body = null; - Date expiryTime = null; - - AccessToken existing = accessTokenDAO.findByOwner(subject); - if (existing != null) { - body = existing.getBody(); - expiryTime = existing.getExpiryTime(); - } - - if (replaceExisting || body == null) { - Triple<String, String, Date> created = generateJWT( - subject, - confDAO.find("jwt.lifetime.minutes", 120L), - claims); - - body = created.getMiddle(); - expiryTime = created.getRight(); + final AccessToken accessToken) { - AccessToken accessToken = entityFactory.newEntity(AccessToken.class); - accessToken.setKey(created.getLeft()); - accessToken.setBody(body); - accessToken.setExpiryTime(expiryTime); - accessToken.setOwner(subject); + Pair<String, Date> generated = generateJWT( + accessToken.getKey(), + subject, + confDAO.find("jwt.lifetime.minutes", 120L), + claims); - if (!adminUser.equals(accessToken.getOwner())) { - accessToken.setAuthorities(authorities); - } + accessToken.setBody(generated.getLeft()); + accessToken.setExpiryTime(generated.getRight()); + accessToken.setOwner(subject); - accessTokenDAO.save(accessToken); + if (!adminUser.equals(accessToken.getOwner())) { + accessToken.setAuthorities(authorities); } - if (replaceExisting && existing != null) { - accessTokenDAO.delete(existing); + return accessTokenDAO.save(accessToken); + } + + @Override + public Pair<String, Date> create( + final String subject, + final Map<String, Object> claims, + final byte[] authorities, + final boolean replace) { + + AccessToken accessToken = accessTokenDAO.findByOwner(subject); + if (accessToken == null) { + // no AccessToken found: create new + accessToken = entityFactory.newEntity(AccessToken.class); + accessToken.setKey(UUID_GENERATOR.generate().toString()); + + accessToken = replace(subject, claims, authorities, accessToken); + } else if (replace) { + // AccessToken found, but replace requested: update existing + accessToken = replace(subject, claims, authorities, accessToken); } - return Pair.of(body, expiryTime); + return Pair.of(accessToken.getBody(), accessToken.getExpiryTime()); } @Override @@ -179,8 +179,7 @@ public class AccessTokenDataBinderImpl implements AccessTokenDataBinder { @Override public AccessTokenTO getAccessTokenTO(final AccessToken accessToken) { AccessTokenTO accessTokenTO = new AccessTokenTO(); - BeanUtils.copyProperties(accessToken, accessTokenTO, IGNORE_PROPERTIES); - accessTokenTO.setOwner(accessToken.getOwner()); + BeanUtils.copyProperties(accessToken, accessTokenTO); return accessTokenTO; } http://git-wip-us.apache.org/repos/asf/syncope/blob/6fd57211/ext/saml2sp/logic/src/main/java/org/apache/syncope/core/logic/SAML2SPLogic.java ---------------------------------------------------------------------- diff --git a/ext/saml2sp/logic/src/main/java/org/apache/syncope/core/logic/SAML2SPLogic.java b/ext/saml2sp/logic/src/main/java/org/apache/syncope/core/logic/SAML2SPLogic.java index 3b68c48..943401e 100644 --- a/ext/saml2sp/logic/src/main/java/org/apache/syncope/core/logic/SAML2SPLogic.java +++ b/ext/saml2sp/logic/src/main/java/org/apache/syncope/core/logic/SAML2SPLogic.java @@ -18,8 +18,6 @@ */ package org.apache.syncope.core.logic; -import org.apache.syncope.core.logic.saml2.SAML2UserManager; - import com.fasterxml.uuid.Generators; import com.fasterxml.uuid.impl.RandomBasedGenerator; import java.io.OutputStream; @@ -35,7 +33,6 @@ import java.util.Map; import javax.annotation.Resource; import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.tuple.Pair; -import org.apache.commons.lang3.tuple.Triple; import org.apache.cxf.rs.security.jose.jws.JwsJwtCompactConsumer; import org.apache.cxf.rs.security.jose.jws.JwsSignatureVerifier; import org.apache.cxf.rs.security.saml.sso.SSOValidatorResponse; @@ -53,6 +50,7 @@ import org.apache.syncope.common.lib.types.StandardEntitlement; import org.apache.syncope.core.logic.saml2.SAML2ReaderWriter; import org.apache.syncope.core.logic.saml2.SAML2IdPCache; import org.apache.syncope.core.logic.saml2.SAML2IdPEntity; +import org.apache.syncope.core.logic.saml2.SAML2UserManager; import org.apache.syncope.core.persistence.api.dao.AccessTokenDAO; import org.apache.syncope.core.persistence.api.dao.NotFoundException; import org.apache.syncope.core.persistence.api.dao.SAML2IdPDAO; @@ -326,13 +324,13 @@ public class SAML2SPLogic extends AbstractSAML2Logic<AbstractBaseBean> { // 3. generate relay state as JWT Map<String, Object> claims = new HashMap<>(); claims.put(JWT_CLAIM_IDP_DEFLATE, idp.isUseDeflateEncoding()); - Triple<String, String, Date> relayState = - accessTokenDataBinder.generateJWT(authnRequest.getID(), JWT_RELAY_STATE_DURATION, claims); + Pair<String, Date> relayState = accessTokenDataBinder.generateJWT( + UUID_GENERATOR.generate().toString(), authnRequest.getID(), JWT_RELAY_STATE_DURATION, claims); // 4. sign and encode AuthnRequest switch (idp.getBindingType()) { case REDIRECT: - requestTO.setRelayState(URLEncoder.encode(relayState.getMiddle(), StandardCharsets.UTF_8.name())); + requestTO.setRelayState(URLEncoder.encode(relayState.getLeft(), StandardCharsets.UTF_8.name())); requestTO.setContent(URLEncoder.encode( saml2rw.encode(authnRequest, true), StandardCharsets.UTF_8.name())); requestTO.setSignAlg(URLEncoder.encode(saml2rw.getSigAlgo(), StandardCharsets.UTF_8.name())); @@ -343,7 +341,7 @@ public class SAML2SPLogic extends AbstractSAML2Logic<AbstractBaseBean> { case POST: default: - requestTO.setRelayState(relayState.getMiddle()); + requestTO.setRelayState(relayState.getLeft()); saml2rw.sign(authnRequest); requestTO.setContent(saml2rw.encode(authnRequest, idp.isUseDeflateEncoding())); } @@ -515,7 +513,7 @@ public class SAML2SPLogic extends AbstractSAML2Logic<AbstractBaseBean> { if (StringUtils.isNotBlank(userTO.getUsername())) { responseTO.setUsername(userTO.getUsername()); } - + responseTO.setSelfReg(true); return responseTO; @@ -621,9 +619,9 @@ public class SAML2SPLogic extends AbstractSAML2Logic<AbstractBaseBean> { Map<String, Object> claims = new HashMap<>(); claims.put(JWT_CLAIM_IDP_DEFLATE, idp.getBindingType() == SAML2BindingType.REDIRECT ? true : idp.isUseDeflateEncoding()); - Triple<String, String, Date> relayState = - accessTokenDataBinder.generateJWT(logoutRequest.getID(), JWT_RELAY_STATE_DURATION, claims); - requestTO.setRelayState(relayState.getMiddle()); + Pair<String, Date> relayState = accessTokenDataBinder.generateJWT( + UUID_GENERATOR.generate().toString(), logoutRequest.getID(), JWT_RELAY_STATE_DURATION, claims); + requestTO.setRelayState(relayState.getLeft()); // 4. sign and encode AuthnRequest switch (idp.getBindingType()) {