use of com.yahoo.athenz.zts.token.IdTokenRequest in project athenz by yahoo.
the class ZTSImpl method getOIDCResponse.
@Override
public Response getOIDCResponse(ResourceContext ctx, String responseType, String clientId, String redirectUri, String scope, String state, String nonce, String keyType) {
final String caller = ctx.getApiName();
final String principalDomain = logPrincipalAndGetDomain(ctx);
validateRequest(ctx.request(), principalDomain, caller);
validate(nonce, TYPE_ENTITY_NAME, principalDomain, caller);
validate(clientId, TYPE_SERVICE_NAME, principalDomain, caller);
if (!StringUtil.isEmpty(state)) {
validate(state, TYPE_ENTITY_NAME, principalDomain, caller);
}
if (!StringUtil.isEmpty(keyType)) {
validate(keyType, TYPE_SIMPLE_NAME, principalDomain, caller);
}
clientId = clientId.toLowerCase();
// get our principal's name
final Principal principal = ((RsrcCtxWrapper) ctx).principal();
String principalName = principal.getFullName();
// verify we have a valid client id
final String domainName = AthenzUtils.extractPrincipalDomainName(clientId);
if (domainName == null) {
throw requestError("Invalid client id", caller, principal.getDomain(), principalDomain);
}
setRequestDomain(ctx, domainName);
// first retrieve our domain data object from the cache
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);
}
final String serviceEndpoint = extractServiceEndpoint(data.getDomainData(), clientId);
if (StringUtil.isEmpty(serviceEndpoint)) {
throw requestError("Invalid Service or empty service endpoint", caller, principal.getDomain(), principalDomain);
}
if (!serviceEndpoint.equalsIgnoreCase(redirectUri)) {
throw requestError("Unregistered redirect uri", caller, principal.getDomain(), principalDomain);
}
if (!ZTSConsts.ZTS_OPENID_RESPONSE_IT_ONLY.equals(responseType)) {
return oidcError("invalid response type", redirectUri, state);
}
if (StringUtil.isEmpty(scope)) {
return oidcError("no scope provided", redirectUri, state);
}
// our scopes are space separated list of values. Any groups
// scopes are preferred over any role scopes
IdTokenRequest tokenRequest = new IdTokenRequest(scope);
if (tokenRequest.getDomainName() != null && !domainName.equalsIgnoreCase(tokenRequest.getDomainName())) {
return oidcError("domain name mismatch", redirectUri, state);
}
// check if the authorized service domain matches to the
// requested domain name
checkRoleTokenAuthorizedServiceRequest(principal, domainName, caller);
// validate principal object to make sure we're not
// processing a role identity, and instead we require
// a service identity
validatePrincipalNotRoleIdentity(principal, caller);
// now let's process our requests and see if we need to extract
// either groups or roles for our response
List<String> groups = null;
if (tokenRequest.isGroupsScope()) {
Set<String> groupNames = tokenRequest.getGroupNames();
if (groupNames != null) {
for (String groupName : groupNames) {
validate(groupName, TYPE_ENTITY_NAME, principalDomain, caller);
}
}
// process our request and retrieve the groups for the principal
groups = dataStore.getPrincipalGroups(principalName, domainName, groupNames);
if (groupNames != null && groups == null) {
return oidcError("principal not included in requested groups", redirectUri, state);
}
} else if (tokenRequest.isRolesScope()) {
String[] requestedRoles = tokenRequest.getRoleNames();
if (requestedRoles != null) {
for (String requestedRole : requestedRoles) {
validate(requestedRole, TYPE_ENTITY_NAME, principalDomain, caller);
}
}
// process our request and retrieve the roles for the principal
Set<String> roles = new HashSet<>();
dataStore.getAccessibleRoles(data, domainName, principalName, requestedRoles, roles, false);
if (requestedRoles != null && roles.isEmpty()) {
return oidcError("principal not included in requested roles", redirectUri, state);
}
groups = new ArrayList<>(roles);
}
long iat = System.currentTimeMillis() / 1000;
IdToken idToken = new IdToken();
idToken.setVersion(1);
idToken.setAudience(clientId);
idToken.setSubject(principalName);
idToken.setIssuer(ztsOpenIDIssuer);
idToken.setNonce(nonce);
idToken.setGroups(groups);
idToken.setIssueTime(iat);
idToken.setAuthTime(iat);
idToken.setExpiryTime(iat + idTokenDefaultTimeout);
ServerPrivateKey signPrivateKey = getSignPrivateKey(keyType);
String location = redirectUri + "#id_token=" + idToken.getSignedToken(signPrivateKey.getKey(), signPrivateKey.getId(), signPrivateKey.getAlgorithm());
if (!StringUtil.isEmpty(state)) {
location += "&state=" + state;
}
return Response.status(ResourceException.FOUND).header("Location", location).build();
}
Aggregations