Example usage for org.springframework.security.oauth2.provider.client BaseClientDetails setAdditionalInformation

List of usage examples for org.springframework.security.oauth2.provider.client BaseClientDetails setAdditionalInformation

Introduction

In this page you can find the example usage for org.springframework.security.oauth2.provider.client BaseClientDetails setAdditionalInformation.

Prototype

public void setAdditionalInformation(Map<String, ?> additionalInformation) 

Source Link

Usage

From source file:it.smartcommunitylab.aac.model.ClientDetailsRowMapper.java

public ClientDetails mapRow(ResultSet rs, int rowNum) throws SQLException {
    BaseClientDetails details = new BaseClientDetails(rs.getString("client_id"), rs.getString("resource_ids"),
            rs.getString("scope"), rs.getString("authorized_grant_types"), rs.getString("authorities"),
            rs.getString("web_server_redirect_uri"));
    details.setClientSecret(rs.getString("client_secret"));
    if (rs.getObject("access_token_validity") != null) {
        details.setAccessTokenValiditySeconds(rs.getInt("access_token_validity"));
    }/*from   w  w  w  . ja v  a  2 s .  c  om*/
    if (rs.getObject("refresh_token_validity") != null) {
        details.setRefreshTokenValiditySeconds(rs.getInt("refresh_token_validity"));
    }
    String json = rs.getString("additional_information");
    if (json != null) {
        try {
            @SuppressWarnings("unchecked")
            Map<String, Object> additionalInformation = mapper.readValue(json, Map.class);
            details.setAdditionalInformation(additionalInformation);
        } catch (Exception e) {
            logger.warn("Could not decode JSON for additional information: " + details, e);
        }
    } else {
        details.setAdditionalInformation(new HashMap<String, Object>());
    }

    // merge developer roles into authorities
    it.smartcommunitylab.aac.model.User developer = userRepository.findOne(rs.getLong("developerId"));
    if (developer != null) {
        List<GrantedAuthority> list = new LinkedList<GrantedAuthority>();
        if (details.getAuthorities() != null)
            list.addAll(details.getAuthorities());
        list.addAll(developer.getRoles().stream().filter(r -> !StringUtils.isEmpty(r.getContext()))
                .collect(Collectors.toList()));
        details.setAuthorities(list);
    }
    return details;
}

From source file:org.cloudfoundry.identity.uaa.client.ClientAdminBootstrap.java

/**
 * Explicitly override autoapprove in all clients that were provided in the
 * whitelist./*from   w  w w  .ja v a2  s  .c  o m*/
 */
private void updateAutoApprovClients() {

    List<ClientDetails> clients = clientRegistrationService.listClientDetails();

    for (ClientDetails client : clients) {
        if (!autoApproveClients.contains(client.getClientId())) {
            continue;
        }
        BaseClientDetails base = new BaseClientDetails(client);
        Map<String, Object> info = new HashMap<String, Object>(client.getAdditionalInformation());
        info.put(ClientConstants.AUTO_APPROVE, true);
        base.setAdditionalInformation(info);
        logger.debug("Adding autoapprove flag: " + base);
        clientRegistrationService.updateClientDetails(base);
    }

}

From source file:org.cloudfoundry.identity.uaa.client.ClientAdminBootstrap.java

private void addNewClients() throws Exception {
    for (Map.Entry<String, Map<String, Object>> entry : clients.entrySet()) {
        String clientId = entry.getKey();
        Map<String, Object> map = entry.getValue();
        BaseClientDetails client = new BaseClientDetails(clientId, (String) map.get("resource-ids"),
                (String) map.get("scope"), (String) map.get("authorized-grant-types"),
                (String) map.get("authorities"), getRedirectUris(map));
        client.setClientSecret((String) map.get("secret"));
        Integer validity = (Integer) map.get("access-token-validity");
        Boolean override = (Boolean) map.get("override");
        if (override == null) {
            override = defaultOverride;/*from w ww.j  a  v a 2 s.  co  m*/
        }
        Map<String, Object> info = new HashMap<String, Object>(map);
        if (validity != null) {
            client.setAccessTokenValiditySeconds(validity);
        }
        validity = (Integer) map.get("refresh-token-validity");
        if (validity != null) {
            client.setRefreshTokenValiditySeconds(validity);
        }
        // UAA does not use the resource ids in client registrations
        client.setResourceIds(Collections.singleton("none"));
        if (client.getScope().isEmpty()) {
            client.setScope(Collections.singleton("uaa.none"));
        }
        if (client.getAuthorities().isEmpty()) {
            client.setAuthorities(Collections.singleton(UaaAuthority.UAA_NONE));
        }
        if (client.getAuthorizedGrantTypes().contains("authorization_code")) {
            client.getAuthorizedGrantTypes().add("refresh_token");
        }
        for (String key : Arrays.asList("resource-ids", "scope", "authorized-grant-types", "authorities",
                "redirect-uri", "secret", "id", "override", "access-token-validity", "refresh-token-validity",
                "show-on-homepage", "app-launch-url", "app-icon")) {
            info.remove(key);
        }

        client.setAdditionalInformation(info);
        try {
            clientRegistrationService.addClientDetails(client);
        } catch (ClientAlreadyExistsException e) {
            if (override == null || override) {
                logger.debug("Overriding client details for " + clientId);
                clientRegistrationService.updateClientDetails(client);
                if (StringUtils.hasText(client.getClientSecret())
                        && didPasswordChange(clientId, client.getClientSecret())) {
                    clientRegistrationService.updateClientSecret(clientId, client.getClientSecret());
                }
            } else {
                // ignore it
                logger.debug(e.getMessage());
            }
        }
        ClientMetadata clientMetadata = buildClientMetadata(map, clientId);
        clientMetadataProvisioning.update(clientMetadata);
    }
}

From source file:org.cloudfoundry.identity.uaa.client.ClientAdminEndpoints.java

private ClientDetails syncWithExisting(ClientDetails existing, ClientDetails input) {
    BaseClientDetails details = new BaseClientDetails(input);
    if (input instanceof BaseClientDetails) {
        BaseClientDetails baseInput = (BaseClientDetails) input;
        if (baseInput.getAutoApproveScopes() != null) {
            details.setAutoApproveScopes(baseInput.getAutoApproveScopes());
        } else {//from   ww  w. j  a  v  a2  s.  com
            details.setAutoApproveScopes(new HashSet<String>());
            if (existing instanceof BaseClientDetails) {
                BaseClientDetails existingDetails = (BaseClientDetails) existing;
                if (existingDetails.getAutoApproveScopes() != null) {
                    for (String scope : existingDetails.getAutoApproveScopes()) {
                        details.getAutoApproveScopes().add(scope);
                    }
                }
            }
        }

    }

    if (details.getAccessTokenValiditySeconds() == null) {
        details.setAccessTokenValiditySeconds(existing.getAccessTokenValiditySeconds());
    }
    if (details.getRefreshTokenValiditySeconds() == null) {
        details.setRefreshTokenValiditySeconds(existing.getRefreshTokenValiditySeconds());
    }
    if (details.getAuthorities() == null || details.getAuthorities().isEmpty()) {
        details.setAuthorities(existing.getAuthorities());
    }
    if (details.getAuthorizedGrantTypes() == null || details.getAuthorizedGrantTypes().isEmpty()) {
        details.setAuthorizedGrantTypes(existing.getAuthorizedGrantTypes());
    }
    if (details.getRegisteredRedirectUri() == null || details.getRegisteredRedirectUri().isEmpty()) {
        details.setRegisteredRedirectUri(existing.getRegisteredRedirectUri());
    }
    if (details.getResourceIds() == null || details.getResourceIds().isEmpty()) {
        details.setResourceIds(existing.getResourceIds());
    }
    if (details.getScope() == null || details.getScope().isEmpty()) {
        details.setScope(existing.getScope());
    }

    Map<String, Object> additionalInformation = new HashMap<String, Object>(
            existing.getAdditionalInformation());
    additionalInformation.putAll(input.getAdditionalInformation());
    for (String key : Collections.unmodifiableSet(additionalInformation.keySet())) {
        if (additionalInformation.get(key) == null) {
            additionalInformation.remove(key);
        }
    }
    details.setAdditionalInformation(additionalInformation);

    return details;
}

From source file:org.cloudfoundry.identity.uaa.client.ClientAdminEndpointsValidator.java

public ClientDetails validate(ClientDetails prototype, boolean create, boolean checkAdmin)
        throws InvalidClientDetailsException {

    BaseClientDetails client = new BaseClientDetails(prototype);
    if (prototype instanceof BaseClientDetails) {
        Set<String> scopes = ((BaseClientDetails) prototype).getAutoApproveScopes();
        if (scopes != null) {
            client.setAutoApproveScopes(((BaseClientDetails) prototype).getAutoApproveScopes());
        }//from   ww w .  j  a  v  a  2s. com
    }

    client.setAdditionalInformation(prototype.getAdditionalInformation());

    String clientId = client.getClientId();
    if (create && reservedClientIds.contains(clientId)) {
        throw new InvalidClientDetailsException("Not allowed: " + clientId + " is a reserved client_id");
    }

    Set<String> requestedGrantTypes = client.getAuthorizedGrantTypes();

    if (requestedGrantTypes.isEmpty()) {
        throw new InvalidClientDetailsException(
                "An authorized grant type must be provided. Must be one of: " + VALID_GRANTS.toString());
    }
    checkRequestedGrantTypes(requestedGrantTypes);

    if ((requestedGrantTypes.contains("authorization_code") || requestedGrantTypes.contains("password"))
            && !requestedGrantTypes.contains("refresh_token")) {
        logger.debug("requested grant type missing refresh_token: " + clientId);

        requestedGrantTypes.add("refresh_token");
    }

    if (checkAdmin && !(securityContextAccessor.isAdmin()
            || securityContextAccessor.getScopes().contains("clients.admin"))) {

        // Not admin, so be strict with grant types and scopes
        for (String grant : requestedGrantTypes) {
            if (NON_ADMIN_INVALID_GRANTS.contains(grant)) {
                throw new InvalidClientDetailsException(
                        grant + " is not an allowed grant type for non-admin caller.");
            }
        }

        if (requestedGrantTypes.contains("implicit") && requestedGrantTypes.contains("authorization_code")) {
            throw new InvalidClientDetailsException(
                    "Not allowed: implicit grant type is not allowed together with authorization_code");
        }

        String callerId = securityContextAccessor.getClientId();
        ClientDetails caller = null;
        try {
            caller = clientDetailsService.retrieve(callerId);
        } catch (Exception e) {
            // best effort to get the caller, but the caller might not belong to this zone.
        }
        if (callerId != null && caller != null) {

            // New scopes are allowed if they are for the caller or the new
            // client.
            String callerPrefix = callerId + ".";
            String clientPrefix = clientId + ".";

            Set<String> validScope = caller.getScope();
            for (String scope : client.getScope()) {
                if (scope.startsWith(callerPrefix) || scope.startsWith(clientPrefix)) {
                    // Allowed
                    continue;
                }
                if (!validScope.contains(scope)) {
                    throw new InvalidClientDetailsException(scope + " is not an allowed scope for caller="
                            + callerId + ". Must have prefix in [" + callerPrefix + "," + clientPrefix
                            + "] or be one of: " + validScope.toString());
                }
            }

        } else {
            // New scopes are allowed if they are for the caller or the new
            // client.
            String clientPrefix = clientId + ".";

            for (String scope : client.getScope()) {
                if (!scope.startsWith(clientPrefix)) {
                    throw new InvalidClientDetailsException(
                            scope + " is not an allowed scope for null caller and client_id=" + clientId
                                    + ". Must start with '" + clientPrefix + "'");
                }
            }
        }

        Set<String> validAuthorities = new HashSet<String>(NON_ADMIN_VALID_AUTHORITIES);
        if (requestedGrantTypes.contains("client_credentials")) {
            // If client_credentials is used then the client might be a
            // resource server
            validAuthorities.add("uaa.resource");
        }

        for (String authority : AuthorityUtils.authorityListToSet(client.getAuthorities())) {
            if (!validAuthorities.contains(authority)) {
                throw new InvalidClientDetailsException(authority + " is not an allowed authority for caller="
                        + callerId + ". Must be one of: " + validAuthorities.toString());
            }
        }

    }

    if (client.getAuthorities().isEmpty()) {
        client.setAuthorities(AuthorityUtils.commaSeparatedStringToAuthorityList("uaa.none"));
    }

    // The UAA does not allow or require resource ids to be registered
    // because they are determined dynamically
    client.setResourceIds(Collections.singleton("none"));

    if (client.getScope().isEmpty()) {
        client.setScope(Collections.singleton("uaa.none"));
    }

    if (requestedGrantTypes.contains("implicit")) {
        if (StringUtils.hasText(client.getClientSecret())) {
            throw new InvalidClientDetailsException("Implicit grant should not have a client_secret");
        }
    }
    if (create) {
        // Only check for missing secret if client is being created.
        if ((requestedGrantTypes.contains("client_credentials")
                || requestedGrantTypes.contains("authorization_code"))
                && !StringUtils.hasText(client.getClientSecret())) {
            throw new InvalidClientDetailsException(
                    "Client secret is required for client_credentials and authorization_code grant types");
        }
    }

    return client;

}

From source file:org.cloudfoundry.identity.uaa.oauth.ClientAdminBootstrap.java

/**
 * Explicitly override autoapprove in all clients that were provided in the
 * whitelist./*from ww  w .j a v a2 s  . c om*/
 */
private void updateAutoApprovClients() {

    List<ClientDetails> clients = clientRegistrationService.listClientDetails();

    for (ClientDetails client : clients) {
        if (!autoApproveClients.contains(client.getClientId())) {
            continue;
        }
        BaseClientDetails base = new BaseClientDetails(client);
        Map<String, Object> info = new HashMap<String, Object>(client.getAdditionalInformation());
        info.put("autoapprove", true);
        base.setAdditionalInformation(info);
        logger.debug("Adding autoapprove flag: " + base);
        clientRegistrationService.updateClientDetails(base);
    }

}

From source file:org.cloudfoundry.identity.uaa.oauth.ClientAdminBootstrap.java

private void addNewClients() throws Exception {
    for (String clientId : clients.keySet()) {
        Map<String, Object> map = clients.get(clientId);
        BaseClientDetails client = new BaseClientDetails(clientId, (String) map.get("resource-ids"),
                (String) map.get("scope"), (String) map.get("authorized-grant-types"),
                (String) map.get("authorities"), (String) map.get("redirect-uri"));
        client.setClientSecret((String) map.get("secret"));
        Integer validity = (Integer) map.get("access-token-validity");
        Boolean override = (Boolean) map.get("override");
        if (override == null) {
            override = defaultOverride;/*from   w ww  .j  av a2s .com*/
        }
        Map<String, Object> info = new HashMap<String, Object>(map);
        if (validity != null) {
            client.setAccessTokenValiditySeconds(validity);
        }
        validity = (Integer) map.get("refresh-token-validity");
        if (validity != null) {
            client.setRefreshTokenValiditySeconds(validity);
        }
        // UAA does not use the resource ids in client registrations
        client.setResourceIds(Collections.singleton("none"));
        if (client.getScope().isEmpty()) {
            client.setScope(Collections.singleton("uaa.none"));
        }
        if (client.getAuthorities().isEmpty()) {
            client.setAuthorities(Collections.singleton(UaaAuthority.UAA_NONE));
        }
        if (client.getAuthorizedGrantTypes().contains("authorization_code")) {
            client.getAuthorizedGrantTypes().add("refresh_token");
        }
        for (String key : Arrays.asList("resource-ids", "scope", "authorized-grant-types", "authorities",
                "redirect-uri", "secret", "id", "override", "access-token-validity",
                "refresh-token-validity")) {
            info.remove(key);
        }
        client.setAdditionalInformation(info);
        try {
            clientRegistrationService.addClientDetails(client);
        } catch (ClientAlreadyExistsException e) {
            if (override == null || override) {
                logger.debug("Overriding client details for " + clientId);
                clientRegistrationService.updateClientDetails(client);
                if (StringUtils.hasText(client.getClientSecret())) {
                    clientRegistrationService.updateClientSecret(clientId, client.getClientSecret());
                }
            } else {
                // ignore it
                logger.debug(e.getMessage());
            }
        }
    }
}

From source file:org.cloudfoundry.identity.uaa.oauth.ClientAdminEndpoints.java

private ClientDetails validateClient(ClientDetails prototype, boolean create) {

    BaseClientDetails client = new BaseClientDetails(prototype);

    client.setAdditionalInformation(prototype.getAdditionalInformation());

    String clientId = client.getClientId();
    if (create && reservedClientIds.contains(clientId)) {
        throw new InvalidClientDetailsException("Not allowed: " + clientId + " is a reserved client_id");
    }//  ww  w .  j av  a 2  s  .co  m

    Set<String> requestedGrantTypes = client.getAuthorizedGrantTypes();

    if (requestedGrantTypes.isEmpty()) {
        throw new InvalidClientDetailsException(
                "An authorized grant type must be provided. Must be one of: " + VALID_GRANTS.toString());
    }
    for (String grant : requestedGrantTypes) {
        if (!VALID_GRANTS.contains(grant)) {
            throw new InvalidClientDetailsException(
                    grant + " is not an allowed grant type. Must be one of: " + VALID_GRANTS.toString());
        }
    }

    if ((requestedGrantTypes.contains("authorization_code") || requestedGrantTypes.contains("password"))
            && !requestedGrantTypes.contains("refresh_token")) {
        logger.debug("requested grant type missing refresh_token: " + clientId);

        requestedGrantTypes.add("refresh_token");
    }

    if (!securityContextAccessor.isAdmin()) {

        // Not admin, so be strict with grant types and scopes
        for (String grant : requestedGrantTypes) {
            if (NON_ADMIN_INVALID_GRANTS.contains(grant)) {
                throw new InvalidClientDetailsException(
                        grant + " is not an allowed grant type for non-admin caller.");
            }
        }

        if (requestedGrantTypes.contains("implicit") && requestedGrantTypes.contains("authorization_code")) {
            throw new InvalidClientDetailsException(
                    "Not allowed: implicit grant type is not allowed together with authorization_code");
        }

        String callerId = securityContextAccessor.getClientId();
        if (callerId != null) {

            // New scopes are allowed if they are for the caller or the new
            // client.
            String callerPrefix = callerId + ".";
            String clientPrefix = clientId + ".";

            ClientDetails caller = clientDetailsService.retrieve(callerId);
            Set<String> validScope = caller.getScope();
            for (String scope : client.getScope()) {
                if (scope.startsWith(callerPrefix) || scope.startsWith(clientPrefix)) {
                    // Allowed
                    continue;
                }
                if (!validScope.contains(scope)) {
                    throw new InvalidClientDetailsException(scope + " is not an allowed scope for caller="
                            + callerId + ". Must have prefix in [" + callerPrefix + "," + clientPrefix
                            + "] or be one of: " + validScope.toString());
                }
            }

        } else { // No client caller. Shouldn't happen in practice, but let's
                 // be defensive

            // New scopes are allowed if they are for the caller or the new
            // client.
            String clientPrefix = clientId + ".";

            for (String scope : client.getScope()) {
                if (!scope.startsWith(clientPrefix)) {
                    throw new InvalidClientDetailsException(
                            scope + " is not an allowed scope for null caller and client_id=" + clientId
                                    + ". Must start with '" + clientPrefix + "'");
                }
            }
        }

        Set<String> validAuthorities = new HashSet<String>(NON_ADMIN_VALID_AUTHORITIES);
        if (requestedGrantTypes.contains("client_credentials")) {
            // If client_credentials is used then the client might be a
            // resource server
            validAuthorities.add("uaa.resource");
        }

        for (String authority : AuthorityUtils.authorityListToSet(client.getAuthorities())) {
            if (!validAuthorities.contains(authority)) {
                throw new InvalidClientDetailsException(authority + " is not an allowed authority for caller="
                        + callerId + ". Must be one of: " + validAuthorities.toString());
            }
        }

    }

    if (client.getAuthorities().isEmpty()) {
        client.setAuthorities(AuthorityUtils.commaSeparatedStringToAuthorityList("uaa.none"));
    }

    // The UAA does not allow or require resource ids to be registered
    // because they are determined dynamically
    client.setResourceIds(Collections.singleton("none"));

    if (client.getScope().isEmpty()) {
        client.setScope(Collections.singleton("uaa.none"));
    }

    if (requestedGrantTypes.contains("implicit")) {
        if (StringUtils.hasText(client.getClientSecret())) {
            throw new InvalidClientDetailsException("Implicit grant should not have a client_secret");
        }
    }
    if (create) {
        // Only check for missing secret if client is being created.
        if ((requestedGrantTypes.contains("client_credentials")
                || requestedGrantTypes.contains("authorization_code"))
                && !StringUtils.hasText(client.getClientSecret())) {
            throw new InvalidClientDetailsException(
                    "Client secret is required for client_credentials and authorization_code grant types");
        }
    }

    return client;

}

From source file:org.cloudfoundry.identity.uaa.oauth.ClientAdminEndpoints.java

private ClientDetails syncWithExisting(ClientDetails existing, ClientDetails input) {
    BaseClientDetails details = new BaseClientDetails(input);
    if (details.getAccessTokenValiditySeconds() == null) {
        details.setAccessTokenValiditySeconds(existing.getAccessTokenValiditySeconds());
    }/*from  w w  w  .  j a  v a2 s . c o  m*/
    if (details.getRefreshTokenValiditySeconds() == null) {
        details.setRefreshTokenValiditySeconds(existing.getRefreshTokenValiditySeconds());
    }
    if (details.getAuthorities() == null || details.getAuthorities().isEmpty()) {
        details.setAuthorities(existing.getAuthorities());
    }
    if (details.getAuthorizedGrantTypes() == null || details.getAuthorizedGrantTypes().isEmpty()) {
        details.setAuthorizedGrantTypes(existing.getAuthorizedGrantTypes());
    }
    if (details.getRegisteredRedirectUri() == null || details.getRegisteredRedirectUri().isEmpty()) {
        details.setRegisteredRedirectUri(existing.getRegisteredRedirectUri());
    }
    if (details.getResourceIds() == null || details.getResourceIds().isEmpty()) {
        details.setResourceIds(existing.getResourceIds());
    }
    if (details.getScope() == null || details.getScope().isEmpty()) {
        details.setScope(existing.getScope());
    }

    Map<String, Object> additionalInformation = new HashMap<String, Object>(
            existing.getAdditionalInformation());
    additionalInformation.putAll(input.getAdditionalInformation());
    for (String key : Collections.unmodifiableSet(additionalInformation.keySet())) {
        if (additionalInformation.get(key) == null) {
            additionalInformation.remove(key);
        }
    }
    details.setAdditionalInformation(additionalInformation);

    return details;
}

From source file:org.cloudfoundry.identity.uaa.oauth.ClientAdminEndpointsValidator.java

public ClientDetails validate(ClientDetails prototype, boolean create, boolean checkAdmin)
        throws InvalidClientDetailsException {

    BaseClientDetails client = new BaseClientDetails(prototype);
    if (prototype instanceof BaseClientDetails) {
        Set<String> scopes = ((BaseClientDetails) prototype).getAutoApproveScopes();
        if (scopes != null) {
            client.setAutoApproveScopes(((BaseClientDetails) prototype).getAutoApproveScopes());
        }//ww w  .  j a  v  a 2  s  .  com
    }

    client.setAdditionalInformation(prototype.getAdditionalInformation());

    String clientId = client.getClientId();
    if (create && reservedClientIds.contains(clientId)) {
        throw new InvalidClientDetailsException("Not allowed: " + clientId + " is a reserved client_id");
    }

    Set<String> requestedGrantTypes = client.getAuthorizedGrantTypes();

    if (requestedGrantTypes.isEmpty()) {
        throw new InvalidClientDetailsException(
                "An authorized grant type must be provided. Must be one of: " + VALID_GRANTS.toString());
    }
    for (String grant : requestedGrantTypes) {
        if (!VALID_GRANTS.contains(grant)) {
            throw new InvalidClientDetailsException(
                    grant + " is not an allowed grant type. Must be one of: " + VALID_GRANTS.toString());
        }
    }

    if ((requestedGrantTypes.contains("authorization_code") || requestedGrantTypes.contains("password"))
            && !requestedGrantTypes.contains("refresh_token")) {
        logger.debug("requested grant type missing refresh_token: " + clientId);

        requestedGrantTypes.add("refresh_token");
    }

    if (checkAdmin && !(securityContextAccessor.isAdmin() || UaaStringUtils
            .getStringsFromAuthorities(securityContextAccessor.getAuthorities()).contains("clients.admin"))) {

        // Not admin, so be strict with grant types and scopes
        for (String grant : requestedGrantTypes) {
            if (NON_ADMIN_INVALID_GRANTS.contains(grant)) {
                throw new InvalidClientDetailsException(
                        grant + " is not an allowed grant type for non-admin caller.");
            }
        }

        if (requestedGrantTypes.contains("implicit") && requestedGrantTypes.contains("authorization_code")) {
            throw new InvalidClientDetailsException(
                    "Not allowed: implicit grant type is not allowed together with authorization_code");
        }

        String callerId = securityContextAccessor.getClientId();
        ClientDetails caller = null;
        try {
            caller = clientDetailsService.retrieve(callerId);
        } catch (Exception e) {
            // best effort to get the caller, but the caller might not belong to this zone.
        }
        if (callerId != null && caller != null) {

            // New scopes are allowed if they are for the caller or the new
            // client.
            String callerPrefix = callerId + ".";
            String clientPrefix = clientId + ".";

            Set<String> validScope = caller.getScope();
            for (String scope : client.getScope()) {
                if (scope.startsWith(callerPrefix) || scope.startsWith(clientPrefix)) {
                    // Allowed
                    continue;
                }
                if (!validScope.contains(scope)) {
                    throw new InvalidClientDetailsException(scope + " is not an allowed scope for caller="
                            + callerId + ". Must have prefix in [" + callerPrefix + "," + clientPrefix
                            + "] or be one of: " + validScope.toString());
                }
            }

        } else {
            // New scopes are allowed if they are for the caller or the new
            // client.
            String clientPrefix = clientId + ".";

            for (String scope : client.getScope()) {
                if (!scope.startsWith(clientPrefix)) {
                    throw new InvalidClientDetailsException(
                            scope + " is not an allowed scope for null caller and client_id=" + clientId
                                    + ". Must start with '" + clientPrefix + "'");
                }
            }
        }

        Set<String> validAuthorities = new HashSet<String>(NON_ADMIN_VALID_AUTHORITIES);
        if (requestedGrantTypes.contains("client_credentials")) {
            // If client_credentials is used then the client might be a
            // resource server
            validAuthorities.add("uaa.resource");
        }

        for (String authority : AuthorityUtils.authorityListToSet(client.getAuthorities())) {
            if (!validAuthorities.contains(authority)) {
                throw new InvalidClientDetailsException(authority + " is not an allowed authority for caller="
                        + callerId + ". Must be one of: " + validAuthorities.toString());
            }
        }

    }

    if (client.getAuthorities().isEmpty()) {
        client.setAuthorities(AuthorityUtils.commaSeparatedStringToAuthorityList("uaa.none"));
    }

    // The UAA does not allow or require resource ids to be registered
    // because they are determined dynamically
    client.setResourceIds(Collections.singleton("none"));

    if (client.getScope().isEmpty()) {
        client.setScope(Collections.singleton("uaa.none"));
    }

    if (requestedGrantTypes.contains("implicit")) {
        if (StringUtils.hasText(client.getClientSecret())) {
            throw new InvalidClientDetailsException("Implicit grant should not have a client_secret");
        }
    }
    if (create) {
        // Only check for missing secret if client is being created.
        if ((requestedGrantTypes.contains("client_credentials")
                || requestedGrantTypes.contains("authorization_code"))
                && !StringUtils.hasText(client.getClientSecret())) {
            throw new InvalidClientDetailsException(
                    "Client secret is required for client_credentials and authorization_code grant types");
        }
    }

    return client;

}