ZTSImpl implements KeyStore, ZTSHandler { @Override public AccessTokenResponse postAccessTokenRequest(ResourceContext ctx, String request) { final String caller = ctx.getApiName(); final String principalDomain = logPrincipalAndGetDomain(ctx); validateRequest(ctx.request(), principalDomain, caller); final Principal principal = ((RsrcCtxWrapper) ctx).principal(); String principalName = principal.getFullName(); if (request == null || request.isEmpty()) { throw requestError("Empty request body", caller, ZTSConsts.ZTS_UNKNOWN_DOMAIN, principalDomain); } ctx.request().setAttribute(ACCESS_LOG_ADDL_QUERY, getQueryLogData(request)); String grantType = null; String scope = null; String proxyForPrincipal = null; int expiryTime = 0; String[] comps = request.split("&"); for (String comp : comps) { int idx = comp.indexOf('='); if (idx == -1) { if (LOGGER.isDebugEnabled()) { LOGGER.debug("postAccessTokenRequest: skipping invalid component: {}", comp); } continue; } final String key = decodeString(comp.substring(0, idx)); if (key == null) { if (LOGGER.isDebugEnabled()) { LOGGER.debug("postAccessTokenRequest: skipping invalid component: {}", comp); } continue; } final String value = decodeString(comp.substring(idx + 1)); if (value == null) { continue; } switch (key) { case KEY_GRANT_TYPE: grantType = value.toLowerCase(); break; case KEY_SCOPE: scope = value.toLowerCase(); break; case KEY_EXPIRES_IN: expiryTime = ZTSUtils.parseInt(value, 0); break; case KEY_PROXY_FOR_PRINCIPAL: proxyForPrincipal = getProxyForPrincipalValue(value.toLowerCase(), principalName, principalDomain, caller); break; } } if (!OAUTH_GRANT_CREDENTIALS.equals(grantType)) { throw requestError("Invalid grant request: " + grantType, caller, principal.getDomain(), principalDomain); } if (scope == null || scope.isEmpty()) { throw requestError("Invalid request: no scope provided", caller, principal.getDomain(), principalDomain); } if (LOGGER.isDebugEnabled()) { LOGGER.debug("postAccessTokenRequest(principal: {}, grant-type: {}, scope: {}, expires-in: {}, proxy-for-principal: {})", principalName, grantType, scope, expiryTime, proxyForPrincipal); } AccessTokenRequest tokenRequest = new AccessTokenRequest(scope); final String domainName = tokenRequest.getDomainName(); setRequestDomain(ctx, domainName); validate(domainName, TYPE_DOMAIN_NAME, principalDomain, caller); String[] requestedRoles = tokenRequest.getRoleNames(); if (requestedRoles != null) { for (String requestedRole : requestedRoles) { validate(requestedRole, TYPE_ENTITY_NAME, principalDomain, caller); } } DataCache data = dataStore.getDataCache(domainName); if (data == null) { setRequestDomain(ctx, ZTSConsts.ZTS_UNKNOWN_DOMAIN); throw notFoundError("No such domain: " + domainName, caller, ZTSConsts.ZTS_UNKNOWN_DOMAIN, principalDomain); } checkRoleTokenAuthorizedServiceRequest(principal, domainName, caller); Set<String> roles = new HashSet<>(); dataStore.getAccessibleRoles(data, domainName, principalName, requestedRoles, roles, false); if (roles.isEmpty()) { throw forbiddenError("No access to any roles in domain: " + domainName, caller, domainName, principalDomain); } String proxyUser = null; if (proxyForPrincipal != null) { if (tokenRequest.isOpenidScope()) { throw requestError("Proxy Principal cannot request id tokens", caller, domainName, principalDomain); } Set<String> rolesForProxy = new HashSet<>(); dataStore.getAccessibleRoles(data, domainName, proxyForPrincipal, requestedRoles, rolesForProxy, false); roles.retainAll(rolesForProxy); if (roles.isEmpty()) { throw forbiddenError("No access to any roles by User and Proxy Principals", caller, domainName, principalDomain); } proxyUser = principalName; principalName = proxyForPrincipal; } if (!isPrincipalRoleCertificateAccessValid(principal, domainName, roles)) { throw forbiddenError("Role based Principal does not include all roles", caller, domainName, principalDomain); } long tokenTimeout = determineTokenTimeout(data, roles, null, expiryTime); long iat = System.currentTimeMillis() / 1000; AccessToken accessToken = new AccessToken(); accessToken.setVersion(1); accessToken.setAudience(domainName); accessToken.setClientId(principalName); accessToken.setIssueTime(iat); accessToken.setAuthTime(iat); accessToken.setExpiryTime(iat + tokenTimeout); accessToken.setUserId(principalName); accessToken.setSubject(principalName); accessToken.setIssuer(ztsOAuthIssuer); accessToken.setProxyPrincipal(proxyUser); accessToken.setScope(new ArrayList<>(roles)); X509Certificate cert = principal.getX509Certificate(); if (cert != null) { accessToken.setConfirmX509CertHash(cert); } String accessJwts = accessToken.getSignedToken(privateKey.getKey(), privateKey.getId(), privateKey.getAlgorithm()); String idJwts = null; if (tokenRequest.isOpenidScope()) { final String serviceName = tokenRequest.getServiceName(); validate(serviceName, TYPE_SIMPLE_NAME, principalDomain, caller); IdToken idToken = new IdToken(); idToken.setVersion(1); idToken.setAudience(tokenRequest.getDomainName() + "." + serviceName); idToken.setSubject(principalName); idToken.setIssuer(ztsOAuthIssuer); idToken.setIssueTime(iat); idToken.setAuthTime(iat); idToken.setExpiryTime(iat + determineIdTokenTimeout(tokenTimeout)); idJwts = idToken.getSignedToken(privateKey.getKey(), privateKey.getId(), privateKey.getAlgorithm()); } AccessTokenResponse response = new AccessTokenResponse().setAccess_token(accessJwts) .setToken_type(OAUTH_BEARER_TOKEN).setExpires_in((int) tokenTimeout).setId_token(idJwts); if (tokenRequest.sendScopeResponse() || requestedRoles != null && requestedRoles.length != roles.size()) { List<String> domainRoles = new ArrayList<>(); for (String role : roles) { domainRoles.add(domainName + AccessTokenRequest.OBJECT_ROLE + role); } if (tokenRequest.isOpenidScope()) { domainRoles.add(AccessTokenRequest.OBJECT_OPENID); } response.setScope(String.join(" ", domainRoles)); } return response; } ZTSImpl();  ZTSImpl(CloudStore implCloudStore, DataStore implDataStore); @Override String getPublicKey(String domain, String service, String keyId); ServiceIdentity getServiceIdentity(ResourceContext ctx, String domainName, String serviceName); PublicKeyEntry getPublicKeyEntry(ResourceContext ctx, String domainName,
            String serviceName, String keyId); ServiceIdentityList getServiceIdentityList(ResourceContext ctx, String domainName); HostServices getHostServices(ResourceContext ctx, String host); Response getDomainSignedPolicyData(ResourceContext ctx, String domainName, String matchingTag); TenantDomains getTenantDomains(ResourceContext ctx, String providerDomainName,
            String userName, String roleName, String serviceName); @Override RoleToken getRoleToken(ResourceContext ctx, String domainName, String roleNames,
            Integer minExpiryTime, Integer maxExpiryTime, String proxyForPrincipal); @Override AccessTokenResponse postAccessTokenRequest(ResourceContext ctx, String request); RoleAccess getRoleAccess(ResourceContext ctx, String domainName, String principal); @Override RoleToken postRoleCertificateRequest(ResourceContext ctx, String domainName,
            String roleName, RoleCertificateRequest req); @Override RoleCertificate postRoleCertificateRequestExt(ResourceContext ctx, RoleCertificateRequest req); AWSTemporaryCredentials getAWSTemporaryCredentials(ResourceContext ctx, String domainName,
            String roleName, Integer durationSeconds, String externalId); @Override Response postInstanceRegisterInformation(ResourceContext ctx, InstanceRegisterInformation info); @Override InstanceIdentity postInstanceRefreshInformation(ResourceContext ctx, String provider,
            String domain, String service, String instanceId, InstanceRefreshInformation info); @Override void deleteInstanceIdentity(ResourceContext ctx, String provider,
            String domain, String service, String instanceId); @Deprecated @Override Identity postInstanceRefreshRequest(ResourceContext ctx, String domain,
            String service, InstanceRefreshRequest req); @Override Response postSSHCertRequest(ResourceContext ctx, SSHCertRequest certRequest); @Override JWKList getJWKList(ResourceContext ctx, Boolean rfc); @Deprecated @Override Identity postOSTKInstanceRefreshRequest(ResourceContext ctx, String domain,
            String service, OSTKInstanceRefreshRequest req); @Override ResourceAccess getResourceAccessExt(ResourceContext ctx, String action, String resource,
            String trustDomain, String checkPrincipal); @Override ResourceAccess getResourceAccess(ResourceContext ctx, String action, String resource,
            String trustDomain, String checkPrincipal); @Override Access getAccess(ResourceContext ctx, String domainName, String roleName,
            String principal); CertificateAuthorityBundle getCertificateAuthorityBundle(ResourceContext ctx, String name); @Override DomainMetrics postDomainMetrics(ResourceContext ctx, String domainName,
            DomainMetrics domainMetrics); @Override Status getStatus(ResourceContext ctx); @Override Schema getRdlSchema(ResourceContext context); ResourceContext newResourceContext(HttpServletRequest request,
                                              HttpServletResponse response,
                                              String apiName); static String getRootDir(); void recordMetrics(ResourceContext ctx, int httpStatus);  }
@Test public void testPostAccessTokenRequest() throws UnsupportedEncodingException { System.setProperty(FilePrivateKeyStore.ATHENZ_PROP_PRIVATE_KEY, "src/test/resources/unit_test_zts_at_private.pem"); CloudStore cloudStore = new CloudStore(); cloudStore.setHttpClient(null); ZTSImpl ztsImpl = new ZTSImpl(cloudStore, store); System.setProperty(FilePrivateKeyStore.ATHENZ_PROP_PRIVATE_KEY, "src/test/resources/unit_test_zts_private.pem"); SignedDomain signedDomain = createSignedDomain("coretech", "weather", "storage", true); store.processDomain(signedDomain, false); Principal principal = SimplePrincipal.create("user_domain", "user", "v=U1;d=user_domain;n=user;s=signature", 0, null); ResourceContext context = createResourceContext(principal); final String scope = URLEncoder.encode("coretech:domain", "UTF-8"); AccessTokenResponse resp = ztsImpl.postAccessTokenRequest(context, "grant_type=client_credentials&scope=" + scope); assertNotNull(resp); assertEquals("coretech:role.writers", resp.getScope()); String accessTokenStr = resp.getAccess_token(); assertNotNull(accessTokenStr); Jws<Claims> claims; try { claims = Jwts.parserBuilder().setSigningKey(Crypto.extractPublicKey(ztsImpl.privateKey.getKey())).build().parseClaimsJws(accessTokenStr); } catch (SignatureException e) { throw new ResourceException(ResourceException.UNAUTHORIZED); } assertNotNull(claims); assertEquals("user_domain.user", claims.getBody().getSubject()); assertEquals("coretech", claims.getBody().getAudience()); assertEquals(ztsImpl.ztsOAuthIssuer, claims.getBody().getIssuer()); List<String> scopes = (List<String>) claims.getBody().get("scp"); assertNotNull(scopes); assertEquals(1, scopes.size()); assertEquals("writers", scopes.get(0)); Principal principal1 = SimplePrincipal.create("user_domain", "user1", "v=U1;d=user_domain;n=user1;s=signature", 0, null); ResourceContext context1 = createResourceContext(principal1); resp = ztsImpl.postAccessTokenRequest(context1, "grant_type=client_credentials&scope=coretech:domain&expires_in=100"); assertNotNull(resp); assertEquals("coretech:role.readers coretech:role.writers", resp.getScope()); accessTokenStr = resp.getAccess_token(); assertNotNull(accessTokenStr); assertEquals(Integer.valueOf(100), resp.getExpires_in()); try { claims = Jwts.parserBuilder().setSigningKey(Crypto.extractPublicKey(ztsImpl.privateKey.getKey())).build().parseClaimsJws(accessTokenStr); } catch (SignatureException e) { throw new ResourceException(ResourceException.UNAUTHORIZED); } assertNotNull(claims); assertEquals("user_domain.user1", claims.getBody().getSubject()); assertEquals("coretech", claims.getBody().getAudience()); assertEquals(100 * 1000, claims.getBody().getExpiration().getTime() - claims.getBody().getIssuedAt().getTime()); }
@Test public void testPostAccessTokenRequestRoleAuthority() { System.setProperty(FilePrivateKeyStore.ATHENZ_PROP_PRIVATE_KEY, "src/test/resources/unit_test_zts_at_private.pem"); CloudStore cloudStore = new CloudStore(); cloudStore.setHttpClient(null); ZTSImpl ztsImpl = new ZTSImpl(cloudStore, store); System.setProperty(FilePrivateKeyStore.ATHENZ_PROP_PRIVATE_KEY, "src/test/resources/unit_test_zts_private.pem"); SignedDomain signedDomain = createSignedDomain("coretech", "weather", "storage", true); store.processDomain(signedDomain, false); SimplePrincipal principal = (SimplePrincipal) SimplePrincipal.create("user_domain", "user1", "v=U1;d=user_domain;n=user1;s=signature", 0, new CertificateAuthority()); ResourceContext context = createResourceContext(principal); List<String> principalRoles = new ArrayList<>(); principalRoles.add("coretech:role.readers"); principal.setRoles(principalRoles); try { ztsImpl.postAccessTokenRequest(context, "grant_type=client_credentials&scope=coretech:domain"); fail(); } catch (ResourceException ex) { assertEquals(403, ex.getCode()); } principalRoles.add("coretech:role.writers"); AccessTokenResponse resp = ztsImpl.postAccessTokenRequest(context, "grant_type=client_credentials&scope=coretech:domain&expires_in=100"); assertNotNull(resp); assertEquals("coretech:role.readers coretech:role.writers", resp.getScope()); }
@Test public void testPostAccessTokenRequestmTLSBound() throws IOException { System.setProperty(FilePrivateKeyStore.ATHENZ_PROP_PRIVATE_KEY, "src/test/resources/unit_test_zts_at_private.pem"); CloudStore cloudStore = new CloudStore(); cloudStore.setHttpClient(null); ZTSImpl ztsImpl = new ZTSImpl(cloudStore, store); System.setProperty(FilePrivateKeyStore.ATHENZ_PROP_PRIVATE_KEY, "src/test/resources/unit_test_zts_private.pem"); SignedDomain signedDomain = createSignedDomain("coretech", "weather", "storage", true); store.processDomain(signedDomain, false); Principal principal = SimplePrincipal.create("user_domain", "user", "x509-certificate-details", 0, new CertificateAuthority()); Path path = Paths.get("src/test/resources/mtls_token_spec.cert"); String certStr = new String(Files.readAllBytes(path)); X509Certificate cert = Crypto.loadX509Certificate(certStr); ((SimplePrincipal) principal).setX509Certificate(cert); ResourceContext context = createResourceContext(principal); AccessTokenResponse resp = ztsImpl.postAccessTokenRequest(context, "grant_type=client_credentials&scope=coretech:domain"); assertNotNull(resp); assertEquals("coretech:role.writers", resp.getScope()); String accessTokenStr = resp.getAccess_token(); assertNotNull(accessTokenStr); Jws<Claims> claims; try { claims = Jwts.parserBuilder().setSigningKey(Crypto.extractPublicKey(ztsImpl.privateKey.getKey())).build().parseClaimsJws(accessTokenStr); } catch (SignatureException e) { throw new ResourceException(ResourceException.UNAUTHORIZED); } assertNotNull(claims); assertEquals("user_domain.user", claims.getBody().getSubject()); assertEquals("coretech", claims.getBody().getAudience()); assertEquals(ztsImpl.ztsOAuthIssuer, claims.getBody().getIssuer()); List<String> scopes = (List<String>) claims.getBody().get("scp"); assertNotNull(scopes); assertEquals(1, scopes.size()); assertEquals("writers", scopes.get(0)); LinkedHashMap<String, Object> cnf = (LinkedHashMap<String, Object>) claims.getBody().get("cnf"); assertEquals("A4DtL2JmUMhAsvJj5tKyn64SqzmuXbMrJa0n761y5v0", cnf.get("x5t#S256")); }
@Test public void testPostAccessTokenRequestECPrivateKey() { System.setProperty(FilePrivateKeyStore.ATHENZ_PROP_PRIVATE_KEY, "src/test/resources/unit_test_zts_private_ec.pem"); CloudStore cloudStore = new CloudStore(); cloudStore.setHttpClient(null); ZTSImpl ztsImpl = new ZTSImpl(cloudStore, store); System.setProperty(FilePrivateKeyStore.ATHENZ_PROP_PRIVATE_KEY, "src/test/resources/unit_test_zts_private.pem"); SignedDomain signedDomain = createSignedDomain("coretech", "weather", "storage", true); store.processDomain(signedDomain, false); Principal principal = SimplePrincipal.create("user_domain", "user", "v=U1;d=user_domain;n=user;s=signature", 0, null); ResourceContext context = createResourceContext(principal); AccessTokenResponse resp = ztsImpl.postAccessTokenRequest(context, "grant_type=client_credentials&scope=coretech:domain"); assertNotNull(resp); assertEquals("coretech:role.writers", resp.getScope()); String accessTokenStr = resp.getAccess_token(); assertNotNull(accessTokenStr); Jws<Claims> claims; try { claims = Jwts.parserBuilder().setSigningKey(Crypto.extractPublicKey(ztsImpl.privateKey.getKey())).build().parseClaimsJws(accessTokenStr); } catch (SignatureException e) { throw new ResourceException(ResourceException.UNAUTHORIZED); } assertNotNull(claims); assertEquals("user_domain.user", claims.getBody().getSubject()); assertEquals("coretech", claims.getBody().getAudience()); assertEquals(ztsImpl.ztsOAuthIssuer, claims.getBody().getIssuer()); List<String> scopes = (List<String>) claims.getBody().get("scp"); assertNotNull(scopes); assertEquals(1, scopes.size()); assertEquals("writers", scopes.get(0)); }
@Test public void testPostAccessTokenRequestSingleRole() { System.setProperty(FilePrivateKeyStore.ATHENZ_PROP_PRIVATE_KEY, "src/test/resources/unit_test_zts_at_private.pem"); CloudStore cloudStore = new CloudStore(); cloudStore.setHttpClient(null); ZTSImpl ztsImpl = new ZTSImpl(cloudStore, store); System.setProperty(FilePrivateKeyStore.ATHENZ_PROP_PRIVATE_KEY, "src/test/resources/unit_test_zts_private.pem"); SignedDomain signedDomain = createSignedDomain("coretech", "weather", "storage", true); store.processDomain(signedDomain, false); Principal principal = SimplePrincipal.create("user_domain", "user", "v=U1;d=user_domain;n=user;s=signature", 0, null); ResourceContext context = createResourceContext(principal); AccessTokenResponse resp = ztsImpl.postAccessTokenRequest(context, "grant_type=client_credentials&scope=coretech:role.writers"); assertNotNull(resp); assertNull(resp.getScope()); }
@Test public void testPostAccessTokenRequestOpenIdScope() throws UnsupportedEncodingException { System.setProperty(FilePrivateKeyStore.ATHENZ_PROP_PRIVATE_KEY, "src/test/resources/unit_test_zts_at_private.pem"); CloudStore cloudStore = new CloudStore(); cloudStore.setHttpClient(null); ZTSImpl ztsImpl = new ZTSImpl(cloudStore, store); System.setProperty(FilePrivateKeyStore.ATHENZ_PROP_PRIVATE_KEY, "src/test/resources/unit_test_zts_private.pem"); SignedDomain signedDomain = createSignedDomain("coretech", "weather", "storage", true); store.processDomain(signedDomain, false); Principal principal = SimplePrincipal.create("user_domain", "user", "v=U1;d=user_domain;n=user;s=signature", 0, null); ResourceContext context = createResourceContext(principal); final String scope = URLEncoder.encode("coretech:domain openid coretech:service.api", "UTF-8"); AccessTokenResponse resp = ztsImpl.postAccessTokenRequest(context, "grant_type=client_credentials&scope=" + scope + "&expires_in=240"); assertNotNull(resp); assertEquals("coretech:role.writers openid", resp.getScope()); String accessTokenStr = resp.getAccess_token(); assertNotNull(accessTokenStr); String idToken = resp.getId_token(); assertNotNull(idToken); Jws<Claims> claims; try { claims = Jwts.parserBuilder().setSigningKey(Crypto.extractPublicKey(ztsImpl.privateKey.getKey())).build().parseClaimsJws(accessTokenStr); } catch (SignatureException e) { throw new ResourceException(ResourceException.UNAUTHORIZED); } assertNotNull(claims); assertEquals(240 * 1000, claims.getBody().getExpiration().getTime() - claims.getBody().getIssuedAt().getTime()); }
@Test public void testPostAccessTokenRequestOpenIdScopeMaxTimeout() throws UnsupportedEncodingException { System.setProperty(FilePrivateKeyStore.ATHENZ_PROP_PRIVATE_KEY, "src/test/resources/unit_test_zts_at_private.pem"); CloudStore cloudStore = new CloudStore(); cloudStore.setHttpClient(null); ZTSImpl ztsImpl = new ZTSImpl(cloudStore, store); System.setProperty(FilePrivateKeyStore.ATHENZ_PROP_PRIVATE_KEY, "src/test/resources/unit_test_zts_private.pem"); SignedDomain signedDomain = createSignedDomain("coretech", "weather", "storage", true); store.processDomain(signedDomain, false); Principal principal = SimplePrincipal.create("user_domain", "user", "v=U1;d=user_domain;n=user;s=signature", 0, null); ResourceContext context = createResourceContext(principal); final String scope = URLEncoder.encode("coretech:domain openid coretech:service.api", "UTF-8"); AccessTokenResponse resp = ztsImpl.postAccessTokenRequest(context, "grant_type=client_credentials&scope=" + scope + "&expires_in=57600"); assertNotNull(resp); assertEquals("coretech:role.writers openid", resp.getScope()); String accessTokenStr = resp.getAccess_token(); assertNotNull(accessTokenStr); String idToken = resp.getId_token(); assertNotNull(idToken); Jws<Claims> claims; try { claims = Jwts.parserBuilder().setSigningKey(Crypto.extractPublicKey(ztsImpl.privateKey.getKey())).build().parseClaimsJws(idToken); } catch (SignatureException e) { throw new ResourceException(ResourceException.UNAUTHORIZED); } assertNotNull(claims); assertEquals(12 * 60 * 60 * 1000, claims.getBody().getExpiration().getTime() - claims.getBody().getIssuedAt().getTime()); }
@Test public void testPostAccessTokenRequestOpenIdScopeOnly() throws UnsupportedEncodingException { SignedDomain signedDomain = createSignedDomain("coretech", "weather", "storage", true); store.processDomain(signedDomain, false); Principal principal = SimplePrincipal.create("user_domain", "user", "v=U1;d=user_domain;n=user;s=signature", 0, null); ResourceContext context = createResourceContext(principal); try { final String scope = URLEncoder.encode("coretech:role.role999 openid coretech:service.api", "UTF-8"); zts.postAccessTokenRequest(context, "grant_type=client_credentials&scope=" + scope); fail(); } catch (ResourceException ex) { assertEquals(403, ex.getCode()); } }
@Test public void testPostAccessTokenRequestOpenIdScopeOnlyDisabled() throws UnsupportedEncodingException { System.setProperty(FilePrivateKeyStore.ATHENZ_PROP_PRIVATE_KEY, "src/test/resources/unit_test_zts_at_private.pem"); CloudStore cloudStore = new CloudStore(); cloudStore.setHttpClient(null); ZTSImpl ztsImpl = new ZTSImpl(cloudStore, store); System.setProperty(FilePrivateKeyStore.ATHENZ_PROP_PRIVATE_KEY, "src/test/resources/unit_test_zts_private.pem"); AccessTokenRequest.setSupportOpenidScope(false); SignedDomain signedDomain = createSignedDomain("coretech", "weather", "storage", true); store.processDomain(signedDomain, false); Principal principal = SimplePrincipal.create("user_domain", "user", "v=U1;d=user_domain;n=user;s=signature", 0, null); ResourceContext context = createResourceContext(principal); try { final String scope = URLEncoder.encode("coretech:role.role999 openid coretech:service.api", "UTF-8"); ztsImpl.postAccessTokenRequest(context, "grant_type=client_credentials&scope=" + scope); fail(); } catch (ResourceException ex) { assertEquals(403, ex.getCode()); } AccessTokenResponse resp = ztsImpl.postAccessTokenRequest(context, "grant_type=client_credentials&scope=coretech:domain openid coretech:service.api"); assertNotNull(resp); assertEquals("coretech:role.writers", resp.getScope()); assertNotNull(resp.getAccess_token()); assertNull(resp.getId_token()); }
@Test public void testPostAccessTokenRequestInvalidDomain() { SignedDomain signedDomain = createSignedDomain("coretech", "weather", "storage", true); store.processDomain(signedDomain, false); Principal principal = SimplePrincipal.create("user_domain", "user", "v=U1;d=user_domain;n=user;s=signature", 0, null); ResourceContext context = createResourceContext(principal); try { zts.postAccessTokenRequest(context, "grant_type=client_credentials&scope=sportstest:domain"); fail(); } catch (ResourceException ex) { assertEquals(404, ex.getCode()); } }
@Test public void testPostAccessTokenRequestNoRoleMatch() { SignedDomain signedDomain = createSignedDomain("coretech", "weather", "storage", true); store.processDomain(signedDomain, false); Principal principal = SimplePrincipal.create("user_domain", "user", "v=U1;d=user_domain;n=user;s=signature", 0, null); ResourceContext context = createResourceContext(principal); try { zts.postAccessTokenRequest(context, "grant_type=client_credentials&scope=coretech:role.testrole"); fail(); } catch (ResourceException ex) { assertEquals(403, ex.getCode()); } }
@Test public void testPostAccessTokenRequestInvalidRequest() { SignedDomain signedDomain = createSignedDomain("coretech", "weather", "storage", true); store.processDomain(signedDomain, false); Principal principal = SimplePrincipal.create("user_domain", "user", "v=U1;d=user_domain;n=user;s=signature", 0, null); ResourceContext context = createResourceContext(principal); try { zts.postAccessTokenRequest(context, null); fail(); } catch (ResourceException ex) { assertEquals(400, ex.getCode()); } try { zts.postAccessTokenRequest(context, ""); fail(); } catch (ResourceException ex) { assertEquals(400, ex.getCode()); } try { zts.postAccessTokenRequest(context, "grant_type=unknown_type&scope=openid"); fail(); } catch (ResourceException ex) { assertEquals(400, ex.getCode()); assertTrue(ex.getMessage().contains("Invalid grant request")); } try { zts.postAccessTokenRequest(context, "grant_type%=client_credentials"); fail(); } catch (ResourceException ex) { assertEquals(400, ex.getCode()); assertTrue(ex.getMessage().contains("Invalid grant request")); } try { zts.postAccessTokenRequest(context, "grant_type=client_credentials%"); fail(); } catch (ResourceException ex) { assertEquals(400, ex.getCode()); assertTrue(ex.getMessage().contains("Invalid grant request")); } try { zts.postAccessTokenRequest(context, "grant_type"); fail(); } catch (ResourceException ex) { assertEquals(400, ex.getCode()); assertTrue(ex.getMessage().contains("Invalid grant request")); } try { zts.postAccessTokenRequest(context, "grant_type=client_credentials"); fail(); } catch (ResourceException ex) { assertEquals(400, ex.getCode()); assertTrue(ex.getMessage().contains("no scope provided")); } try { zts.postAccessTokenRequest(context, "grant_type=client_credentials&scope="); fail(); } catch (ResourceException ex) { assertEquals(400, ex.getCode()); assertTrue(ex.getMessage().contains("no scope provided")); } }
@Test public void testPostAccessTokenRequestProxyUser() { System.setProperty(FilePrivateKeyStore.ATHENZ_PROP_PRIVATE_KEY, "src/test/resources/unit_test_zts_at_private.pem"); CloudStore cloudStore = new CloudStore(); cloudStore.setHttpClient(null); ZTSImpl ztsImpl = new ZTSImpl(cloudStore, store); System.setProperty(FilePrivateKeyStore.ATHENZ_PROP_PRIVATE_KEY, "src/test/resources/unit_test_zts_private.pem"); List<RoleMember> writers = new ArrayList<>(); writers.add(new RoleMember().setMemberName("user_domain.proxy-user1")); writers.add(new RoleMember().setMemberName("user_domain.joe")); List<RoleMember> readers = new ArrayList<>(); readers.add(new RoleMember().setMemberName("user_domain.proxy-user2")); readers.add(new RoleMember().setMemberName("user_domain.jane")); SignedDomain signedDomain = createSignedDomain("coretech-proxy2", "weather-proxy2", "storage", writers, readers, true); store.processDomain(signedDomain, false); Principal principal = SimplePrincipal.create("user_domain", "proxy-user1", "v=U1;d=user_domain;n=proxy-user1;s=sig", 0, null); ResourceContext context = createResourceContext(principal); AccessTokenResponse resp = ztsImpl.postAccessTokenRequest(context, "grant_type=client_credentials&scope=coretech-proxy2:domain&proxy_for_principal=user_domain.joe"); assertNotNull(resp); assertEquals("coretech-proxy2:role.writers", resp.getScope()); String accessTokenStr = resp.getAccess_token(); assertNotNull(accessTokenStr); Jws<Claims> claims; try { claims = Jwts.parserBuilder().setSigningKey(Crypto.extractPublicKey(ztsImpl.privateKey.getKey())).build().parseClaimsJws(accessTokenStr); } catch (SignatureException e) { throw new ResourceException(ResourceException.UNAUTHORIZED); } assertNotNull(claims); assertEquals("user_domain.joe", claims.getBody().getSubject()); assertEquals("user_domain.proxy-user1", claims.getBody().get("proxy")); assertEquals("coretech-proxy2", claims.getBody().getAudience()); assertEquals(ztsImpl.ztsOAuthIssuer, claims.getBody().getIssuer()); List<String> scopes = (List<String>) claims.getBody().get("scp"); assertNotNull(scopes); assertEquals(1, scopes.size()); assertEquals("writers", scopes.get(0)); }
@Test public void testPostAccessTokenRequestProxyUserMismatchRolesIntersection() { System.setProperty(FilePrivateKeyStore.ATHENZ_PROP_PRIVATE_KEY, "src/test/resources/unit_test_zts_at_private.pem"); CloudStore cloudStore = new CloudStore(); cloudStore.setHttpClient(null); ZTSImpl ztsImpl = new ZTSImpl(cloudStore, store); System.setProperty(FilePrivateKeyStore.ATHENZ_PROP_PRIVATE_KEY, "src/test/resources/unit_test_zts_private.pem"); List<RoleMember> writers = new ArrayList<>(); writers.add(new RoleMember().setMemberName("user_domain.proxy-user1")); writers.add(new RoleMember().setMemberName("user_domain.joe")); List<RoleMember> readers = new ArrayList<>(); readers.add(new RoleMember().setMemberName("user_domain.proxy-user2")); readers.add(new RoleMember().setMemberName("user_domain.jane")); readers.add(new RoleMember().setMemberName("user_domain.proxy-user1")); SignedDomain signedDomain = createSignedDomain("coretech-proxy3", "weather-proxy3", "storage", writers, readers, true); store.processDomain(signedDomain, false); Principal principal = SimplePrincipal.create("user_domain", "proxy-user1", "v=U1;d=user_domain;n=proxy-user1;s=sig", 0, null); ResourceContext context = createResourceContext(principal); AccessTokenResponse resp = ztsImpl.postAccessTokenRequest(context, "grant_type=client_credentials&scope=coretech-proxy3:domain&proxy_for_principal=user_domain.joe"); assertNotNull(resp); assertEquals("coretech-proxy3:role.writers", resp.getScope()); String accessTokenStr = resp.getAccess_token(); assertNotNull(accessTokenStr); Jws<Claims> claims; try { claims = Jwts.parserBuilder().setSigningKey(Crypto.extractPublicKey(ztsImpl.privateKey.getKey())).build().parseClaimsJws(accessTokenStr); } catch (SignatureException e) { throw new ResourceException(ResourceException.UNAUTHORIZED); } assertNotNull(claims); assertEquals("user_domain.joe", claims.getBody().getSubject()); assertEquals("user_domain.proxy-user1", claims.getBody().get("proxy")); assertEquals("coretech-proxy3", claims.getBody().getAudience()); assertEquals(ztsImpl.ztsOAuthIssuer, claims.getBody().getIssuer()); List<String> scopes = (List<String>) claims.getBody().get("scp"); assertNotNull(scopes); assertEquals(1, scopes.size()); assertEquals("writers", scopes.get(0)); }
@Test public void testPostAccessTokenRequestProxyUserMismatchRolesEmptySet() { List<RoleMember> writers = new ArrayList<>(); writers.add(new RoleMember().setMemberName("user_domain.joe")); List<RoleMember> readers = new ArrayList<>(); readers.add(new RoleMember().setMemberName("user_domain.proxy-user2")); readers.add(new RoleMember().setMemberName("user_domain.jane")); readers.add(new RoleMember().setMemberName("user_domain.proxy-user1")); SignedDomain signedDomain = createSignedDomain("coretech-proxy4", "weather-proxy4", "storage", writers, readers, true); store.processDomain(signedDomain, false); Principal principal = SimplePrincipal.create("user_domain", "proxy-user1", "v=U1;d=user_domain;n=proxy-user1;s=sig", 0, null); ResourceContext context = createResourceContext(principal); try { zts.postAccessTokenRequest(context, "grant_type=client_credentials&scope=coretech-proxy4:domain&proxy_for_principal=user_domain.joe"); fail(); } catch (ResourceException ex) { assertEquals(ex.getCode(), 403); } }
@Test public void testPostAccessTokenRequestProxyUserOpenidScope() throws UnsupportedEncodingException { List<RoleMember> writers = new ArrayList<>(); writers.add(new RoleMember().setMemberName("user_domain.joe")); List<RoleMember> readers = new ArrayList<>(); readers.add(new RoleMember().setMemberName("user_domain.proxy-user2")); readers.add(new RoleMember().setMemberName("user_domain.jane")); readers.add(new RoleMember().setMemberName("user_domain.proxy-user1")); SignedDomain signedDomain = createSignedDomain("coretech-proxy4", "weather-proxy4", "storage", writers, readers, true); store.processDomain(signedDomain, false); Principal principal = SimplePrincipal.create("user_domain", "proxy-user1", "v=U1;d=user_domain;n=proxy-user1;s=sig", 0, null); ResourceContext context = createResourceContext(principal); try { final String scope = URLEncoder.encode("openid coretech-proxy4:domain coretech-proxy4:service.api", "UTF-8"); zts.postAccessTokenRequest(context, "grant_type=client_credentials&scope=" + scope + "&proxy_for_principal=user_domain.jane"); fail(); } catch (ResourceException ex) { assertEquals(ex.getCode(), 400); assertTrue(ex.getMessage().contains("Proxy Principal cannot request id tokens")); } }
@Test public void testPostAccessTokenRequestProxyUserSpecificRole() { System.setProperty(FilePrivateKeyStore.ATHENZ_PROP_PRIVATE_KEY, "src/test/resources/unit_test_zts_at_private.pem"); CloudStore cloudStore = new CloudStore(); cloudStore.setHttpClient(null); ZTSImpl ztsImpl = new ZTSImpl(cloudStore, store); System.setProperty(FilePrivateKeyStore.ATHENZ_PROP_PRIVATE_KEY, "src/test/resources/unit_test_zts_private.pem"); List<RoleMember> writers = new ArrayList<>(); writers.add(new RoleMember().setMemberName("user_domain.proxy-user1")); writers.add(new RoleMember().setMemberName("user_domain.joe")); List<RoleMember> readers = new ArrayList<>(); readers.add(new RoleMember().setMemberName("user_domain.proxy-user2")); readers.add(new RoleMember().setMemberName("user_domain.jane")); readers.add(new RoleMember().setMemberName("user_domain.proxy-user1")); SignedDomain signedDomain = createSignedDomain("coretech-proxy4", "weather-proxy4", "storage", writers, readers, true); store.processDomain(signedDomain, false); Principal principal = SimplePrincipal.create("user_domain", "proxy-user1", "v=U1;d=user_domain;n=proxy-user1;s=sig", 0, null); ResourceContext context = createResourceContext(principal); AccessTokenResponse resp = ztsImpl.postAccessTokenRequest(context, "grant_type=client_credentials&scope=coretech-proxy4:role.writers&proxy_for_principal=user_domain.joe"); assertNotNull(resp); String accessTokenStr = resp.getAccess_token(); assertNotNull(accessTokenStr); Jws<Claims> claims; try { claims = Jwts.parserBuilder().setSigningKey(Crypto.extractPublicKey(ztsImpl.privateKey.getKey())).build().parseClaimsJws(accessTokenStr); } catch (SignatureException e) { throw new ResourceException(ResourceException.UNAUTHORIZED); } assertNotNull(claims); assertEquals("user_domain.joe", claims.getBody().getSubject()); assertEquals("user_domain.proxy-user1", claims.getBody().get("proxy")); assertEquals("coretech-proxy4", claims.getBody().getAudience()); assertEquals(ztsImpl.ztsOAuthIssuer, claims.getBody().getIssuer()); List<String> scopes = (List<String>) claims.getBody().get("scp"); assertNotNull(scopes); assertEquals(1, scopes.size()); assertEquals("writers", scopes.get(0)); }