OAuthCertBoundJwtAccessTokenAuthority implements Authority, AuthorityKeyStore, KeyStore { @Override public void initialize() { String authnChallengeRealm = OAuthAuthorityUtils.getProperty(OAuthAuthorityConsts.JA_PROP_AUTHN_CHALLENGE_REALM, "https: this.authenticateChallenge = String.format("Bearer realm=\"%s\"", authnChallengeRealm); boolean excludeRoleCertificates = Boolean.valueOf(OAuthAuthorityUtils.getProperty(OAuthAuthorityConsts.JA_PROP_CERT_EXCLUDE_ROLE_CERTIFICATES, "false")); Set<String> excludedPrincipals = OAuthAuthorityUtils.csvToSet(OAuthAuthorityUtils.getProperty(OAuthAuthorityConsts.JA_PROP_CERT_EXCLUDED_PRINCIPALS, ""), OAuthAuthorityConsts.CSV_DELIMITER); this.certificateIdentityParser = new CertificateIdentityParser(excludedPrincipals, excludeRoleCertificates); String jwtParserFactoryClass = OAuthAuthorityUtils.getProperty(OAuthAuthorityConsts.JA_PROP_PARSER_FACTORY_CLASS, "com.yahoo.athenz.auth.oauth.parser.DefaultOAuthJwtAccessTokenParserFactory"); try { OAuthJwtAccessTokenParserFactory jwtParserFactory = (OAuthJwtAccessTokenParserFactory) Class.forName(jwtParserFactoryClass).newInstance(); this.parser = jwtParserFactory.create(this); } catch (InstantiationException | IllegalAccessException | ClassNotFoundException e) { LOG.error("Invalid OAuthJwtAccessTokenParserFactory class: " + jwtParserFactoryClass + " error: " + e.getMessage()); throw new IllegalArgumentException("Invalid JWT parser class", e); } this.shouldVerifyCertThumbprint = Boolean.valueOf(OAuthAuthorityUtils.getProperty(OAuthAuthorityConsts.JA_PROP_VERIFY_CERT_THUMBPRINT, "true")); String authorizedClientIdsPath = OAuthAuthorityUtils.getProperty(OAuthAuthorityConsts.JA_PROP_AUTHORIZED_CLIENT_IDS_PATH, ""); Map<String, Set<String>> authorizedClientIds = new HashMap<>(); Map<String, String> authorizedServices = new HashMap<>(); this.processAuthorizedClientIds(authorizedClientIdsPath, authorizedClientIds, authorizedServices); this.authorizedServices = authorizedServices; String trustedIssuer = OAuthAuthorityUtils.getProperty(OAuthAuthorityConsts.JA_PROP_CLAIM_ISS, "https: Set<String> requiredAudiences = OAuthAuthorityUtils.csvToSet(OAuthAuthorityUtils.getProperty(OAuthAuthorityConsts.JA_PROP_CLAIM_AUD, "https: Set<String> requiredScopes = OAuthAuthorityUtils.csvToSet(OAuthAuthorityUtils.getProperty(OAuthAuthorityConsts.JA_PROP_CLAIM_SCOPE, "sys.auth:role.admin"), OAuthJwtAccessToken.SCOPE_DELIMITER); this.validator = new DefaultOAuthJwtAccessTokenValidator(trustedIssuer, requiredAudiences, requiredScopes, authorizedClientIds); }  @Override void setKeyStore(KeyStore keyStore); @Override String getPublicKey(String domain, String service, String keyId); @Override CredSource getCredSource(); @Override String getAuthenticateChallenge(); @Override String getDomain(); @Override String getHeader(); @Override Principal authenticate(String credentials, String remoteAddr, String httpMethod, StringBuilder errMsg); @Override void initialize(); @Override Principal authenticate(HttpServletRequest request, StringBuilder errMsg);  }
@Test public void testInitialize() throws Exception { OAuthCertBoundJwtAccessTokenAuthority authority = new OAuthCertBoundJwtAccessTokenAuthority(); Field authenticateChallengeField = authority.getClass().getDeclaredField("authenticateChallenge"); authenticateChallengeField.setAccessible(true); System.setProperty("athenz.auth.oauth.jwt.authn_challenge_realm", "https: authority.initialize(); System.clearProperty("athenz.auth.oauth.jwt.authn_challenge_realm"); assertEquals(authenticateChallengeField.get(authority), "Bearer realm=\"https: System.clearProperty("athenz.auth.oauth.jwt.authn_challenge_realm"); authority.initialize(); assertEquals(authenticateChallengeField.get(authority), "Bearer realm=\"https: CertificateIdentityParser certParser = null; Field excludeRoleCertificatesField = null, excludedPrincipalsField = null; Field certificateIdentityParserField = authority.getClass().getDeclaredField("certificateIdentityParser"); certificateIdentityParserField.setAccessible(true); System.setProperty("athenz.auth.oauth.jwt.cert.exclude_role_certificates", "true"); System.setProperty("athenz.auth.oauth.jwt.cert.excluded_principals", "principals_1,principals_2"); authority.initialize(); System.clearProperty("athenz.auth.oauth.jwt.cert.exclude_role_certificates"); System.clearProperty("athenz.auth.oauth.jwt.cert.excluded_principals"); certParser = (CertificateIdentityParser) certificateIdentityParserField.get(authority); excludeRoleCertificatesField = certParser.getClass().getDeclaredField("excludeRoleCertificates"); excludedPrincipalsField = certParser.getClass().getDeclaredField("excludedPrincipalSet"); excludeRoleCertificatesField.setAccessible(true); excludedPrincipalsField.setAccessible(true); assertEquals(excludeRoleCertificatesField.get(certParser), true); assertEquals(excludedPrincipalsField.get(certParser), new HashSet<>(Arrays.asList(new String[]{ "principals_1", "principals_2" }))); System.clearProperty("athenz.auth.oauth.jwt.cert.exclude_role_certificates"); System.clearProperty("athenz.auth.oauth.jwt.cert.excluded_principals"); authority.initialize(); certParser = (CertificateIdentityParser) certificateIdentityParserField.get(authority); excludeRoleCertificatesField = certParser.getClass().getDeclaredField("excludeRoleCertificates"); excludedPrincipalsField = certParser.getClass().getDeclaredField("excludedPrincipalSet"); excludeRoleCertificatesField.setAccessible(true); excludedPrincipalsField.setAccessible(true); assertEquals(excludeRoleCertificatesField.get(certParser), false); assertEquals(excludedPrincipalsField.get(certParser), (Set<String>) null); Field parserField = authority.getClass().getDeclaredField("parser"); parserField.setAccessible(true); System.setProperty("athenz.auth.oauth.jwt.parser_factory_class", "invalid_class"); assertThrows(IllegalArgumentException.class, () -> authority.initialize()); System.clearProperty("athenz.auth.oauth.jwt.parser_factory_class"); System.setProperty("athenz.auth.oauth.jwt.parser_factory_class", OAuthCertBoundJwtAccessTokenAuthorityTestParserFactory.class.getName()); authority.initialize(); System.clearProperty("athenz.auth.oauth.jwt.parser_factory_class"); assertTrue(parserField.get(authority) instanceof OAuthCertBoundJwtAccessTokenAuthorityTestParser); System.clearProperty("athenz.auth.oauth.jwt.parser_factory_class"); authority.initialize(); assertTrue(parserField.get(authority) instanceof DefaultOAuthJwtAccessTokenParser); Field shouldVerifyCertThumbprintField = authority.getClass().getDeclaredField("shouldVerifyCertThumbprint"); shouldVerifyCertThumbprintField.setAccessible(true); System.clearProperty("athenz.auth.oauth.jwt.verify_cert_thumbprint"); authority.initialize(); assertEquals(shouldVerifyCertThumbprintField.get(authority), true); System.setProperty("athenz.auth.oauth.jwt.verify_cert_thumbprint", "false"); authority.initialize(); System.clearProperty("athenz.auth.oauth.jwt.verify_cert_thumbprint"); assertEquals(shouldVerifyCertThumbprintField.get(authority), false); DefaultOAuthJwtAccessTokenValidator validator = null; Field trustedIssuerField = null, requiredAudiencesField = null, requiredScopesField = null, authorizedClientIdsField = null; Field authorizedServicesField = authority.getClass().getDeclaredField("authorizedServices"); authorizedServicesField.setAccessible(true); Field validatorField = authority.getClass().getDeclaredField("validator"); validatorField.setAccessible(true); System.setProperty("athenz.auth.oauth.jwt.authorized_client_ids_path", ""); System.setProperty("athenz.auth.oauth.jwt.claim.iss", ""); System.setProperty("athenz.auth.oauth.jwt.claim.aud", ""); System.setProperty("athenz.auth.oauth.jwt.claim.scope", ""); assertThrows(IllegalArgumentException.class, () -> authority.initialize()); System.clearProperty("athenz.auth.oauth.jwt.authorized_client_ids_path"); System.clearProperty("athenz.auth.oauth.jwt.claim.iss"); System.clearProperty("athenz.auth.oauth.jwt.claim.aud"); System.clearProperty("athenz.auth.oauth.jwt.claim.scope"); Map<String, String> expectedAuthorizedServices = new HashMap<>(); Map<String, Set<String>> expectedAuthorizedClientIds = new HashMap<>(); expectedAuthorizedServices.put("ui.athenz.io", "sys.auth.ui"); expectedAuthorizedClientIds.put("ui.athenz.io", new HashSet<>(Arrays.asList(new String[]{"client_id_1","client_id_2","ui.athenz.io"}))); System.setProperty("athenz.auth.oauth.jwt.authorized_client_ids_path", this.classLoader.getResource("authorized_client_ids.single.txt").getPath()); System.setProperty("athenz.auth.oauth.jwt.claim.iss", "iss"); System.setProperty("athenz.auth.oauth.jwt.claim.aud", "aud_1,aud_2"); System.setProperty("athenz.auth.oauth.jwt.claim.scope", "scope_1 scope_2"); authority.initialize(); System.clearProperty("athenz.auth.oauth.jwt.authorized_client_ids_path"); System.clearProperty("athenz.auth.oauth.jwt.claim.iss"); System.clearProperty("athenz.auth.oauth.jwt.claim.aud"); System.clearProperty("athenz.auth.oauth.jwt.claim.scope"); assertEquals(authorizedServicesField.get(authority), expectedAuthorizedServices); validator = (DefaultOAuthJwtAccessTokenValidator) validatorField.get(authority); trustedIssuerField = validator.getClass().getDeclaredField("trustedIssuer"); requiredAudiencesField = validator.getClass().getDeclaredField("requiredAudiences"); requiredScopesField = validator.getClass().getDeclaredField("requiredScopes"); authorizedClientIdsField = validator.getClass().getDeclaredField("authorizedClientIds"); trustedIssuerField.setAccessible(true); requiredAudiencesField.setAccessible(true); requiredScopesField.setAccessible(true); authorizedClientIdsField.setAccessible(true); assertEquals(trustedIssuerField.get(validator), "iss"); assertEquals(requiredAudiencesField.get(validator), new HashSet<>(Arrays.asList(new String[]{"aud_1", "aud_2"}))); assertEquals(requiredScopesField.get(validator), new HashSet<>(Arrays.asList(new String[]{"scope_1", "scope_2"}))); assertEquals(authorizedClientIdsField.get(validator), expectedAuthorizedClientIds); System.clearProperty("athenz.auth.oauth.jwt.authorized_client_ids_path"); System.clearProperty("athenz.auth.oauth.jwt.claim.iss"); System.clearProperty("athenz.auth.oauth.jwt.claim.aud"); System.clearProperty("athenz.auth.oauth.jwt.claim.scope"); authority.initialize(); assertEquals(authorizedServicesField.get(authority), new HashMap<String, String>()); validator = (DefaultOAuthJwtAccessTokenValidator) validatorField.get(authority); trustedIssuerField = validator.getClass().getDeclaredField("trustedIssuer"); requiredAudiencesField = validator.getClass().getDeclaredField("requiredAudiences"); requiredScopesField = validator.getClass().getDeclaredField("requiredScopes"); authorizedClientIdsField = validator.getClass().getDeclaredField("authorizedClientIds"); trustedIssuerField.setAccessible(true); requiredAudiencesField.setAccessible(true); requiredScopesField.setAccessible(true); authorizedClientIdsField.setAccessible(true); assertEquals(trustedIssuerField.get(validator), "https: assertEquals(requiredAudiencesField.get(validator), new HashSet<>(Arrays.asList(new String[]{"https: assertEquals(requiredScopesField.get(validator), new HashSet<>(Arrays.asList(new String[]{"sys.auth:role.admin"}))); assertEquals(authorizedClientIdsField.get(validator), new HashMap<String, String>()); }