Skip to content

Introduce a config to continue backend JWT generation on user claim retrieval failure #13051

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

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
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
Original file line number Diff line number Diff line change
Expand Up @@ -427,7 +427,7 @@ private String generateAndRetrieveJWTToken(String tokenSignature, JWTInfoDto jwt
return endUserToken;
}

private void includeUserStoreClaimsIntoClaims(JWTInfoDto jwtInfoDto) {
private void includeUserStoreClaimsIntoClaims(JWTInfoDto jwtInfoDto) throws JWTGeneratorException {

JWTInfoDto localJWTInfoDto = new JWTInfoDto(jwtInfoDto);
Map<String, String> userClaimsFromKeyManager = getUserClaimsFromKeyManager(localJWTInfoDto);
Expand Down Expand Up @@ -859,7 +859,7 @@ protected Cache getGatewayJWTTokenCache() {

return CacheProvider.getGatewayJWTTokenCache();
}
private Map<String, String> getUserClaimsFromKeyManager(JWTInfoDto jwtInfoDto) {
private Map<String, String> getUserClaimsFromKeyManager(JWTInfoDto jwtInfoDto) throws JWTGeneratorException {

if (jwtConfigurationDto.isEnableUserClaimRetrievalFromUserStore()) {
String tenantDomain = CarbonContext.getThreadLocalCarbonContext().getTenantDomain();
Expand All @@ -881,7 +881,11 @@ private Map<String, String> getUserClaimsFromKeyManager(JWTInfoDto jwtInfoDto) {
try {
return keyManagerInstance.getUserClaims(jwtInfoDto.getEndUser(), properties);
} catch (APIManagementException e) {
log.error("Error while retrieving User claims from Key Manager ", e);
if (jwtConfigurationDto.isContinueOnClaimRetrievalFailure()) {
log.error("Error while retrieving User Claims from Key Manager ", e);
} else {
throw new JWTGeneratorException("Error while retrieving User Claims from Key Manager", e);
}
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ public APIKeyValidationInfoDTO getAPIKeyData(String context, String apiVersion,
} catch (APIKeyMgtException | APIManagementException e) {
log.error("Error while retrieving data from datastore", e);
throw new APISecurityException(APISecurityConstants.API_AUTH_GENERAL_ERROR,
"Error while retrieving data from datastore", e);
e.getMessage(), e);
}

}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
import org.wso2.carbon.apimgt.gateway.MethodStats;
import org.wso2.carbon.apimgt.gateway.handlers.security.APISecurityConstants;
import org.wso2.carbon.apimgt.gateway.handlers.security.APISecurityException;
import org.wso2.carbon.apimgt.impl.APIConstants;
import org.wso2.carbon.apimgt.impl.dto.APIKeyValidationInfoDTO;
import org.wso2.carbon.apimgt.keymgt.model.entity.Scope;
import org.wso2.carbon.apimgt.keymgt.service.TokenValidationContext;
Expand Down Expand Up @@ -53,6 +54,10 @@ public APIKeyValidationInfoDTO getAPIKeyData(String context, String apiVersion,
return client.getAPIKeyData(context, apiVersion, apiKey, requiredAuthenticationLevel,
matchingResource, httpVerb, tenantDomain, keyManagers);
} catch (APISecurityException ex) {
if (ex.getMessage().equalsIgnoreCase(APIConstants.JWT_GENERATION_ERROR)) {
throw new APISecurityException(ex.getErrorCode(),
APISecurityConstants.API_AUTH_GENERAL_ERROR_MESSAGE, ex);
}
throw new APISecurityException(ex.getErrorCode(),
"Resource forbidden", ex);
} catch (Exception e) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -676,6 +676,7 @@ private AI() {
public static final String VALUE = "value";
public static final String GATEWAY_INTROSPECT_CACHE_NAME = "GatewayIntrospectCache";
public static final String ENABLE_USER_CLAIMS_RETRIEVAL_FROM_KEY_MANAGER = "EnableUserClaimRetrievalFromKeyManager";
public static final String CONTINUE_ON_CLAIM_RETRIEVAL_FAILURE = "ContinueOnClaimRetrievalFailure";

public static final String DELEM_COLON = ":";
public static final String DELEM_COMMA = ",";
Expand Down Expand Up @@ -1912,6 +1913,8 @@ public enum RegistryResourceTypesForUI {
public static final String MSG_TIER_RET_ERROR = "Error while retrieving API tiers from registry";
public static final String MSG_MALFORMED_XML_ERROR = "Malformed XML found in the API tier policy resource";

public static final String JWT_GENERATION_ERROR = "Error occurred while generating JWT";

//Doc search related constants

public static final String PUBLISHER_CLIENT = "Publisher";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1845,6 +1845,12 @@ private void setJWTConfiguration(OMElement omElement) {
}
}
}
OMElement continueOnCustomClaimRetrievalFailureElement =
omElement.getFirstChildWithName(new QName(APIConstants.CONTINUE_ON_CLAIM_RETRIEVAL_FAILURE));
if (continueOnCustomClaimRetrievalFailureElement != null) {
jwtConfigurationDto.setContinueOnClaimRetrievalFailure(
Boolean.parseBoolean(continueOnCustomClaimRetrievalFailureElement.getText()));
}
OMElement enableBase64PaddingElement = gatewayJWTConfigurationElement.getFirstChildWithName(
new QName(APIConstants.ENABLE_BASE64_PADDING));
if (enableBase64PaddingElement != null) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ public class ExtendedJWTConfigurationDto extends JWTConfigurationDto {
private String jwtGeneratorImplClass = "org.wso2.carbon.apimgt.keymgt.token.JWTGenerator";
private String claimRetrieverImplClass;
private boolean tenantBasedSigningEnabled;
private boolean continueOnClaimRetrievalFailure;
private boolean enableUserClaimRetrievalFromUserStore;
private boolean isBindFederatedUserClaims;
private boolean isJWKSApiEnabled;
Expand Down Expand Up @@ -50,6 +51,14 @@ public boolean isEnableUserClaimRetrievalFromUserStore() {
return enableUserClaimRetrievalFromUserStore;
}

public boolean isContinueOnClaimRetrievalFailure() {
return continueOnClaimRetrievalFailure;
}

public void setContinueOnClaimRetrievalFailure(boolean continueOnClaimRetrievalFailure) {
this.continueOnClaimRetrievalFailure = continueOnClaimRetrievalFailure;
}

public boolean isBindFederatedUserClaims() {

return isBindFederatedUserClaims;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -133,17 +133,19 @@ protected boolean hasTokenRequiredAuthLevel(String authScheme,
@Override
public boolean generateConsumerToken(TokenValidationContext validationContext) throws APIKeyMgtException {


String jwt = null;
try {
String jwt = getCachedJWTToken(validationContext);
validationContext.getValidationInfoDTO().setEndUserToken(jwt);
return true;

jwt = getCachedJWTToken(validationContext);
} catch (APIManagementException e) {
log.error("Error occurred while generating JWT. ", e);
if (!(ServiceReferenceHolder.getInstance().getAPIManagerConfigurationService().getAPIManagerConfiguration()
.getJwtConfigurationDto().isContinueOnClaimRetrievalFailure())) {
throw new APIKeyMgtException(APIConstants.JWT_GENERATION_ERROR, e);
} else {
log.error("Error occurred while generating JWT. ", e);
}
}

return false;
validationContext.getValidationInfoDTO().setEndUserToken(jwt);
return true;
}

private String getCachedJWTToken(TokenValidationContext validationContext) throws APIManagementException {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
"apim.jwt.encode_x5t_without_padding": false,
"apim.jwt.enable_tenant_based_signing": false,
"apim.jwt.gateway_generator.enable_claim_retrieval": false,
"apim.jwt.continue_on_claim_retrieval_failure": true,
"apim.jwt.binding_federated_user_claims": false,
"apim.hashing.hashing_algorithm": "SHA-256",
"apim.cache.gateway_token.enable": true,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,8 @@
<!-- This parameter specifies which implementation should be used for generating the Token. For URL safe JWT
Token generation the implementation is provided in URLSafeJWTGenerator -->
<!--<JWTGeneratorImpl>org.wso2.carbon.apimgt.keymgt.token.URLSafeJWTGenerator</JWTGeneratorImpl>-->
<ContinueOnClaimRetrievalFailure>{{apim.jwt.continue_on_claim_retrieval_failure}}</ContinueOnClaimRetrievalFailure>

{% if apim.jwt.enable_tenant_based_signing is defined %}
<EnableTenantBasedSigning>{{apim.jwt.enable_tenant_based_signing}}</EnableTenantBasedSigning>
{% endif %}
Expand Down
Loading