diff --git a/component/org.wso2.carbon.identity.dpop/pom.xml b/component/org.wso2.carbon.identity.dpop/pom.xml index ded463f9..db544c5e 100644 --- a/component/org.wso2.carbon.identity.dpop/pom.xml +++ b/component/org.wso2.carbon.identity.dpop/pom.xml @@ -119,7 +119,7 @@ org.wso2.carbon.identity.oauth2.*; version="${identity.inbound.auth.oauth.imp.pkg.version}", org.wso2.carbon.identity.auth.service.*; - version="${identity.carbon.auth.rest.version}", + version="${identity.carbon.auth.rest.imp.pkg.version}", org.wso2.carbon.identity.base; version="${carbon.identity.package.import.version.range}", org.wso2.carbon.identity.core.*; @@ -135,7 +135,7 @@ version="${org.wso2.carbon.database.utils.version.range}", org.apache.axiom.om.*; version="${axiom.osgi.version.range}", org.wso2.carbon.idp.mgt; - version="${carbon.identity.version}", + version="${carbon.identity.framework.imp.pkg.version.range}", org.wso2.carbon.context.*; version="${carbon.kernel.imp.pkg.version.range}", net.minidev.json.*; version="${net.minidev.json.imp.pkg.version.range}" diff --git a/component/org.wso2.carbon.identity.dpop/src/main/java/org/wso2/carbon/identity/dpop/constant/DPoPConstants.java b/component/org.wso2.carbon.identity.dpop/src/main/java/org/wso2/carbon/identity/dpop/constant/DPoPConstants.java index d5dec5f1..b22b88db 100644 --- a/component/org.wso2.carbon.identity.dpop/src/main/java/org/wso2/carbon/identity/dpop/constant/DPoPConstants.java +++ b/component/org.wso2.carbon.identity.dpop/src/main/java/org/wso2/carbon/identity/dpop/constant/DPoPConstants.java @@ -24,9 +24,9 @@ public class DPoPConstants { public static final String OAUTH_CONFIG_ELEMENT = "OAuth"; - public static final String DPOP_CONFIG_ELEMENT = "DPoPConfig"; + public static final String DPOP_CONFIG_ELEMENT = "DPoP"; public static final String DPOP_ENABLED = "Enable"; - public static final String HEADER_VALIDITY = "OAuth.DPoPConfig.HeaderValidity"; + public static final String HEADER_VALIDITY = "OAuth.DPoP.HeaderValidity"; public static final int DEFAULT_HEADER_VALIDITY = 60000; public static final String DPOP_ISSUED_AT = "iat"; public static final String DPOP_HTTP_URI = "htu"; @@ -35,6 +35,8 @@ public class DPoPConstants { public static final String DPOP_TOKEN_TYPE = "DPoP"; public static final String INVALID_DPOP_PROOF = "invalid_dpop_proof"; public static final String INVALID_DPOP_ERROR = "Invalid DPoP Proof"; + public static final String INVALID_CLIENT = "invalid_client"; + public static final String INVALID_CLIENT_ERROR = "Invalid Client"; public static final String ECDSA_ENCRYPTION = "EC"; public static final String RSA_ENCRYPTION = "RSA"; public static final String HTTP_METHOD ="httpMethod"; @@ -54,6 +56,7 @@ public static class SQLQueries { public static final String RETRIEVE_TOKEN_BINDING_BY_REFRESH_TOKEN = "SELECT BINDING.TOKEN_BINDING_TYPE,BINDING.TOKEN_BINDING_VALUE,BINDING.TOKEN_BINDING_REF " + "FROM IDN_OAUTH2_ACCESS_TOKEN TOKEN LEFT JOIN IDN_OAUTH2_TOKEN_BINDING BINDING ON " + - "TOKEN.TOKEN_ID=BINDING.TOKEN_ID WHERE TOKEN.REFRESH_TOKEN = ?"; + "TOKEN.TOKEN_ID=BINDING.TOKEN_ID WHERE TOKEN.REFRESH_TOKEN = ? " + + "AND BINDING.TOKEN_BINDING_TYPE = ?"; } } diff --git a/component/org.wso2.carbon.identity.dpop/src/main/java/org/wso2/carbon/identity/dpop/dao/DPoPTokenManagerDAOImpl.java b/component/org.wso2.carbon.identity.dpop/src/main/java/org/wso2/carbon/identity/dpop/dao/DPoPTokenManagerDAOImpl.java index 12744f21..49e9dc8d 100644 --- a/component/org.wso2.carbon.identity.dpop/src/main/java/org/wso2/carbon/identity/dpop/dao/DPoPTokenManagerDAOImpl.java +++ b/component/org.wso2.carbon.identity.dpop/src/main/java/org/wso2/carbon/identity/dpop/dao/DPoPTokenManagerDAOImpl.java @@ -68,7 +68,11 @@ private TokenBinding getBindingFromRefreshToken(String refreshToken,boolean isTo return tokenBinding; }, - preparedStatement -> preparedStatement.setString(1, finalRefreshToken)); + preparedStatement -> { + int parameterIndex = 0; + preparedStatement.setString(++parameterIndex, finalRefreshToken); + preparedStatement.setString(++parameterIndex, DPoPConstants.DPOP_TOKEN_TYPE); + }); return tokenBindingList.isEmpty() ? null : tokenBindingList.get(0); } catch (DataAccessException e) { diff --git a/component/org.wso2.carbon.identity.dpop/src/main/java/org/wso2/carbon/identity/dpop/listener/OauthDPoPInterceptorHandlerProxy.java b/component/org.wso2.carbon.identity.dpop/src/main/java/org/wso2/carbon/identity/dpop/listener/OauthDPoPInterceptorHandlerProxy.java index 93a97c9b..e08b93d1 100644 --- a/component/org.wso2.carbon.identity.dpop/src/main/java/org/wso2/carbon/identity/dpop/listener/OauthDPoPInterceptorHandlerProxy.java +++ b/component/org.wso2.carbon.identity.dpop/src/main/java/org/wso2/carbon/identity/dpop/listener/OauthDPoPInterceptorHandlerProxy.java @@ -84,7 +84,7 @@ public void onPreTokenIssue(OAuth2AccessTokenReqDTO tokenReqDTO, OAuthTokenReqMe } } } catch (InvalidOAuthClientException e) { - throw new IdentityOAuth2ClientException("invalid_client", "Invalid Client"); + throw new IdentityOAuth2ClientException(DPoPConstants.INVALID_CLIENT, DPoPConstants.INVALID_CLIENT_ERROR); } } @@ -100,39 +100,49 @@ public void onPreTokenRenewal(OAuth2AccessTokenReqDTO tokenReqDTO, OAuthTokenReq log.debug(String.format("DPoP proxy intercepted the token renewal request from the client : %s.", consumerKey)); } + try { + String tokenBindingType = DPoPHeaderValidator.getApplicationBindingType(tokenReqDTO.getClientId()); + TokenBinding tokenBinding = + tokenBindingTypeManagerDao.getTokenBinding(tokenReqDTO.getRefreshToken(), OAuth2Util.isHashEnabled()); + if (tokenBinding != null) { + if (!DPoPConstants.DPOP_TOKEN_TYPE.equals(tokenBindingType)) { + if (log.isDebugEnabled()) { + log.debug(String.format("DPoP based token binding is not enabled for the " + + "application Id : %s.", consumerKey)); + } + throw new IdentityOAuth2ClientException(DPoPConstants.INVALID_CLIENT, + DPoPConstants.INVALID_CLIENT_ERROR); + } - // Check if the Refresh token is of DPoP type. - boolean isDPoPBinding = false; - TokenBinding tokenBinding = - tokenBindingTypeManagerDao.getTokenBinding(tokenReqDTO.getRefreshToken(), OAuth2Util.isHashEnabled()); - if (tokenBinding != null && - StringUtils.equalsIgnoreCase(DPoPConstants.DPOP_TOKEN_TYPE, tokenBinding.getBindingType())) { - isDPoPBinding = true; - } - - String dPoPProof = DPoPHeaderValidator.getDPoPHeader(tokReqMsgCtx); - if (isDPoPBinding && StringUtils.isNotBlank(dPoPProof)) { + String dPoPProof = DPoPHeaderValidator.getDPoPHeader(tokReqMsgCtx); + if (StringUtils.isBlank(dPoPProof)) { + if (log.isDebugEnabled()) { + log.debug(String.format("Renewal request received without the DPoP proof from the " + + "application Id: %s.", consumerKey)); + } + throw new IdentityOAuth2ClientException(DPoPConstants.INVALID_DPOP_PROOF, + "DPoP proof is required."); + } - if (!DPoPHeaderValidator.isValidDPoP(dPoPProof, tokenReqDTO, tokReqMsgCtx)) { - if (log.isDebugEnabled()) { - log.debug(String.format("DPoP proof validation failed for the application Id : %s.", consumerKey)); + if (!DPoPHeaderValidator.isValidDPoP(dPoPProof, tokenReqDTO, tokReqMsgCtx)) { + if (log.isDebugEnabled()) { + log.debug(String.format("DPoP proof validation failed for the application Id : %s.", + consumerKey)); + } + throw new IdentityOAuth2ClientException(DPoPConstants.INVALID_DPOP_PROOF, + DPoPConstants.INVALID_DPOP_ERROR); + } + if (!tokReqMsgCtx.getTokenBinding().getBindingValue().equalsIgnoreCase(tokenBinding.getBindingValue())) { + if (log.isDebugEnabled()) { + log.debug("DPoP proof thumbprint value of the public key is not equal to binding value from" + + " the refresh token."); + } + throw new IdentityOAuth2ClientException(DPoPConstants.INVALID_DPOP_PROOF, + DPoPConstants.INVALID_DPOP_ERROR); } - throw new IdentityOAuth2ClientException(DPoPConstants.INVALID_DPOP_PROOF, - DPoPConstants.INVALID_DPOP_ERROR); - } - if (!tokReqMsgCtx.getTokenBinding().getBindingValue().equalsIgnoreCase(tokenBinding.getBindingValue())) { - log.error("DPoP proof thumbprint value of the public key is not equal to binding value from" + - " the refresh token."); - throw new IdentityOAuth2ClientException(DPoPConstants.INVALID_DPOP_PROOF, - DPoPConstants.INVALID_DPOP_ERROR); - } - } else if (isDPoPBinding) { - if (log.isDebugEnabled()) { - log.debug(String.format("Renewal request received without the DPoP proof from the application Id: %s.", - consumerKey)); } - - throw new IdentityOAuth2ClientException(DPoPConstants.INVALID_DPOP_PROOF, "DPoP proof is required."); + } catch (InvalidOAuthClientException e) { + throw new IdentityOAuth2ClientException(DPoPConstants.INVALID_CLIENT, DPoPConstants.INVALID_CLIENT_ERROR); } } diff --git a/component/org.wso2.carbon.identity.dpop/src/main/java/org/wso2/carbon/identity/dpop/validators/DPoPHeaderValidator.java b/component/org.wso2.carbon.identity.dpop/src/main/java/org/wso2/carbon/identity/dpop/validators/DPoPHeaderValidator.java index 1e9db48f..6b57d4e4 100644 --- a/component/org.wso2.carbon.identity.dpop/src/main/java/org/wso2/carbon/identity/dpop/validators/DPoPHeaderValidator.java +++ b/component/org.wso2.carbon.identity.dpop/src/main/java/org/wso2/carbon/identity/dpop/validators/DPoPHeaderValidator.java @@ -44,6 +44,7 @@ import java.sql.Timestamp; import java.text.ParseException; import java.util.Date; + import javax.servlet.http.HttpServletRequest; /** @@ -261,8 +262,17 @@ private static boolean checkHTTPURI(String httpUrl, JWTClaimsSet jwtClaimsSet) t private static int getDPoPValidityPeriod() { String validityPeriod = IdentityUtil.getProperty(DPoPConstants.HEADER_VALIDITY); - return StringUtils.isNotBlank(validityPeriod) ? Integer.parseInt(validityPeriod.trim()) * 1000 - : DPoPConstants.DEFAULT_HEADER_VALIDITY; + if (StringUtils.isNotBlank(validityPeriod)) { + if (Integer.parseInt(validityPeriod.trim()) < 0) { + if (log.isDebugEnabled()) { + log.debug("Configured dpop validity period is set to a negative value.Hence the default validity " + + "period will be used."); + } + return DPoPConstants.DEFAULT_HEADER_VALIDITY; + } + return Integer.parseInt(validityPeriod.trim()) * 1000; + } + return DPoPConstants.DEFAULT_HEADER_VALIDITY; } private static void setCnFValue(OAuthTokenReqMessageContext tokReqMsgCtx, String tokenBindingValue) { diff --git a/component/org.wso2.carbon.identity.oauth2.token.handler.clientauth.mutualtls/src/test/java/org/wso2/carbon/identity/oauth2/token/handler/clientauth/mutualtls/utils/MutualTLSUtilTest.java b/component/org.wso2.carbon.identity.oauth2.token.handler.clientauth.mutualtls/src/test/java/org/wso2/carbon/identity/oauth2/token/handler/clientauth/mutualtls/utils/MutualTLSUtilTest.java index 4de22f62..c4ed4db3 100644 --- a/component/org.wso2.carbon.identity.oauth2.token.handler.clientauth.mutualtls/src/test/java/org/wso2/carbon/identity/oauth2/token/handler/clientauth/mutualtls/utils/MutualTLSUtilTest.java +++ b/component/org.wso2.carbon.identity.oauth2.token.handler.clientauth.mutualtls/src/test/java/org/wso2/carbon/identity/oauth2/token/handler/clientauth/mutualtls/utils/MutualTLSUtilTest.java @@ -85,7 +85,7 @@ public void testGetThumbPrint() throws Exception { X509Certificate Cert = (X509Certificate) factory.generateCertificate( new ByteArrayInputStream(DatatypeConverter.parseBase64Binary(CERTIFICATE_CONTENT))); assertEquals(MutualTLSUtil.getThumbPrint(Cert, null), - "OTE2OWI4MzQ0MTQ5ZDMzMTk3ZmI2NjNjOGYyNjZhNTZhYzgxZWU5Zg"); + "YTJkZTg5OGQ3NWUwMTQ2N2UwYTcwMGE1ZTFmMTcyMjE5ZGUwMDBiMDE2ZWVhOWI0NjY1OWQ4YTZlZjQ3YzJmMQ"); } diff --git a/pom.xml b/pom.xml index a3797b00..342039cb 100644 --- a/pom.xml +++ b/pom.xml @@ -388,13 +388,15 @@ - 5.20.66 - 6.2.18 + 5.20.234 + [5.17.5, 6.0.0) + + 6.7.70 2.0.7 [2.0.0,2.1.0) [6.2.18,7.0.0) - 1.4.0 + 1.4.47 [1.0.0,2.0.0) 4.6.0