Skip to content
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

Change default token type of portal apps to JWT. #12281

Merged
merged 8 commits into from
Feb 25, 2024
Original file line number Diff line number Diff line change
Expand Up @@ -8944,6 +8944,26 @@
return temp;
}

/**
* Helper method to retrieve default key manager configuration for the given organization.
*
* @param organization Organization
* @return KeyManagerConfigurationDTO
* @throws APIManagementException if an error occurs while retrieving latest default key manager configs
*/
public static KeyManagerConfigurationDTO getDefaultKeyManagerConfiguration(String organization) throws
APIManagementException {

KeyManagerConfigurationDTO keyManagerConfiguration =
ApiMgtDAO.getInstance().getKeyManagerConfigurationByName(organization,

Check warning on line 8958 in components/apimgt/org.wso2.carbon.apimgt.impl/src/main/java/org/wso2/carbon/apimgt/impl/utils/APIUtil.java

View check run for this annotation

Codecov / codecov/patch

components/apimgt/org.wso2.carbon.apimgt.impl/src/main/java/org/wso2/carbon/apimgt/impl/utils/APIUtil.java#L8958

Added line #L8958 was not covered by tests
APIConstants.KeyManager.DEFAULT_KEY_MANAGER);
if (keyManagerConfiguration != null) {
APIUtil.getAndSetDefaultKeyManagerConfiguration(keyManagerConfiguration);
return keyManagerConfiguration;

Check warning on line 8962 in components/apimgt/org.wso2.carbon.apimgt.impl/src/main/java/org/wso2/carbon/apimgt/impl/utils/APIUtil.java

View check run for this annotation

Codecov / codecov/patch

components/apimgt/org.wso2.carbon.apimgt.impl/src/main/java/org/wso2/carbon/apimgt/impl/utils/APIUtil.java#L8961-L8962

Added lines #L8961 - L8962 were not covered by tests
}
return null;

Check warning on line 8964 in components/apimgt/org.wso2.carbon.apimgt.impl/src/main/java/org/wso2/carbon/apimgt/impl/utils/APIUtil.java

View check run for this annotation

Codecov / codecov/patch

components/apimgt/org.wso2.carbon.apimgt.impl/src/main/java/org/wso2/carbon/apimgt/impl/utils/APIUtil.java#L8964

Added line #L8964 was not covered by tests
}

public static KeyManagerConfigurationDTO getAndSetDefaultKeyManagerConfiguration(
KeyManagerConfigurationDTO keyManagerConfigurationDTO) throws APIManagementException {

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -144,7 +144,7 @@
}
}

String tokenType = APIConstants.DEFAULT_TOKEN_TYPE;
String tokenType = APIConstants.JWT;

Check warning on line 147 in components/apimgt/org.wso2.carbon.apimgt.rest.api.dcr/src/main/java/org/wso2/carbon/apimgt/rest/api/dcr/web/impl/RegistrationServiceImpl.java

View check run for this annotation

Codecov / codecov/patch

components/apimgt/org.wso2.carbon.apimgt.rest.api.dcr/src/main/java/org/wso2/carbon/apimgt/rest/api/dcr/web/impl/RegistrationServiceImpl.java#L147

Added line #L147 was not covered by tests
String profileTokenType = profile.getTokenType();
if (StringUtils.isNotEmpty(profileTokenType)) {
tokenType = profileTokenType;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,12 +26,15 @@
import org.apache.cxf.message.Message;
import org.wso2.carbon.apimgt.api.APIManagementException;
import org.wso2.carbon.apimgt.api.OAuthTokenInfo;
import org.wso2.carbon.apimgt.api.dto.KeyManagerConfigurationDTO;
import org.wso2.carbon.apimgt.common.gateway.constants.JWTConstants;
import org.wso2.carbon.apimgt.common.gateway.dto.JWTValidationInfo;
import org.wso2.carbon.apimgt.common.gateway.dto.TokenIssuerDto;
import org.wso2.carbon.apimgt.impl.APIConstants;
import org.wso2.carbon.apimgt.impl.APIConstants.JwtTokenConstants;
import org.wso2.carbon.apimgt.impl.RESTAPICacheConfiguration;
import org.wso2.carbon.apimgt.impl.dto.KeyManagerDto;
import org.wso2.carbon.apimgt.impl.factory.KeyManagerHolder;
dushaniw marked this conversation as resolved.
Show resolved Hide resolved
import org.wso2.carbon.apimgt.impl.jwt.JWTValidator;
import org.wso2.carbon.apimgt.impl.jwt.SignedJWTInfo;
import org.wso2.carbon.apimgt.impl.utils.APIUtil;
Expand All @@ -52,12 +55,8 @@
import java.net.URL;
import java.text.ParseException;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import static org.wso2.carbon.apimgt.rest.api.common.APIMConfigUtil.getRestApiJWTAuthAudiences;

/**
* This OAuthJwtAuthenticatorImpl class specifically implemented for API Manager store and publisher rest APIs'
* JWT based authentication.
Expand Down Expand Up @@ -223,10 +222,11 @@

JWTValidationInfo jwtValidationInfo;
String issuer = signedJWTInfo.getJwtClaimsSet().getIssuer();
String subject = signedJWTInfo.getJwtClaimsSet().getSubject();

Check warning on line 225 in components/apimgt/org.wso2.carbon.apimgt.rest.api.util/src/main/java/org/wso2/carbon/apimgt/rest/api/util/impl/OAuthJwtAuthenticatorImpl.java

View check run for this annotation

Codecov / codecov/patch

components/apimgt/org.wso2.carbon.apimgt.rest.api.util/src/main/java/org/wso2/carbon/apimgt/rest/api/util/impl/OAuthJwtAuthenticatorImpl.java#L225

Added line #L225 was not covered by tests

if (StringUtils.isNotEmpty(issuer)) {
//validate Issuer
if (tokenIssuers != null && tokenIssuers.containsKey(issuer)) {
if (tokenIssuers != null && validateIssuer(subject, issuer, maskedToken)) {
if (isRESTApiTokenCacheEnabled) {
JWTValidationInfo tempJWTValidationInfo = (JWTValidationInfo) getRESTAPITokenCache().get(jti);
if (tempJWTValidationInfo != null) {
Expand Down Expand Up @@ -256,27 +256,38 @@
}
}
//info not in cache. validate signature and exp
JWTValidator jwtValidator = APIMConfigUtil.getJWTValidatorMap().get(issuer);
jwtValidationInfo = jwtValidator.validateToken(signedJWTInfo);
if (jwtValidationInfo.isValid()) {
//valid token
if (isRESTApiTokenCacheEnabled) {
getRESTAPITokenCache().put(jti, jwtValidationInfo);
JWTValidator jwtValidator = getJWTValidator(issuer, subject, maskedToken);

Check warning on line 259 in components/apimgt/org.wso2.carbon.apimgt.rest.api.util/src/main/java/org/wso2/carbon/apimgt/rest/api/util/impl/OAuthJwtAuthenticatorImpl.java

View check run for this annotation

Codecov / codecov/patch

components/apimgt/org.wso2.carbon.apimgt.rest.api.util/src/main/java/org/wso2/carbon/apimgt/rest/api/util/impl/OAuthJwtAuthenticatorImpl.java#L259

Added line #L259 was not covered by tests
if (jwtValidator != null) {
jwtValidationInfo = jwtValidator.validateToken(signedJWTInfo);

Check warning on line 261 in components/apimgt/org.wso2.carbon.apimgt.rest.api.util/src/main/java/org/wso2/carbon/apimgt/rest/api/util/impl/OAuthJwtAuthenticatorImpl.java

View check run for this annotation

Codecov / codecov/patch

components/apimgt/org.wso2.carbon.apimgt.rest.api.util/src/main/java/org/wso2/carbon/apimgt/rest/api/util/impl/OAuthJwtAuthenticatorImpl.java#L261

Added line #L261 was not covered by tests
if (jwtValidationInfo.isValid()) {
//valid token
if (isRESTApiTokenCacheEnabled) {
getRESTAPITokenCache().put(jti, jwtValidationInfo);

Check warning on line 265 in components/apimgt/org.wso2.carbon.apimgt.rest.api.util/src/main/java/org/wso2/carbon/apimgt/rest/api/util/impl/OAuthJwtAuthenticatorImpl.java

View check run for this annotation

Codecov / codecov/patch

components/apimgt/org.wso2.carbon.apimgt.rest.api.util/src/main/java/org/wso2/carbon/apimgt/rest/api/util/impl/OAuthJwtAuthenticatorImpl.java#L265

Added line #L265 was not covered by tests
}
} else {
//put in invalid cache
if (isRESTApiTokenCacheEnabled) {
getRESTAPIInvalidTokenCache().put(jti, jwtValidationInfo);

Check warning on line 270 in components/apimgt/org.wso2.carbon.apimgt.rest.api.util/src/main/java/org/wso2/carbon/apimgt/rest/api/util/impl/OAuthJwtAuthenticatorImpl.java

View check run for this annotation

Codecov / codecov/patch

components/apimgt/org.wso2.carbon.apimgt.rest.api.util/src/main/java/org/wso2/carbon/apimgt/rest/api/util/impl/OAuthJwtAuthenticatorImpl.java#L270

Added line #L270 was not covered by tests
}
//invalid credentials : 900901 error code
log.error("JWT token validation failed. Reason: Invalid Credentials. " +

Check warning on line 273 in components/apimgt/org.wso2.carbon.apimgt.rest.api.util/src/main/java/org/wso2/carbon/apimgt/rest/api/util/impl/OAuthJwtAuthenticatorImpl.java

View check run for this annotation

Codecov / codecov/patch

components/apimgt/org.wso2.carbon.apimgt.rest.api.util/src/main/java/org/wso2/carbon/apimgt/rest/api/util/impl/OAuthJwtAuthenticatorImpl.java#L273

Added line #L273 was not covered by tests
"Make sure you have provided the correct security credentials in the token :"
+ maskedToken);
}
} else {
//put in invalid cache
if (isRESTApiTokenCacheEnabled) {
getRESTAPIInvalidTokenCache().put(jti, jwtValidationInfo);
}
//invalid credentials : 900901 error code
log.error("JWT token validation failed. Reason: Invalid Credentials. " +
"Make sure you have provided the correct security credentials in the token :"
+ maskedToken);
log.error("JWT token issuer validation failed. Reason: Cannot find a JWTValidator for the " +

Check warning on line 278 in components/apimgt/org.wso2.carbon.apimgt.rest.api.util/src/main/java/org/wso2/carbon/apimgt/rest/api/util/impl/OAuthJwtAuthenticatorImpl.java

View check run for this annotation

Codecov / codecov/patch

components/apimgt/org.wso2.carbon.apimgt.rest.api.util/src/main/java/org/wso2/carbon/apimgt/rest/api/util/impl/OAuthJwtAuthenticatorImpl.java#L278

Added line #L278 was not covered by tests
"issuer present in the JWT: " + issuer);
return null;

Check warning on line 280 in components/apimgt/org.wso2.carbon.apimgt.rest.api.util/src/main/java/org/wso2/carbon/apimgt/rest/api/util/impl/OAuthJwtAuthenticatorImpl.java

View check run for this annotation

Codecov / codecov/patch

components/apimgt/org.wso2.carbon.apimgt.rest.api.util/src/main/java/org/wso2/carbon/apimgt/rest/api/util/impl/OAuthJwtAuthenticatorImpl.java#L280

Added line #L280 was not covered by tests
}
} else {
//invalid issuer. invalid token
log.error("JWT token issuer validation failed. Reason: Issuer present in the JWT (" + issuer
+ ") does not match with the token issuer (" + tokenIssuers.keySet().toString() + ")");
if (tokenIssuers != null) {
log.error("JWT token issuer validation failed. Reason: Issuer present in the JWT (" + issuer
+ ") does not match with the token issuer (" + tokenIssuers.keySet() + ")");

Check warning on line 286 in components/apimgt/org.wso2.carbon.apimgt.rest.api.util/src/main/java/org/wso2/carbon/apimgt/rest/api/util/impl/OAuthJwtAuthenticatorImpl.java

View check run for this annotation

Codecov / codecov/patch

components/apimgt/org.wso2.carbon.apimgt.rest.api.util/src/main/java/org/wso2/carbon/apimgt/rest/api/util/impl/OAuthJwtAuthenticatorImpl.java#L285-L286

Added lines #L285 - L286 were not covered by tests
} else {
log.error("JWT token issuer validation failed. Reason: Issuer present in the JWT (" + issuer

Check warning on line 288 in components/apimgt/org.wso2.carbon.apimgt.rest.api.util/src/main/java/org/wso2/carbon/apimgt/rest/api/util/impl/OAuthJwtAuthenticatorImpl.java

View check run for this annotation

Codecov / codecov/patch

components/apimgt/org.wso2.carbon.apimgt.rest.api.util/src/main/java/org/wso2/carbon/apimgt/rest/api/util/impl/OAuthJwtAuthenticatorImpl.java#L288

Added line #L288 was not covered by tests
+ ") does not match with the token issuer.");
}
return null;
}
} else {
Expand All @@ -286,6 +297,72 @@
return jwtValidationInfo;
}

/**
* Get logged-in organization from the sub claim of the token.
*
* @param subject Sub claim value
* @param maskedToken Masked token for logging
* @return Organization
*/
private String getOrganizationFromSubject(String subject, String maskedToken) {
if (subject == null) {
log.error("Subject is not found in the token " + maskedToken);
return null;

Check warning on line 310 in components/apimgt/org.wso2.carbon.apimgt.rest.api.util/src/main/java/org/wso2/carbon/apimgt/rest/api/util/impl/OAuthJwtAuthenticatorImpl.java

View check run for this annotation

Codecov / codecov/patch

components/apimgt/org.wso2.carbon.apimgt.rest.api.util/src/main/java/org/wso2/carbon/apimgt/rest/api/util/impl/OAuthJwtAuthenticatorImpl.java#L309-L310

Added lines #L309 - L310 were not covered by tests
}
return MultitenantUtils.getTenantDomain(subject);

Check warning on line 312 in components/apimgt/org.wso2.carbon.apimgt.rest.api.util/src/main/java/org/wso2/carbon/apimgt/rest/api/util/impl/OAuthJwtAuthenticatorImpl.java

View check run for this annotation

Codecov / codecov/patch

components/apimgt/org.wso2.carbon.apimgt.rest.api.util/src/main/java/org/wso2/carbon/apimgt/rest/api/util/impl/OAuthJwtAuthenticatorImpl.java#L312

Added line #L312 was not covered by tests
}

/**
* Retrieve JWT Validator for the given issuer.
*
* @param issuer Issuer from the token
* @param subject Subject from the token
* @param maskedToken Masked token string for logging
* @return JWTValidator implementation for the given issuer.
*/
private JWTValidator getJWTValidator(String issuer, String subject, String maskedToken) {

JWTValidator jwtValidator = APIMConfigUtil.getJWTValidatorMap().get(issuer);

Check warning on line 325 in components/apimgt/org.wso2.carbon.apimgt.rest.api.util/src/main/java/org/wso2/carbon/apimgt/rest/api/util/impl/OAuthJwtAuthenticatorImpl.java

View check run for this annotation

Codecov / codecov/patch

components/apimgt/org.wso2.carbon.apimgt.rest.api.util/src/main/java/org/wso2/carbon/apimgt/rest/api/util/impl/OAuthJwtAuthenticatorImpl.java#L325

Added line #L325 was not covered by tests
if (jwtValidator == null) {
String organization = getOrganizationFromSubject(subject, maskedToken);

Check warning on line 327 in components/apimgt/org.wso2.carbon.apimgt.rest.api.util/src/main/java/org/wso2/carbon/apimgt/rest/api/util/impl/OAuthJwtAuthenticatorImpl.java

View check run for this annotation

Codecov / codecov/patch

components/apimgt/org.wso2.carbon.apimgt.rest.api.util/src/main/java/org/wso2/carbon/apimgt/rest/api/util/impl/OAuthJwtAuthenticatorImpl.java#L327

Added line #L327 was not covered by tests
if (StringUtils.isNotEmpty(issuer) && StringUtils.isNotEmpty(organization)) {
KeyManagerDto keyManagerDto = KeyManagerHolder.getKeyManagerByIssuer(organization, issuer);

Check warning on line 329 in components/apimgt/org.wso2.carbon.apimgt.rest.api.util/src/main/java/org/wso2/carbon/apimgt/rest/api/util/impl/OAuthJwtAuthenticatorImpl.java

View check run for this annotation

Codecov / codecov/patch

components/apimgt/org.wso2.carbon.apimgt.rest.api.util/src/main/java/org/wso2/carbon/apimgt/rest/api/util/impl/OAuthJwtAuthenticatorImpl.java#L329

Added line #L329 was not covered by tests
if (keyManagerDto != null && keyManagerDto.getJwtValidator() != null) {
jwtValidator = keyManagerDto.getJwtValidator();

Check warning on line 331 in components/apimgt/org.wso2.carbon.apimgt.rest.api.util/src/main/java/org/wso2/carbon/apimgt/rest/api/util/impl/OAuthJwtAuthenticatorImpl.java

View check run for this annotation

Codecov / codecov/patch

components/apimgt/org.wso2.carbon.apimgt.rest.api.util/src/main/java/org/wso2/carbon/apimgt/rest/api/util/impl/OAuthJwtAuthenticatorImpl.java#L331

Added line #L331 was not covered by tests
}
}
}
return jwtValidator;

Check warning on line 335 in components/apimgt/org.wso2.carbon.apimgt.rest.api.util/src/main/java/org/wso2/carbon/apimgt/rest/api/util/impl/OAuthJwtAuthenticatorImpl.java

View check run for this annotation

Codecov / codecov/patch

components/apimgt/org.wso2.carbon.apimgt.rest.api.util/src/main/java/org/wso2/carbon/apimgt/rest/api/util/impl/OAuthJwtAuthenticatorImpl.java#L335

Added line #L335 was not covered by tests
}

/**
* Validate issuer in the token against the registered token issuers/default key manager issuer.
*
* @param subject Subject to derive the logged-in organization
* @param tokenIssuer Token issuer from the token
* @param maskedToken Masked token for logging purposes
* @return if issuer validation fails or sucess
* @throws APIManagementException if an error occurs during validation
*/
private boolean validateIssuer(String subject, String tokenIssuer, String maskedToken)
throws APIManagementException {

String organization = getOrganizationFromSubject(subject, maskedToken);

Check warning on line 350 in components/apimgt/org.wso2.carbon.apimgt.rest.api.util/src/main/java/org/wso2/carbon/apimgt/rest/api/util/impl/OAuthJwtAuthenticatorImpl.java

View check run for this annotation

Codecov / codecov/patch

components/apimgt/org.wso2.carbon.apimgt.rest.api.util/src/main/java/org/wso2/carbon/apimgt/rest/api/util/impl/OAuthJwtAuthenticatorImpl.java#L350

Added line #L350 was not covered by tests
if (tokenIssuers != null && !tokenIssuers.isEmpty()) {
return tokenIssuers.containsKey(tokenIssuer);

Check warning on line 352 in components/apimgt/org.wso2.carbon.apimgt.rest.api.util/src/main/java/org/wso2/carbon/apimgt/rest/api/util/impl/OAuthJwtAuthenticatorImpl.java

View check run for this annotation

Codecov / codecov/patch

components/apimgt/org.wso2.carbon.apimgt.rest.api.util/src/main/java/org/wso2/carbon/apimgt/rest/api/util/impl/OAuthJwtAuthenticatorImpl.java#L352

Added line #L352 was not covered by tests
}
KeyManagerConfigurationDTO keyManagerConfigurationDTO =
APIUtil.getDefaultKeyManagerConfiguration(organization);

Check warning on line 355 in components/apimgt/org.wso2.carbon.apimgt.rest.api.util/src/main/java/org/wso2/carbon/apimgt/rest/api/util/impl/OAuthJwtAuthenticatorImpl.java

View check run for this annotation

Codecov / codecov/patch

components/apimgt/org.wso2.carbon.apimgt.rest.api.util/src/main/java/org/wso2/carbon/apimgt/rest/api/util/impl/OAuthJwtAuthenticatorImpl.java#L354-L355

Added lines #L354 - L355 were not covered by tests
if (keyManagerConfigurationDTO == null) {
//invalid issuer. invalid token
log.error("JWT token issuer validation failed. Reason: Default Key Manager configuration cannot be"

Check warning on line 358 in components/apimgt/org.wso2.carbon.apimgt.rest.api.util/src/main/java/org/wso2/carbon/apimgt/rest/api/util/impl/OAuthJwtAuthenticatorImpl.java

View check run for this annotation

Codecov / codecov/patch

components/apimgt/org.wso2.carbon.apimgt.rest.api.util/src/main/java/org/wso2/carbon/apimgt/rest/api/util/impl/OAuthJwtAuthenticatorImpl.java#L358

Added line #L358 was not covered by tests
+ " found for the organization: " + organization);
return false;

Check warning on line 360 in components/apimgt/org.wso2.carbon.apimgt.rest.api.util/src/main/java/org/wso2/carbon/apimgt/rest/api/util/impl/OAuthJwtAuthenticatorImpl.java

View check run for this annotation

Codecov / codecov/patch

components/apimgt/org.wso2.carbon.apimgt.rest.api.util/src/main/java/org/wso2/carbon/apimgt/rest/api/util/impl/OAuthJwtAuthenticatorImpl.java#L360

Added line #L360 was not covered by tests
}
return StringUtils.equals(tokenIssuer, (String) keyManagerConfigurationDTO.getAdditionalProperties()
.get(APIConstants.KeyManager.ISSUER));

Check warning on line 363 in components/apimgt/org.wso2.carbon.apimgt.rest.api.util/src/main/java/org/wso2/carbon/apimgt/rest/api/util/impl/OAuthJwtAuthenticatorImpl.java

View check run for this annotation

Codecov / codecov/patch

components/apimgt/org.wso2.carbon.apimgt.rest.api.util/src/main/java/org/wso2/carbon/apimgt/rest/api/util/impl/OAuthJwtAuthenticatorImpl.java#L362-L363

Added lines #L362 - L363 were not covered by tests
}

/**
* Retrieve token issuer details from deployment.toml file.
*
Expand Down
Loading