use of org.forgerock.openidconnect.Client in project OpenAM by OpenRock.
the class ClientCredentialsReader method extractCredentials.
/**
* Extracts the client's credentials from the OAuth2 request.
*
* @param request The OAuth2 request.
* @param endpoint The endpoint this request should be for, or null to disable audience verification.
* @return The client's credentials.
* @throws InvalidRequestException If the request contains multiple client credentials.
* @throws InvalidClientException If the request does not contain the client's id.
*/
public ClientCredentials extractCredentials(OAuth2Request request, String endpoint) throws InvalidRequestException, InvalidClientException, NotFoundException {
final Request req = request.getRequest();
boolean basicAuth = false;
if (req.getChallengeResponse() != null) {
basicAuth = true;
}
final ClientCredentials client;
Client.TokenEndpointAuthMethod method = CLIENT_SECRET_POST;
//jwt type first
if (JWT_PROFILE_CLIENT_ASSERTION_TYPE.equalsIgnoreCase(request.<String>getParameter(CLIENT_ASSERTION_TYPE))) {
client = verifyJwtBearer(request, basicAuth, endpoint);
method = PRIVATE_KEY_JWT;
} else {
String clientId = request.getParameter(OAuth2Constants.Params.CLIENT_ID);
String clientSecret = request.getParameter(OAuth2Constants.Params.CLIENT_SECRET);
if (basicAuth && clientId != null) {
logger.error("Client (" + clientId + ") using multiple authentication methods");
throw new InvalidRequestException("Client authentication failed");
}
if (req.getChallengeResponse() != null) {
final ChallengeResponse challengeResponse = req.getChallengeResponse();
clientId = challengeResponse.getIdentifier();
clientSecret = "";
if (challengeResponse.getSecret() != null && challengeResponse.getSecret().length > 0) {
clientSecret = String.valueOf(req.getChallengeResponse().getSecret());
}
method = CLIENT_SECRET_BASIC;
}
if (clientId == null || clientId.isEmpty()) {
logger.error("Client Id is not set");
throw failureFactory.getException(request, "Client authentication failed");
}
client = new ClientCredentials(clientId, clientSecret == null ? null : clientSecret.toCharArray(), false, basicAuth);
}
final OpenIdConnectClientRegistration cr = clientRegistrationStore.get(client.getClientId(), request);
final Set<String> scopes = cr.getAllowedScopes();
//if we're accessing the token endpoint, check we're authenticating using the appropriate method
if (scopes.contains(OAuth2Constants.Params.OPENID) && req.getResourceRef().getLastSegment().equals(OAuth2Constants.Params.ACCESS_TOKEN) && !cr.getTokenEndpointAuthMethod().equals(method.getType())) {
throw failureFactory.getException(request, "Invalid authentication method for accessing this endpoint.");
}
return client;
}
use of org.forgerock.openidconnect.Client in project OpenAM by OpenRock.
the class OpenAMClientDAO method read.
/**
* {@inheritDoc}
*/
public Client read(String clientId, OAuth2Request request) throws UnauthorizedClientException {
Map<String, Set<String>> clientAttributes = new HashMap<String, Set<String>>();
try {
AMIdentity theID = null;
final SSOToken token = AccessController.doPrivileged(AdminTokenAction.getInstance());
final String realm = request.getParameter(OAuth2Constants.Custom.REALM);
AMIdentityRepository repo = idRepoFactory.create(realm, token);
IdSearchControl idsc = new IdSearchControl();
idsc.setRecursive(true);
idsc.setAllReturnAttributes(true);
// search for the identity
Set<AMIdentity> results;
idsc.setMaxResults(0);
IdSearchResults searchResults = repo.searchIdentities(IdType.AGENTONLY, clientId, idsc);
results = searchResults.getSearchResults();
if (results == null || results.size() != 1) {
logger.error("OpenAMClientDAO.read(): No client profile or more than one profile found.");
throw new UnauthorizedClientException("Not able to get client from OpenAM");
}
theID = results.iterator().next();
//if the client is deactivated return null
if (!theID.isActive()) {
theID = null;
} else {
clientAttributes = theID.getAttributes();
}
} catch (UnauthorizedClientException e) {
logger.error("OpenAMClientDAO.read(): Unable to get client AMIdentity: ", e);
throw new UnauthorizedClientException("Not able to get client from OpenAM");
} catch (SSOException e) {
logger.error("OpenAMClientDAO.read(): Unable to get client AMIdentity: ", e);
throw new UnauthorizedClientException("Not able to get client from OpenAM");
} catch (IdRepoException e) {
logger.error("OpenAMClientDAO.read(): Unable to get client AMIdentity: ", e);
throw new UnauthorizedClientException("Not able to get client from OpenAM");
}
Client client = createClient(clientAttributes);
client.setClientID(clientId);
return client;
}
use of org.forgerock.openidconnect.Client in project OpenAM by OpenRock.
the class OpenAMResourceOwnerSessionValidator method getMaxAge.
/**
* Returns the max_age, set either as a client default (if enabled) or by request in ms, or -1 if not used.
*/
private long getMaxAge(OAuth2Request request) throws URISyntaxException, AccessDeniedException, ServerException, NotFoundException, EncodingException, UnauthorizedClientException, ResourceOwnerAuthenticationRequired, SSOException, ParseException, InvalidClientAuthZHeaderException, InvalidClientException, InvalidRequestException {
final ClientCredentials clientCredentials = clientCredentialsReader.extractCredentials(request, null);
final String maxAgeStr = request.getParameter(MAX_AGE);
long maxAge = -1;
if (maxAgeStr != null) {
//max_age is in seconds
maxAge = Long.valueOf(maxAgeStr);
if (maxAge < MIN_DEFAULT_MAX_AGE) {
//default to the minimum default to avoid infinite redirects
maxAge = MIN_DEFAULT_MAX_AGE;
}
} else {
//default_max_age is also in seconds
Client client = clientDAO.read(clientCredentials.getClientId(), request);
if (client.getDefaultMaxAgeEnabled()) {
maxAge = client.getDefaultMaxAge();
}
}
//return as ms
return maxAge * 1000;
}
use of org.forgerock.openidconnect.Client in project OpenAM by OpenRock.
the class OpenAMOpenIdConnectClientRegistrationService method createRegistration.
/**
* {@inheritDoc}
*/
public JsonValue createRegistration(String accessToken, String deploymentUrl, OAuth2Request request) throws InvalidRedirectUri, InvalidClientMetadata, ServerException, UnsupportedResponseTypeException, AccessDeniedException, NotFoundException, InvalidPostLogoutRedirectUri {
final OAuth2ProviderSettings providerSettings = providerSettingsFactory.get(request);
if (!providerSettings.isOpenDynamicClientRegistrationAllowed()) {
if (!tokenVerifier.verify(request).isValid()) {
throw new AccessDeniedException("Access Token not valid");
}
}
final JsonValue input = request.getBody();
//check input to ensure it is valid
Set<String> inputKeys = input.keys();
for (String key : inputKeys) {
OAuth2Constants.ShortClientAttributeNames keyName = fromString(key);
if (keyName == null) {
logger.warn("Unknown input given. Key: " + key);
}
}
//create client given input
ClientBuilder clientBuilder = new ClientBuilder();
try {
boolean jwks = false;
if (input.get(JWKS.getType()).asString() != null) {
jwks = true;
try {
JsonValueBuilder.toJsonValue(input.get(JWKS.getType()).asString());
} catch (JsonException e) {
throw new InvalidClientMetadata("jwks must be valid JSON.");
}
clientBuilder.setJwks(input.get(JWKS.getType()).asString());
clientBuilder.setPublicKeySelector(Client.PublicKeySelector.JWKS.getType());
}
if (input.get(JWKS_URI.getType()).asString() != null) {
if (jwks) {
//allowed to set either jwks or jwks_uri but not both
throw new InvalidClientMetadata("Must define either jwks or jwks_uri, not both.");
}
jwks = true;
try {
new URL(input.get(JWKS_URI.getType()).asString());
} catch (MalformedURLException e) {
throw new InvalidClientMetadata("jwks_uri must be a valid URL.");
}
clientBuilder.setJwksUri(input.get(JWKS_URI.getType()).asString());
clientBuilder.setPublicKeySelector(Client.PublicKeySelector.JWKS_URI.getType());
}
//not spec-defined, this is OpenAM proprietary
if (input.get(X509.getType()).asString() != null) {
clientBuilder.setX509(input.get(X509.getType()).asString());
}
//drop to this if neither other are set
if (!jwks) {
clientBuilder.setPublicKeySelector(Client.PublicKeySelector.X509.getType());
}
if (input.get(TOKEN_ENDPOINT_AUTH_METHOD.getType()).asString() != null) {
if (Client.TokenEndpointAuthMethod.fromString(input.get(TOKEN_ENDPOINT_AUTH_METHOD.getType()).asString()) == null) {
logger.error("Invalid token_endpoint_auth_method requested.");
throw new InvalidClientMetadata("Invalid token_endpoint_auth_method requested.");
}
clientBuilder.setTokenEndpointAuthMethod(input.get(TOKEN_ENDPOINT_AUTH_METHOD.getType()).asString());
} else {
clientBuilder.setTokenEndpointAuthMethod(Client.TokenEndpointAuthMethod.CLIENT_SECRET_BASIC.getType());
}
if (input.get(CLIENT_ID.getType()).asString() != null) {
clientBuilder.setClientID(input.get(CLIENT_ID.getType()).asString());
} else {
clientBuilder.setClientID(UUID.randomUUID().toString());
}
if (input.get(CLIENT_SECRET.getType()).asString() != null) {
clientBuilder.setClientSecret(input.get(CLIENT_SECRET.getType()).asString());
} else {
clientBuilder.setClientSecret(UUID.randomUUID().toString());
}
if (input.get(CLIENT_TYPE.getType()).asString() != null) {
if (Client.ClientType.fromString(input.get(CLIENT_TYPE.getType()).asString()) != null) {
clientBuilder.setClientType(input.get(CLIENT_TYPE.getType()).asString());
} else {
logger.error("Invalid client_type requested.");
throw new InvalidClientMetadata("Invalid client_type requested");
}
} else {
clientBuilder.setClientType(Client.ClientType.CONFIDENTIAL.getType());
}
if (input.get(DEFAULT_MAX_AGE.getType()).asLong() != null) {
clientBuilder.setDefaultMaxAge(input.get(DEFAULT_MAX_AGE.getType()).asLong());
clientBuilder.setDefaultMaxAgeEnabled(true);
} else {
clientBuilder.setDefaultMaxAge(Client.MIN_DEFAULT_MAX_AGE);
clientBuilder.setDefaultMaxAgeEnabled(false);
}
List<String> redirectUris = new ArrayList<String>();
if (input.get(REDIRECT_URIS.getType()).asList() != null) {
redirectUris = input.get(REDIRECT_URIS.getType()).asList(String.class);
boolean isValidUris = true;
for (String redirectUri : redirectUris) {
try {
urlValidator.validate(redirectUri);
} catch (ValidationException e) {
isValidUris = false;
logger.error("The redirectUri: " + redirectUri + " is invalid.");
}
}
if (!isValidUris) {
throw new InvalidRedirectUri();
}
clientBuilder.setRedirectionURIs(redirectUris);
}
if (input.get(SECTOR_IDENTIFIER_URI.getType()).asString() != null) {
try {
URL sectorIdentifier = new URL(input.get(SECTOR_IDENTIFIER_URI.getType()).asString());
List<String> response = mapper.readValue(sectorIdentifier, List.class);
if (!response.containsAll(redirectUris)) {
logger.error("Request_uris not included in sector_identifier_uri.");
throw new InvalidClientMetadata();
}
} catch (Exception e) {
logger.error("Invalid sector_identifier_uri requested.");
throw new InvalidClientMetadata("Invalid sector_identifier_uri requested.");
}
clientBuilder.setSectorIdentifierUri(input.get(SECTOR_IDENTIFIER_URI.getType()).asString());
}
List<String> scopes = input.get(SCOPES.getType()).asList(String.class);
if (scopes != null && !scopes.isEmpty()) {
if (!containsAllCaseInsensitive(providerSettings.getSupportedScopes(), scopes)) {
logger.error("Invalid scopes requested.");
throw new InvalidClientMetadata("Invalid scopes requested");
}
} else {
//if nothing requested, fall back to provider defaults
scopes = new ArrayList<String>();
scopes.addAll(providerSettings.getDefaultScopes());
}
//regardless, we add openid
if (!scopes.contains(OPENID)) {
scopes = new ArrayList<String>(scopes);
scopes.add(OPENID);
}
clientBuilder.setAllowedGrantScopes(scopes);
List<String> defaultScopes = input.get(DEFAULT_SCOPES.getType()).asList(String.class);
if (defaultScopes != null) {
if (containsAllCaseInsensitive(providerSettings.getSupportedScopes(), defaultScopes)) {
clientBuilder.setDefaultGrantScopes(defaultScopes);
} else {
throw new InvalidClientMetadata("Invalid default scopes requested.");
}
}
List<String> clientNames = new ArrayList<String>();
Set<String> keys = input.keys();
for (String key : keys) {
if (key.equals(CLIENT_NAME.getType())) {
clientNames.add(input.get(key).asString());
} else if (key.startsWith(CLIENT_NAME.getType())) {
try {
Locale locale = new Locale(key.substring(CLIENT_NAME.getType().length() + 1));
clientNames.add(locale.toString() + "|" + input.get(key).asString());
} catch (Exception e) {
logger.error("Invalid locale for client_name.");
throw new InvalidClientMetadata("Invalid locale for client_name.");
}
}
}
if (clientNames != null) {
clientBuilder.setClientName(clientNames);
}
if (input.get(CLIENT_DESCRIPTION.getType()).asList() != null) {
clientBuilder.setDisplayDescription(input.get(CLIENT_DESCRIPTION.getType()).asList(String.class));
}
if (input.get(SUBJECT_TYPE.getType()).asString() != null) {
if (providerSettings.getSupportedSubjectTypes().contains(input.get(SUBJECT_TYPE.getType()).asString())) {
clientBuilder.setSubjectType(input.get(SUBJECT_TYPE.getType()).asString());
} else {
logger.error("Invalid subject_type requested.");
throw new InvalidClientMetadata("Invalid subject_type requested");
}
} else {
clientBuilder.setSubjectType(Client.SubjectType.PUBLIC.getType());
}
if (input.get(ID_TOKEN_SIGNED_RESPONSE_ALG.getType()).asString() != null) {
if (containsCaseInsensitive(providerSettings.getSupportedIDTokenSigningAlgorithms(), input.get(ID_TOKEN_SIGNED_RESPONSE_ALG.getType()).asString())) {
clientBuilder.setIdTokenSignedResponseAlgorithm(input.get(ID_TOKEN_SIGNED_RESPONSE_ALG.getType()).asString());
} else {
logger.error("Unsupported id_token_response_signed_alg requested.");
throw new InvalidClientMetadata("Unsupported id_token_response_signed_alg requested.");
}
} else {
clientBuilder.setIdTokenSignedResponseAlgorithm(ID_TOKEN_SIGNED_RESPONSE_ALG_DEFAULT);
}
if (input.get(POST_LOGOUT_REDIRECT_URIS.getType()).asList() != null) {
List<String> logoutRedirectUris = input.get(POST_LOGOUT_REDIRECT_URIS.getType()).asList(String.class);
boolean isValidUris = true;
for (String logoutRedirectUri : logoutRedirectUris) {
try {
urlValidator.validate(logoutRedirectUri);
} catch (ValidationException e) {
isValidUris = false;
logger.error("The post_logout_redirect_uris: {} is invalid.", logoutRedirectUri);
}
}
if (!isValidUris) {
throw new InvalidPostLogoutRedirectUri();
}
clientBuilder.setPostLogoutRedirectionURIs(logoutRedirectUris);
}
if (input.get(REGISTRATION_ACCESS_TOKEN.getType()).asString() != null) {
clientBuilder.setAccessToken(input.get(REGISTRATION_ACCESS_TOKEN.getType()).asString());
} else {
clientBuilder.setAccessToken(accessToken);
}
if (input.get(CLIENT_SESSION_URI.getType()).asString() != null) {
clientBuilder.setClientSessionURI(input.get(CLIENT_SESSION_URI.getType()).asString());
}
if (input.get(APPLICATION_TYPE.getType()).asString() != null) {
if (Client.ApplicationType.fromString(input.get(APPLICATION_TYPE.getType()).asString()) != null) {
clientBuilder.setApplicationType(Client.ApplicationType.WEB.getType());
} else {
logger.error("Invalid application_type requested.");
throw new InvalidClientMetadata("Invalid application_type requested.");
}
} else {
clientBuilder.setApplicationType(DEFAULT_APPLICATION_TYPE);
}
if (input.get(DISPLAY_NAME.getType()).asList() != null) {
clientBuilder.setDisplayName(input.get(DISPLAY_NAME.getType()).asList(String.class));
}
if (input.get(RESPONSE_TYPES.getType()).asList() != null) {
final List<String> clientResponseTypeList = input.get(RESPONSE_TYPES.getType()).asList(String.class);
final List<String> typeList = new ArrayList<String>();
for (String responseType : clientResponseTypeList) {
typeList.addAll(Arrays.asList(responseType.split(" ")));
}
if (containsAllCaseInsensitive(providerSettings.getAllowedResponseTypes().keySet(), typeList)) {
clientBuilder.setResponseTypes(clientResponseTypeList);
} else {
logger.error("Invalid response_types requested.");
throw new InvalidClientMetadata("Invalid response_types requested.");
}
} else {
List<String> defaultResponseTypes = new ArrayList<String>();
defaultResponseTypes.add("code");
clientBuilder.setResponseTypes(defaultResponseTypes);
}
if (input.get(AUTHORIZATION_CODE_LIFE_TIME.getType()).asLong() != null) {
clientBuilder.setAuthorizationCodeLifeTime(input.get(AUTHORIZATION_CODE_LIFE_TIME.getType()).asLong());
} else {
clientBuilder.setAuthorizationCodeLifeTime(0L);
}
if (input.get(ACCESS_TOKEN_LIFE_TIME.getType()).asLong() != null) {
clientBuilder.setAccessTokenLifeTime(input.get(ACCESS_TOKEN_LIFE_TIME.getType()).asLong());
} else {
clientBuilder.setAccessTokenLifeTime(0L);
}
if (input.get(REFRESH_TOKEN_LIFE_TIME.getType()).asLong() != null) {
clientBuilder.setRefreshTokenLifeTime(input.get(REFRESH_TOKEN_LIFE_TIME.getType()).asLong());
} else {
clientBuilder.setRefreshTokenLifeTime(0L);
}
if (input.get(JWT_TOKEN_LIFE_TIME.getType()).asLong() != null) {
clientBuilder.setJwtTokenLifeTime(input.get(JWT_TOKEN_LIFE_TIME.getType()).asLong());
} else {
clientBuilder.setJwtTokenLifeTime(0L);
}
if (input.get(CONTACTS.getType()).asList() != null) {
clientBuilder.setContacts(input.get(CONTACTS.getType()).asList(String.class));
}
} catch (JsonValueException e) {
logger.error("Unable to build client.", e);
throw new InvalidClientMetadata();
}
Client client = clientBuilder.createClient();
// See OPENAM-3604 and http://openid.net/specs/openid-connect-registration-1_0.html#ClientRegistration
if (providerSettings.isRegistrationAccessTokenGenerationEnabled() && !client.hasAccessToken()) {
client.setAccessToken(createRegistrationAccessToken(client, request));
}
clientDAO.create(client, request);
// have some visibility on who is registering clients.
if (logger.isInfoEnabled()) {
logger.info("Registered OpenID Connect client: " + client.getClientID() + ", name=" + client.getClientName() + ", type=" + client.getClientType());
}
Map<String, Object> response = client.asMap();
response = convertClientReadResponseFormat(response);
response.put(REGISTRATION_CLIENT_URI, deploymentUrl + "/oauth2/connect/register?client_id=" + client.getClientID());
response.put(EXPIRES_AT, 0);
return new JsonValue(response);
}
use of org.forgerock.openidconnect.Client in project OpenAM by OpenRock.
the class OpenAMOpenIdConnectClientRegistrationService method getRegistration.
/**
* {@inheritDoc}
*/
public JsonValue getRegistration(String clientId, String accessToken, OAuth2Request request) throws InvalidRequestException, InvalidClientMetadata, InvalidTokenException {
if (clientId != null) {
final Client client;
try {
client = clientDAO.read(clientId, request);
} catch (UnauthorizedClientException e) {
logger.error("ConnectClientRegistration.Validate(): Unable to create client", e);
throw new InvalidClientMetadata();
}
if (!client.getAccessToken().equals(accessToken)) {
//client access token doesn't match the access token supplied in the request
logger.error("ConnectClientRegistration.getClient(): Invalid accessToken");
throw new InvalidTokenException();
}
//remove the client fields that don't need to be reported.
client.remove(REGISTRATION_ACCESS_TOKEN.getType());
final JsonValue response = new JsonValue(convertClientReadResponseFormat(client.asMap()));
response.put(EXPIRES_AT, 0);
return response;
} else {
logger.error("ConnectClientRegistration.readRequest(): No client id sent");
throw new InvalidRequestException();
}
}
Aggregations