diff --git a/components/org.wso2.carbon.identity.api.server.dcr/src/gen/java/org/wso2/carbon/identity/oauth2/dcr/endpoint/dto/ApplicationDTO.java b/components/org.wso2.carbon.identity.api.server.dcr/src/gen/java/org/wso2/carbon/identity/oauth2/dcr/endpoint/dto/ApplicationDTO.java
index a66d1be779..f7d980a4e1 100644
--- a/components/org.wso2.carbon.identity.api.server.dcr/src/gen/java/org/wso2/carbon/identity/oauth2/dcr/endpoint/dto/ApplicationDTO.java
+++ b/components/org.wso2.carbon.identity.api.server.dcr/src/gen/java/org/wso2/carbon/identity/oauth2/dcr/endpoint/dto/ApplicationDTO.java
@@ -65,6 +65,7 @@ public class ApplicationDTO {
private String jwksUri = null;
private String tokenEndpointAuthMethod = null;
+ private Boolean tokenEndpointAllowReusePvtKeyJwt = null;
private String tokenEndpointAuthSigningAlg = null;
private String sectorIdentifierUri = null;
private String idTokenSignedResponseAlg = null;
@@ -292,6 +293,17 @@ public void setTokenEndpointAuthMethod(String tokenEndpointAuthMethod) {
this.tokenEndpointAuthMethod = tokenEndpointAuthMethod;
}
+ @ApiModelProperty(value = "")
+ @JsonProperty("token_endpoint_allow_reuse_pvt_key_jwt")
+ public Boolean isTokenEndpointAllowReusePvtKeyJwt() {
+
+ return tokenEndpointAllowReusePvtKeyJwt;
+ }
+
+ public void setTokenEndpointAllowReusePvtKeyJwt(Boolean tokenEndpointAllowReusePvtKeyJwt) {
+
+ this.tokenEndpointAllowReusePvtKeyJwt = tokenEndpointAllowReusePvtKeyJwt;
+ }
@ApiModelProperty(value = "")
@JsonProperty("token_endpoint_auth_signing_alg")
diff --git a/components/org.wso2.carbon.identity.api.server.dcr/src/gen/java/org/wso2/carbon/identity/oauth2/dcr/endpoint/dto/RegistrationRequestDTO.java b/components/org.wso2.carbon.identity.api.server.dcr/src/gen/java/org/wso2/carbon/identity/oauth2/dcr/endpoint/dto/RegistrationRequestDTO.java
index 92e34409e4..e42227c3b0 100644
--- a/components/org.wso2.carbon.identity.api.server.dcr/src/gen/java/org/wso2/carbon/identity/oauth2/dcr/endpoint/dto/RegistrationRequestDTO.java
+++ b/components/org.wso2.carbon.identity.api.server.dcr/src/gen/java/org/wso2/carbon/identity/oauth2/dcr/endpoint/dto/RegistrationRequestDTO.java
@@ -49,6 +49,7 @@ public class RegistrationRequestDTO {
private String extTokenType = null;
private String tokenEndpointAuthMethod = null;
private String tokenEndpointAuthSigningAlg = null;
+ private Boolean tokenEndpointAllowReusePvtKeyJwt;
private String sectorIdentifierUri = null;
private String idTokenSignedResponseAlg = null;
private String idTokenEncryptedResponseAlg = null;
@@ -332,6 +333,18 @@ public void setTokenEndpointAuthMethod(String tokenEndpointAuthMethod) {
this.tokenEndpointAuthMethod = tokenEndpointAuthMethod;
}
+ @ApiModelProperty(value = "")
+ @JsonProperty("token_endpoint_allow_reuse_pvt_key_jwt")
+ public Boolean isTokenEndpointAllowReusePvtKeyJwt() {
+
+ return tokenEndpointAllowReusePvtKeyJwt;
+ }
+
+ public void setTokenEndpointAllowReusePvtKeyJwt(Boolean tokenEndpointAllowReusePvtKeyJwt) {
+
+ this.tokenEndpointAllowReusePvtKeyJwt = tokenEndpointAllowReusePvtKeyJwt;
+ }
+
@ApiModelProperty(value = "")
@JsonProperty("token_endpoint_auth_signing_alg")
diff --git a/components/org.wso2.carbon.identity.api.server.dcr/src/gen/java/org/wso2/carbon/identity/oauth2/dcr/endpoint/dto/UpdateRequestDTO.java b/components/org.wso2.carbon.identity.api.server.dcr/src/gen/java/org/wso2/carbon/identity/oauth2/dcr/endpoint/dto/UpdateRequestDTO.java
index 81471cc237..085eb32d26 100644
--- a/components/org.wso2.carbon.identity.api.server.dcr/src/gen/java/org/wso2/carbon/identity/oauth2/dcr/endpoint/dto/UpdateRequestDTO.java
+++ b/components/org.wso2.carbon.identity.api.server.dcr/src/gen/java/org/wso2/carbon/identity/oauth2/dcr/endpoint/dto/UpdateRequestDTO.java
@@ -36,6 +36,7 @@ public class UpdateRequestDTO {
private boolean extPublicClient;
private String extTokenType = null;
private String tokenEndpointAuthMethod = null;
+ private Boolean tokenEndpointAllowReusePvtKeyJwt;
private String tokenEndpointAuthSigningAlg = null;
private String sectorIdentifierUri = null;
private String idTokenSignedResponseAlg = null;
@@ -241,6 +242,18 @@ public void setTokenEndpointAuthMethod(String tokenEndpointAuthMethod) {
this.tokenEndpointAuthMethod = tokenEndpointAuthMethod;
}
+ @ApiModelProperty(value = "")
+ @JsonProperty("token_endpoint_allow_reuse_pvt_key_jwt")
+ public Boolean isTokenEndpointAllowReusePvtKeyJwt() {
+
+ return tokenEndpointAllowReusePvtKeyJwt;
+ }
+
+ public void setTokenEndpointAllowReusePvtKeyJwt(Boolean tokenEndpointAllowReusePvtKeyJwt) {
+
+ this.tokenEndpointAllowReusePvtKeyJwt = tokenEndpointAllowReusePvtKeyJwt;
+ }
+
@ApiModelProperty(value = "")
@JsonProperty("token_endpoint_auth_signing_alg")
public String getTokenEndpointAuthSigningAlg() {
diff --git a/components/org.wso2.carbon.identity.api.server.dcr/src/main/java/org/wso2/carbon/identity/oauth2/dcr/endpoint/util/DCRMUtils.java b/components/org.wso2.carbon.identity.api.server.dcr/src/main/java/org/wso2/carbon/identity/oauth2/dcr/endpoint/util/DCRMUtils.java
index 8e46d6c25f..23e87ffa55 100644
--- a/components/org.wso2.carbon.identity.api.server.dcr/src/main/java/org/wso2/carbon/identity/oauth2/dcr/endpoint/util/DCRMUtils.java
+++ b/components/org.wso2.carbon.identity.api.server.dcr/src/main/java/org/wso2/carbon/identity/oauth2/dcr/endpoint/util/DCRMUtils.java
@@ -81,6 +81,8 @@ public static ApplicationRegistrationRequest getApplicationRegistrationRequest(
appRegistrationRequest.setExtTokenType(registrationRequestDTO.getExtTokenType());
appRegistrationRequest.setJwksURI(registrationRequestDTO.getJwksUri());
appRegistrationRequest.setTokenEndpointAuthMethod(registrationRequestDTO.getTokenEndpointAuthMethod());
+ appRegistrationRequest.setTokenEndpointAllowReusePvtKeyJwt(registrationRequestDTO
+ .isTokenEndpointAllowReusePvtKeyJwt());
appRegistrationRequest.setTokenEndpointAuthSignatureAlgorithm
(registrationRequestDTO.getTokenEndpointAuthSigningAlg());
appRegistrationRequest.setSectorIdentifierURI(registrationRequestDTO.getSectorIdentifierUri());
@@ -125,6 +127,8 @@ public static ApplicationUpdateRequest getApplicationUpdateRequest(UpdateRequest
applicationUpdateRequest.setExtTokenType(updateRequestDTO.getExtTokenType());
applicationUpdateRequest.setJwksURI(updateRequestDTO.getJwksUri());
applicationUpdateRequest.setTokenEndpointAuthMethod(updateRequestDTO.getTokenEndpointAuthMethod());
+ applicationUpdateRequest.setTokenEndpointAllowReusePvtKeyJwt(
+ updateRequestDTO.isTokenEndpointAllowReusePvtKeyJwt());
applicationUpdateRequest.setTokenEndpointAuthSignatureAlgorithm
(updateRequestDTO.getTokenEndpointAuthSigningAlg());
applicationUpdateRequest.setSectorIdentifierURI(updateRequestDTO.getSectorIdentifierUri());
@@ -235,6 +239,7 @@ public static ApplicationDTO getApplicationDTOFromApplication(Application applic
applicationDTO.setExtTokenType(application.getExtTokenType());
applicationDTO.setJwksUri(application.getJwksURI());
applicationDTO.setTokenEndpointAuthMethod(application.getTokenEndpointAuthMethod());
+ applicationDTO.setTokenEndpointAllowReusePvtKeyJwt(application.isTokenEndpointAllowReusePvtKeyJwt());
applicationDTO.setTokenEndpointAuthSigningAlg(application.getTokenEndpointAuthSignatureAlgorithm());
applicationDTO.setSectorIdentifierUri(application.getSectorIdentifierURI());
applicationDTO.setIdTokenSignedResponseAlg(application.getIdTokenSignatureAlgorithm());
diff --git a/components/org.wso2.carbon.identity.oauth.common/src/main/java/org/wso2/carbon/identity/oauth/common/OAuthConstants.java b/components/org.wso2.carbon.identity.oauth.common/src/main/java/org/wso2/carbon/identity/oauth/common/OAuthConstants.java
index 57e7feac1e..94b888cec6 100644
--- a/components/org.wso2.carbon.identity.oauth.common/src/main/java/org/wso2/carbon/identity/oauth/common/OAuthConstants.java
+++ b/components/org.wso2.carbon.identity.oauth.common/src/main/java/org/wso2/carbon/identity/oauth/common/OAuthConstants.java
@@ -622,6 +622,7 @@ public static class OIDCConfigProperties {
public static final String TOKEN_BINDING_VALIDATION = "tokenBindingValidation";
public static final String TOKEN_BINDING_TYPE_NONE = "None";
public static final String TOKEN_AUTH_METHOD = "tokenEndpointAuthMethod";
+ public static final String TOKEN_EP_ALLOW_REUSE_PVT_KEY_JWT = "tokenEndpointAllowReusePvtKeyJwt";
public static final String TOKEN_AUTH_SIGNATURE_ALGORITHM = "tokenEndpointAuthSigningAlg";
public static final String SECTOR_IDENTIFIER_URI = "sectorIdentifierUri";
public static final String ID_TOKEN_SIGNATURE_ALGORITHM = "idTokenSignedResponseAlg";
@@ -636,7 +637,14 @@ public static class OIDCConfigProperties {
public static final String IS_SUBJECT_TOKEN_ENABLED = "isSubjectTokenEnabled";
public static final String SUBJECT_TOKEN_EXPIRY_TIME = "subjectTokenExpiryTime";
public static final int SUBJECT_TOKEN_EXPIRY_TIME_VALUE = 180;
-
+ public static final String PREVENT_TOKEN_REUSE = "PreventTokenReuse";
+ public static final boolean DEFAULT_VALUE_FOR_PREVENT_TOKEN_REUSE = true;
+ // Name of the {@code JWTClientAuthenticatorConfig} resource type in the Configuration Management API.
+ public static final String JWT_CONFIGURATION_RESOURCE_TYPE_NAME = "PK_JWT_CONFIGURATION";
+ // Name of the {@code JWTClientAuthenticatorConfig} resource (per tenant) in the Configuration Management API.
+ public static final String JWT_CONFIGURATION_RESOURCE_NAME = "TENANT_PK_JWT_CONFIGURATION";
+ public static final String PVT_KEY_JWT_CLIENT_AUTHENTICATOR_CLASS_NAME = "PrivateKeyJWTClientAuthenticator";
+ public static final String ENABLE_TOKEN_REUSE = "EnableTokenReuse";
private OIDCConfigProperties() {
}
diff --git a/components/org.wso2.carbon.identity.oauth.dcr/src/main/java/org/wso2/carbon/identity/oauth/dcr/bean/Application.java b/components/org.wso2.carbon.identity.oauth.dcr/src/main/java/org/wso2/carbon/identity/oauth/dcr/bean/Application.java
index bb555c1f16..7f0d3907f2 100644
--- a/components/org.wso2.carbon.identity.oauth.dcr/src/main/java/org/wso2/carbon/identity/oauth/dcr/bean/Application.java
+++ b/components/org.wso2.carbon.identity.oauth.dcr/src/main/java/org/wso2/carbon/identity/oauth/dcr/bean/Application.java
@@ -46,6 +46,7 @@ public class Application implements Serializable {
private String extTokenType = null;
private String jwksURI = null;
private String tokenEndpointAuthMethod = null;
+ private Boolean tokenEndpointAllowReusePvtKeyJwt;
private String tokenEndpointAuthSignatureAlgorithm = null;
private String sectorIdentifierURI = null;
private String idTokenSignatureAlgorithm = null;
@@ -253,6 +254,16 @@ public void setTokenEndpointAuthMethod(String tokenEndpointAuthMethod) {
this.tokenEndpointAuthMethod = tokenEndpointAuthMethod;
}
+ public Boolean isTokenEndpointAllowReusePvtKeyJwt() {
+
+ return tokenEndpointAllowReusePvtKeyJwt;
+ }
+
+ public void setTokenEndpointAllowReusePvtKeyJwt(Boolean tokenEndpointAllowReusePvtKeyJwt) {
+
+ this.tokenEndpointAllowReusePvtKeyJwt = tokenEndpointAllowReusePvtKeyJwt;
+ }
+
public String getTokenEndpointAuthSignatureAlgorithm() {
return tokenEndpointAuthSignatureAlgorithm;
diff --git a/components/org.wso2.carbon.identity.oauth.dcr/src/main/java/org/wso2/carbon/identity/oauth/dcr/bean/ApplicationRegistrationRequest.java b/components/org.wso2.carbon.identity.oauth.dcr/src/main/java/org/wso2/carbon/identity/oauth/dcr/bean/ApplicationRegistrationRequest.java
index af1666e651..068fa18637 100644
--- a/components/org.wso2.carbon.identity.oauth.dcr/src/main/java/org/wso2/carbon/identity/oauth/dcr/bean/ApplicationRegistrationRequest.java
+++ b/components/org.wso2.carbon.identity.oauth.dcr/src/main/java/org/wso2/carbon/identity/oauth/dcr/bean/ApplicationRegistrationRequest.java
@@ -52,6 +52,7 @@ public class ApplicationRegistrationRequest implements Serializable {
private String jwksURI;
private String softwareStatement;
private String tokenEndpointAuthMethod;
+ private Boolean tokenEndpointAllowReusePvtKeyJwt;
private String tokenEndpointAuthSignatureAlgorithm;
private String sectorIdentifierURI;
private String idTokenSignatureAlgorithm;
@@ -380,6 +381,16 @@ public void setTokenEndpointAuthMethod(String tokenEndpointAuthMethod) {
this.tokenEndpointAuthMethod = tokenEndpointAuthMethod;
}
+ public Boolean isTokenEndpointAllowReusePvtKeyJwt() {
+
+ return tokenEndpointAllowReusePvtKeyJwt;
+ }
+
+ public void setTokenEndpointAllowReusePvtKeyJwt(Boolean tokenEndpointAllowReusePvtKeyJwt) {
+
+ this.tokenEndpointAllowReusePvtKeyJwt = tokenEndpointAllowReusePvtKeyJwt;
+ }
+
public String getTokenEndpointAuthSignatureAlgorithm() {
return tokenEndpointAuthSignatureAlgorithm;
diff --git a/components/org.wso2.carbon.identity.oauth.dcr/src/main/java/org/wso2/carbon/identity/oauth/dcr/bean/ApplicationUpdateRequest.java b/components/org.wso2.carbon.identity.oauth.dcr/src/main/java/org/wso2/carbon/identity/oauth/dcr/bean/ApplicationUpdateRequest.java
index b98772d5dd..443821cd55 100644
--- a/components/org.wso2.carbon.identity.oauth.dcr/src/main/java/org/wso2/carbon/identity/oauth/dcr/bean/ApplicationUpdateRequest.java
+++ b/components/org.wso2.carbon.identity.oauth.dcr/src/main/java/org/wso2/carbon/identity/oauth/dcr/bean/ApplicationUpdateRequest.java
@@ -48,6 +48,7 @@ public class ApplicationUpdateRequest implements Serializable {
private String jwksURI = null;
private String softwareStatement;
private String tokenEndpointAuthMethod;
+ private Boolean tokenEndpointAllowReusePvtKeyJwt;
private String tokenEndpointAuthSignatureAlgorithm;
private String sectorIdentifierURI;
private String idTokenSignatureAlgorithm;
@@ -305,6 +306,16 @@ public void setTokenEndpointAuthMethod(String tokenEndpointAuthMethod) {
this.tokenEndpointAuthMethod = tokenEndpointAuthMethod;
}
+ public Boolean isTokenEndpointAllowReusePvtKeyJwt() {
+
+ return tokenEndpointAllowReusePvtKeyJwt;
+ }
+
+ public void setTokenEndpointAllowReusePvtKeyJwt(Boolean tokenEndpointAllowReusePvtKeyJwt) {
+
+ this.tokenEndpointAllowReusePvtKeyJwt = tokenEndpointAllowReusePvtKeyJwt;
+ }
+
public String getTokenEndpointAuthSignatureAlgorithm() {
return tokenEndpointAuthSignatureAlgorithm;
diff --git a/components/org.wso2.carbon.identity.oauth.dcr/src/main/java/org/wso2/carbon/identity/oauth/dcr/service/DCRMService.java b/components/org.wso2.carbon.identity.oauth.dcr/src/main/java/org/wso2/carbon/identity/oauth/dcr/service/DCRMService.java
index 6aa00ca66a..994bd068fa 100644
--- a/components/org.wso2.carbon.identity.oauth.dcr/src/main/java/org/wso2/carbon/identity/oauth/dcr/service/DCRMService.java
+++ b/components/org.wso2.carbon.identity.oauth.dcr/src/main/java/org/wso2/carbon/identity/oauth/dcr/service/DCRMService.java
@@ -351,6 +351,7 @@ public Application updateApplication(ApplicationUpdateRequest updateRequest, Str
if (updateRequest.getTokenEndpointAuthMethod() != null) {
appDTO.setTokenEndpointAuthMethod(updateRequest.getTokenEndpointAuthMethod());
}
+ appDTO.setTokenEndpointAllowReusePvtKeyJwt(updateRequest.isTokenEndpointAllowReusePvtKeyJwt());
if (updateRequest.getTokenEndpointAuthSignatureAlgorithm() != null) {
appDTO.setTokenEndpointAuthSignatureAlgorithm
(updateRequest.getTokenEndpointAuthSignatureAlgorithm());
@@ -670,6 +671,7 @@ private Application buildResponse(OAuthConsumerAppDTO createdApp, String tenantD
application.setExtTokenType(createdApp.getTokenType());
application.setJwksURI(createdApp.getJwksURI());
application.setTokenEndpointAuthMethod(createdApp.getTokenEndpointAuthMethod());
+ application.setTokenEndpointAllowReusePvtKeyJwt(createdApp.isTokenEndpointAllowReusePvtKeyJwt());
application.setTokenEndpointAuthSignatureAlgorithm(createdApp.getTokenEndpointAuthSignatureAlgorithm());
application.setSectorIdentifierURI(createdApp.getSectorIdentifierURI());
application.setIdTokenSignatureAlgorithm(createdApp.getIdTokenSignatureAlgorithm());
@@ -764,6 +766,7 @@ private OAuthConsumerAppDTO createOAuthApp(ApplicationRegistrationRequest regist
if (registrationRequest.getTokenEndpointAuthMethod() != null) {
oAuthConsumerApp.setTokenEndpointAuthMethod(registrationRequest.getTokenEndpointAuthMethod());
}
+ oAuthConsumerApp.setTokenEndpointAllowReusePvtKeyJwt(registrationRequest.isTokenEndpointAllowReusePvtKeyJwt());
if (registrationRequest.getTokenEndpointAuthSignatureAlgorithm() != null) {
oAuthConsumerApp.setTokenEndpointAuthSignatureAlgorithm
(registrationRequest.getTokenEndpointAuthSignatureAlgorithm());
diff --git a/components/org.wso2.carbon.identity.oauth.stub/src/main/resources/OAuthAdminService.wsdl b/components/org.wso2.carbon.identity.oauth.stub/src/main/resources/OAuthAdminService.wsdl
old mode 100644
new mode 100755
index 8b9539eddc..a1b5a18871
--- a/components/org.wso2.carbon.identity.oauth.stub/src/main/resources/OAuthAdminService.wsdl
+++ b/components/org.wso2.carbon.identity.oauth.stub/src/main/resources/OAuthAdminService.wsdl
@@ -432,6 +432,7 @@
+
diff --git a/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth/OAuthAdminServiceImpl.java b/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth/OAuthAdminServiceImpl.java
old mode 100644
new mode 100755
index 068ac62c57..3129f55459
--- a/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth/OAuthAdminServiceImpl.java
+++ b/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth/OAuthAdminServiceImpl.java
@@ -107,6 +107,7 @@
import static org.wso2.carbon.identity.oauth.OAuthUtil.handleErrorWithExceptionType;
import static org.wso2.carbon.identity.oauth.common.OAuthConstants.OauthAppStates.APP_STATE_ACTIVE;
import static org.wso2.carbon.identity.oauth.common.OAuthConstants.OauthAppStates.APP_STATE_DELETED;
+import static org.wso2.carbon.identity.oauth.common.OAuthConstants.PRIVATE_KEY_JWT;
import static org.wso2.carbon.identity.oauth.common.OAuthConstants.TokenBindings.NONE;
import static org.wso2.carbon.identity.oauth2.util.OAuth2Util.buildScopeString;
import static org.wso2.carbon.identity.oauth2.util.OAuth2Util.getTenantId;
@@ -429,6 +430,13 @@ OAuthConsumerAppDTO registerAndRetrieveOAuthApplicationData(OAuthConsumerAppDTO
}
app.setTokenEndpointAuthMethod(tokenEndpointAuthMethod);
}
+ Boolean tokenEndpointAllowReusePvtKeyJwt = application.isTokenEndpointAllowReusePvtKeyJwt();
+ if (isInvalidTokenEPReusePvtKeyJwtRequest(tokenEndpointAuthMethod,
+ tokenEndpointAllowReusePvtKeyJwt)) {
+ throw handleClientError(INVALID_REQUEST, "Requested client authentication method " +
+ "incompatible with the Private Key JWT Reuse config value.");
+ }
+ app.setTokenEndpointAllowReusePvtKeyJwt(tokenEndpointAllowReusePvtKeyJwt);
String tokenEndpointAuthSigningAlgorithm = application.getTokenEndpointAuthSignatureAlgorithm();
if (StringUtils.isNotEmpty(tokenEndpointAuthSigningAlgorithm)) {
if (isFAPIConformanceEnabled) {
@@ -855,6 +863,13 @@ void updateConsumerApplication(OAuthConsumerAppDTO consumerAppDTO, boolean enabl
}
oAuthAppDO.setTokenEndpointAuthMethod(tokenEndpointAuthMethod);
+ Boolean tokenEndpointAllowReusePvtKeyJwt = consumerAppDTO.isTokenEndpointAllowReusePvtKeyJwt();
+ if (isInvalidTokenEPReusePvtKeyJwtRequest(tokenEndpointAuthMethod, tokenEndpointAllowReusePvtKeyJwt)) {
+ throw handleClientError(INVALID_REQUEST, "Requested client authentication method " +
+ "incompatible with the Private Key JWT Reuse config value.");
+ }
+ oAuthAppDO.setTokenEndpointAllowReusePvtKeyJwt(tokenEndpointAllowReusePvtKeyJwt);
+
String tokenEndpointAuthSignatureAlgorithm = consumerAppDTO.getTokenEndpointAuthSignatureAlgorithm();
if (StringUtils.isNotEmpty(tokenEndpointAuthSignatureAlgorithm)) {
if (isFAPIConformanceEnabled) {
@@ -2492,6 +2507,24 @@ private void handleInternalTokenRevocation(String consumerKey, Properties proper
}
}
+ /**
+ * Return whether the request of updating the tokenEndpointAllowReusePvtKeyJwt is valid.
+ *
+ * @param tokenEndpointAuthMethod token endpoint client authentication method.
+ * @param tokenEndpointAllowReusePvtKeyJwt During client authentication whether to reuse private key JWT.
+ * @return True if tokenEndpointAuthMethod and tokenEndpointAllowReusePvtKeyJwt is NOT in the correct format.
+ */
+ private boolean isInvalidTokenEPReusePvtKeyJwtRequest(String tokenEndpointAuthMethod,
+ Boolean tokenEndpointAllowReusePvtKeyJwt) {
+
+ if (StringUtils.isNotBlank(tokenEndpointAuthMethod)) {
+ if (tokenEndpointAuthMethod.equals(PRIVATE_KEY_JWT)) {
+ return tokenEndpointAllowReusePvtKeyJwt == null;
+ }
+ }
+ return tokenEndpointAllowReusePvtKeyJwt != null;
+ }
+
/**
* FAPI validation to restrict the token endpoint authentication methods.
* Link - https://openid.net/specs/openid-financial-api-part-2-1_0.html#authorization-server (5.2.2 - 14)
diff --git a/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth/OAuthUtil.java b/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth/OAuthUtil.java
old mode 100644
new mode 100755
index 2fe5e743a0..2ca4524208
--- a/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth/OAuthUtil.java
+++ b/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth/OAuthUtil.java
@@ -37,6 +37,11 @@
import org.wso2.carbon.identity.application.mgt.ApplicationManagementService;
import org.wso2.carbon.identity.base.IdentityConstants;
import org.wso2.carbon.identity.central.log.mgt.utils.LoggerUtils;
+import org.wso2.carbon.identity.configuration.mgt.core.exception.ConfigurationManagementException;
+import org.wso2.carbon.identity.configuration.mgt.core.model.Attribute;
+import org.wso2.carbon.identity.configuration.mgt.core.model.Resource;
+import org.wso2.carbon.identity.core.handler.AbstractIdentityHandler;
+import org.wso2.carbon.identity.core.model.IdentityEventListenerConfig;
import org.wso2.carbon.identity.core.util.IdentityTenantUtil;
import org.wso2.carbon.identity.core.util.IdentityUtil;
import org.wso2.carbon.identity.oauth.cache.OAuthCache;
@@ -77,6 +82,7 @@
import java.util.HashSet;
import java.util.List;
import java.util.Map;
+import java.util.Objects;
import java.util.Optional;
import java.util.Set;
import java.util.UUID;
@@ -89,6 +95,12 @@
import static org.wso2.carbon.identity.application.authentication.framework.util.FrameworkConstants.CURRENT_TOKEN_IDENTIFIER;
import static org.wso2.carbon.identity.application.authentication.framework.util.FrameworkConstants.Config.PRESERVE_LOGGED_IN_SESSION_AT_PASSWORD_UPDATE;
import static org.wso2.carbon.identity.application.authentication.framework.util.FrameworkConstants.ORGANIZATION_LOGIN_HOME_REALM_IDENTIFIER;
+import static org.wso2.carbon.identity.oauth.common.OAuthConstants.OIDCConfigProperties.DEFAULT_VALUE_FOR_PREVENT_TOKEN_REUSE;
+import static org.wso2.carbon.identity.oauth.common.OAuthConstants.OIDCConfigProperties.ENABLE_TOKEN_REUSE;
+import static org.wso2.carbon.identity.oauth.common.OAuthConstants.OIDCConfigProperties.JWT_CONFIGURATION_RESOURCE_NAME;
+import static org.wso2.carbon.identity.oauth.common.OAuthConstants.OIDCConfigProperties.JWT_CONFIGURATION_RESOURCE_TYPE_NAME;
+import static org.wso2.carbon.identity.oauth.common.OAuthConstants.OIDCConfigProperties.PREVENT_TOKEN_REUSE;
+import static org.wso2.carbon.identity.oauth.common.OAuthConstants.OIDCConfigProperties.PVT_KEY_JWT_CLIENT_AUTHENTICATOR_CLASS_NAME;
import static org.wso2.carbon.identity.oauth.common.OAuthConstants.TokenBindings.NONE;
import static org.wso2.carbon.identity.oauth.common.OAuthConstants.UserType.FEDERATED_USER_DOMAIN_PREFIX;
@@ -536,6 +548,7 @@ public static OAuthConsumerAppDTO buildConsumerAppDTO(OAuthAppDO appDO) {
.isTokenRevocationWithIDPSessionTerminationEnabled());
dto.setTokenBindingValidationEnabled(appDO.isTokenBindingValidationEnabled());
dto.setTokenEndpointAuthMethod(appDO.getTokenEndpointAuthMethod());
+ dto.setTokenEndpointAllowReusePvtKeyJwt(appDO.isTokenEndpointAllowReusePvtKeyJwt());
dto.setTokenEndpointAuthSignatureAlgorithm(appDO.getTokenEndpointAuthSignatureAlgorithm());
dto.setSectorIdentifierURI(appDO.getSectorIdentifierURI());
dto.setIdTokenSignatureAlgorithm(appDO.getIdTokenSignatureAlgorithm());
@@ -1197,4 +1210,73 @@ private static void setOrganizationSSOUserDetails(AuthenticatedUser authenticate
authenticatedUser.setFederatedIdPName(orgSsoIdp.getIdentityProviderName());
}
}
+
+ /**
+ * Get the value of the Tenant configuration of Reuse Private key JWT from the tenant configuration.
+ *
+ * @param tokenEPAllowReusePvtKeyJwtValue Value of the tokenEPAllowReusePvtKeyJwt configuration.
+ * @param tokenAuthMethod Token authentication method.
+ * @return Value of the tokenEPAllowReusePvtKeyJwt configuration.
+ * @throws IdentityOAuth2ServerException IdentityOAuth2ServerException exception.
+ */
+ public static String getValueOfTokenEPAllowReusePvtKeyJwt(String tokenEPAllowReusePvtKeyJwtValue,
+ String tokenAuthMethod)
+ throws IdentityOAuth2ServerException {
+
+ if (tokenEPAllowReusePvtKeyJwtValue == null && StringUtils.isNotBlank(tokenAuthMethod)
+ && OAuthConstants.PRIVATE_KEY_JWT.equals(tokenAuthMethod)) {
+ try {
+ tokenEPAllowReusePvtKeyJwtValue = readTenantConfigurationPvtKeyJWTReuse();
+ } catch (ConfigurationManagementException e) {
+ throw new IdentityOAuth2ServerException("Unable to retrieve JWT Authenticator tenant configuration.",
+ e);
+ }
+ if (tokenEPAllowReusePvtKeyJwtValue == null) {
+ tokenEPAllowReusePvtKeyJwtValue = readServerConfigurationPvtKeyJWTReuse();
+ if (tokenEPAllowReusePvtKeyJwtValue == null) {
+ tokenEPAllowReusePvtKeyJwtValue = String.valueOf(DEFAULT_VALUE_FOR_PREVENT_TOKEN_REUSE);
+ }
+ }
+ }
+ return tokenEPAllowReusePvtKeyJwtValue;
+ }
+
+ private static String readTenantConfigurationPvtKeyJWTReuse() throws ConfigurationManagementException {
+
+ String tokenEPAllowReusePvtKeyJwtTenantConfig = null;
+ Resource resource = OAuthComponentServiceHolder.getInstance().getConfigurationManager()
+ .getResource(JWT_CONFIGURATION_RESOURCE_TYPE_NAME, JWT_CONFIGURATION_RESOURCE_NAME);
+
+ if (resource != null) {
+ tokenEPAllowReusePvtKeyJwtTenantConfig = resource.getAttributes().stream()
+ .filter(attribute -> ENABLE_TOKEN_REUSE.equals(attribute.getKey()))
+ .map(Attribute::getValue)
+ .findFirst()
+ .orElse(null);
+ }
+ return tokenEPAllowReusePvtKeyJwtTenantConfig;
+ }
+
+ private static String readServerConfigurationPvtKeyJWTReuse() {
+
+ String tokenEPAllowReusePvtKeyJwtTenantConfig = null;
+ IdentityEventListenerConfig identityEventListenerConfig = IdentityUtil.readEventListenerProperty(
+ AbstractIdentityHandler.class.getName(), PVT_KEY_JWT_CLIENT_AUTHENTICATOR_CLASS_NAME);
+
+ if (identityEventListenerConfig != null
+ && Boolean.parseBoolean(identityEventListenerConfig.getEnable())) {
+ if (identityEventListenerConfig.getProperties() != null) {
+ for (Map.Entry