Skip to content

Commit

Permalink
Merge pull request #12485 from lasanthaS/id-token-fix
Browse files Browse the repository at this point in the history
Fix accessing API resources using id_token
  • Loading branch information
RakhithaRR authored Aug 16, 2024
2 parents 5e2ddd9 + 8983c67 commit d6841be
Show file tree
Hide file tree
Showing 7 changed files with 133 additions and 2 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -667,6 +667,7 @@ private AI() {
public static final String JWKS_URI = "jwksUri";

public static final String ORG_ALL_QUERY_PARAM = "ALL";
public static final String JWT_HEADER_ACCESS_TOKEN_TYPE = "at+jwt";

public static class TokenStatus {

Expand Down Expand Up @@ -3167,4 +3168,9 @@ public static class APILogHandler {

//Property for enabling tenant aware sub claims when invoking APIs with API key
public static final String ENABLE_TENANT_AWARE_SUB_CLAIM= "enable.tenant.aware.subclaim";

public static class TokenValidationConstants {
public static final String TOKEN_VALIDATION_CONFIG = "TokenValidation";
public static final String ENFORCE_JWT_TYPE_HEADER_VALIDATION = "EnforceTypeHeaderValidation";
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@
import org.wso2.carbon.apimgt.impl.dto.GatewayCleanupSkipList;
import org.wso2.carbon.apimgt.impl.dto.RedisConfig;
import org.wso2.carbon.apimgt.impl.dto.ThrottleProperties;
import org.wso2.carbon.apimgt.impl.dto.TokenValidationDto;
import org.wso2.carbon.apimgt.impl.dto.WorkflowProperties;
import org.wso2.carbon.apimgt.impl.monetization.MonetizationConfigurationDto;
import org.wso2.carbon.apimgt.impl.recommendationmgt.RecommendationEnvironment;
Expand Down Expand Up @@ -133,6 +134,7 @@ public class APIManagerConfiguration {
private Map<String, List<String>> restApiJWTAuthAudiences = new HashMap<>();
private JSONObject subscriberAttributes = new JSONObject();
private static Map<String, String> analyticsMaskProps;
private TokenValidationDto tokenValidationDto = new TokenValidationDto();

public Map<String, List<String>> getRestApiJWTAuthAudiences() {
return restApiJWTAuthAudiences;
Expand Down Expand Up @@ -656,6 +658,8 @@ private void readChildElements(OMElement serverConfig,
setMarketplaceAssistantConfiguration(element);
} else if (APIConstants.AI.API_CHAT.equals(localName)) {
setApiChatConfiguration(element);
} else if (APIConstants.TokenValidationConstants.TOKEN_VALIDATION_CONFIG.equals(localName)) {
setTokenValidation(element);
}
readChildElements(element, nameStack);
nameStack.pop();
Expand Down Expand Up @@ -694,6 +698,20 @@ private void setSubscriberAttributeConfigs(OMElement element) {
}
}

/**
* Set token validation configurations from the api-manager.xml file
*
* @param omElement OMElement of the TokenValidation configuration block
*/
private void setTokenValidation(OMElement omElement) {
OMElement enforceTypeHeaderValidation = omElement.getFirstChildWithName(new QName(
APIConstants.TokenValidationConstants.ENFORCE_JWT_TYPE_HEADER_VALIDATION));
if (enforceTypeHeaderValidation != null) {
tokenValidationDto.setEnforceTypeHeaderValidation(Boolean.parseBoolean(
enforceTypeHeaderValidation.getText()));
}
}

/**
* Set property values for each gateway environments defined in the api-manager.xml config file
*
Expand Down Expand Up @@ -2484,4 +2502,8 @@ public boolean isJWTClaimCacheEnabled() {
}
return false;
}

public TokenValidationDto getTokenValidationDto() {
return tokenValidationDto;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
import org.osgi.service.component.annotations.Component;
import org.wso2.carbon.apimgt.api.model.ConfigurationDto;
import org.wso2.carbon.apimgt.api.model.KeyManagerConnectorConfiguration;
import org.wso2.carbon.apimgt.impl.jwt.JWTValidatorImpl;
import org.wso2.carbon.apimgt.impl.jwt.TypeEnforcedJWTValidatorImpl;

import java.util.ArrayList;
import java.util.Collections;
Expand All @@ -46,7 +46,7 @@ public String getImplementation() {
@Override
public String getJWTValidator() {

return JWTValidatorImpl.class.getName();
return TypeEnforcedJWTValidatorImpl.class.getName();
}

@Override
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
/*
* Copyright (c) 2024, WSO2 LLC. (http://www.wso2.org) All Rights Reserved.
*
* WSO2 LLC. licenses this file to you under the Apache License,
* Version 2.0 (the "License"); you may not use this file except
* in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/

package org.wso2.carbon.apimgt.impl.dto;

import java.io.Serializable;

public class TokenValidationDto implements Serializable {
private boolean enforceTypeHeaderValidation = false;

public boolean isEnforceTypeHeaderValidation() {
return enforceTypeHeaderValidation;
}

public void setEnforceTypeHeaderValidation(boolean enforceTypeHeaderValidation) {
this.enforceTypeHeaderValidation = enforceTypeHeaderValidation;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
/*
* Copyright (c) 2024, WSO2 LLC. (http://www.wso2.org) All Rights Reserved.
*
* WSO2 LLC. licenses this file to you under the Apache License,
* Version 2.0 (the "License"); you may not use this file except
* in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/

package org.wso2.carbon.apimgt.impl.jwt;

import org.wso2.carbon.apimgt.api.APIManagementException;
import org.wso2.carbon.apimgt.common.gateway.dto.JWTValidationInfo;
import org.wso2.carbon.apimgt.impl.APIConstants;
import org.wso2.carbon.apimgt.impl.APIManagerConfiguration;
import org.wso2.carbon.apimgt.impl.internal.ServiceReferenceHolder;

public class TypeEnforcedJWTValidatorImpl extends JWTValidatorImpl {
@Override
public JWTValidationInfo validateToken(SignedJWTInfo signedJWTInfo) throws APIManagementException {
// If this is a refresh token, return an error
String tokenTypeClaim = (String) signedJWTInfo.getJwtClaimsSet().getClaim(
APIConstants.JwtTokenConstants.TOKEN_TYPE);
if (APIConstants.OAuthConstants.REFRESH_TOKEN.equals(tokenTypeClaim)) {
// Invalid type header
JWTValidationInfo jwtValidationInfo = new JWTValidationInfo();
jwtValidationInfo.setValid(false);
jwtValidationInfo.setValidationCode(APIConstants.KeyValidationStatus.API_AUTH_INVALID_CREDENTIALS);
return jwtValidationInfo;
}

APIManagerConfiguration apiManagerConfiguration = ServiceReferenceHolder.getInstance()
.getAPIManagerConfigurationService().getAPIManagerConfiguration();
if (apiManagerConfiguration.getTokenValidationDto().isEnforceTypeHeaderValidation()) {
// JWT type header validation is enforced via the configuration
if (signedJWTInfo.getSignedJWT().getHeader().getType() != null
&& APIConstants.JWT_HEADER_ACCESS_TOKEN_TYPE.equals(
signedJWTInfo.getSignedJWT().getHeader().getType().toString())) {
// The type header present with the value "at+jwt"
return super.validateToken(signedJWTInfo);
} else {
// Invalid type header
JWTValidationInfo jwtValidationInfo = new JWTValidationInfo();
jwtValidationInfo.setValid(false);
jwtValidationInfo.setValidationCode(APIConstants.KeyValidationStatus.API_AUTH_INVALID_CREDENTIALS);
return jwtValidationInfo;
}
}
return super.validateToken(signedJWTInfo);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -512,6 +512,11 @@
{% endif %}
</TokenRevocationNotifiers>

<TokenValidation>
<!-- Enforce validating JWT type header -->
<EnforceTypeHeaderValidation>{{apim.token.validation.enforce_type_header_validation}}</EnforceTypeHeaderValidation>
</TokenValidation>

<!-- Settings related to managing API access tiers. -->
<TierManagement>
<!-- Enable the providers to expose their APIs over the special 'Unlimited' tier which
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -284,6 +284,11 @@
</PersistentNotifier>
</TokenRevocationNotifiers>

<TokenValidation>
<!-- Enforce validating JWT type header -->
<EnforceTypeHeaderValidation>false</EnforceTypeHeaderValidation>
</TokenValidation>

<!-- Settings related to managing API access tiers. -->
<TierManagement>
<!-- Enable the providers to expose their APIs over the special 'Unlimited' tier which
Expand Down

0 comments on commit d6841be

Please sign in to comment.