
org.xlcloud.iam.DecisionResourceClient Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of iam-utils Show documentation
Show all versions of iam-utils Show documentation
This module is provides set of base IAM utilities.
The newest version!
/*
* Copyright 2012 AMG.lab, a Bull Group Company
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.xlcloud.iam;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.Reader;
import java.io.StringWriter;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
import javax.annotation.PostConstruct;
import javax.inject.Inject;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang.StringUtils;
import org.apache.log4j.Logger;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import org.json.JSONTokener;
import org.xlcloud.config.ConfigParam;
import org.xlcloud.iam.Decision.DecisionAnswer;
import org.xlcloud.logging.LoggingUtils;
import com.sun.jersey.api.client.Client;
import com.sun.jersey.api.client.ClientResponse;
import com.sun.jersey.api.client.WebResource;
/**
* Calls OpenAM's decision service in order to determine the access permission
*
* @author Jakub Wachowski, AMG.net
*
*/
public class DecisionResourceClient {
private final Logger LOG = Logger.getLogger(DecisionResourceClient.class);
@Inject
@IamRestClient
private Client client;
public static final String DECISION_SERVICE_URL = IamUtils.getOpenAmUrl() + "/ws/1/entitlement/entitlement";
public static final String QUERY_PARAM_REALM = "realm";
public static final String QUERY_PARAM_APPLICATION = "application";
public static final String QUERY_PARAM_RESOURCE = "resource";
public static final String ACCEPT_AUTHN_HEADER = "X-Accept-Authentication";
public static final String QUERY_PARAMS_HEADER = "X-Query-Parameters";
public static final String AUTHN_SCHEMA = "oauth";
public static final String AUTHZ_SCHEMA = "oauth";
public static final String AUTHZ_SCHEMA_SEPARATOR = ":";
private static final String REASON_ATTRIBUTE_KEY = "reason";
private static final String REASON_RESTRICTED_VALUE = "restricted";
private static final String DETAIL_ATTRIBUTE_KEY = "details";
@Inject
@ConfigParam
private String xlcRealmName;
private String decisionServiceUrl = DECISION_SERVICE_URL;
@PostConstruct
public void init() {
LOG.debug("Using Jersey client " + client.hashCode());
}
/**
* Determines whether a given token is allowed to access given resource with given method
* @param accessToken OAuth2's access token
* @param method http method (GET, POST, DELETE or PUT)
* @param resource resource for which access decision is to be made
* @return true if given access token is allowed to access the resource, false otherwise
*/
public Decision isAllowed(String accessToken, String method, String resource) {
if (LOG.isDebugEnabled()) {
LOG.debug("evaluating access for token=[" + LoggingUtils.maskPartially(accessToken) + "], method=[" + method + "], resource=["
+ LoggingUtils.maskResource(resource) + "]");
}
WebResource webResource = client.resource(decisionServiceUrl)
.queryParam(QUERY_PARAM_REALM, xlcRealmName)
.queryParam(QUERY_PARAM_APPLICATION, IamUtils.REST_SERVICE_NAME)
.queryParam(QUERY_PARAM_RESOURCE, resource);
ClientResponse clientResponse = webResource.header(ACCEPT_AUTHN_HEADER, AUTHN_SCHEMA)
.header(QUERY_PARAMS_HEADER, AUTHZ_SCHEMA + AUTHZ_SCHEMA_SEPARATOR + accessToken)
.get(ClientResponse.class);
Decision decision;
if(clientResponse.getStatus() == 200) {
decision = getDecision(clientResponse, method);
} else {
String responseBody = null;
try {
StringWriter writer = new StringWriter();
IOUtils.copy(clientResponse.getEntityInputStream(), writer, "UTF-8");
responseBody = writer.toString();
if (LOG.isDebugEnabled()) {
LOG.debug("Failed to validate entitlements, status code: " + clientResponse.getStatus() + ", response: " + responseBody);
}
} catch (IOException e) {
LOG.error(e.getMessage(), e);
}
decision = new Decision(DecisionAnswer.FAILED, "Received response with status code " + clientResponse.getStatus()
+ (responseBody != null ? ": " + responseBody : ""));
}
if (LOG.isDebugEnabled()) {
LOG.debug("access for token=[" + LoggingUtils.maskPartially(accessToken) + "], method=[" + method + "], resource=["
+ LoggingUtils.maskResource(resource) + "] is " + decision);
}
return decision;
}
private Decision getDecision(ClientResponse clientResponse, String method) {
try {
boolean answer = false;
Map> attrs = new HashMap<>();
Reader reader = new InputStreamReader(clientResponse.getEntityInputStream());
JSONTokener tokener = new JSONTokener(reader);
JSONObject root = new JSONObject(tokener);
JSONObject body = root.getJSONObject("body");
JSONObject actionsValues = body.getJSONObject("actionsValues");
if (!actionsValues.isNull(method)) {
answer = actionsValues.getBoolean(method);
}
JSONObject attributes = body.getJSONObject("attributes");
@SuppressWarnings( "unchecked" )
Iterator attrIt = attributes.keys();
while (attrIt.hasNext()) {
String key = attrIt.next();
Set values = new HashSet();
JSONArray vals = (JSONArray) attributes.get(key);
for (int i = 0; i < vals.length(); i++) {
values.add(vals.getString(i));
}
attrs.put(key, values);
}
if (answer) {
return new Decision(DecisionAnswer.ALLOW);
}
if (attrs.get(REASON_ATTRIBUTE_KEY) != null && attrs.get(REASON_ATTRIBUTE_KEY).contains(REASON_RESTRICTED_VALUE)) {
String details = null;
if (attrs.containsKey(DETAIL_ATTRIBUTE_KEY)) {
details = StringUtils.join(attrs.get(DETAIL_ATTRIBUTE_KEY).toArray(),';');
}
return new Decision(DecisionAnswer.RESTRICTED,details);
}
return new Decision(DecisionAnswer.DENY);
} catch (JSONException e) {
return new Decision(DecisionAnswer.FAILED);
}
}
/**
* Gets the value of {@link #decisionServiceUrl}.
* @return value of {@link #decisionServiceUrl}
*/
public String getDecisionServiceUrl() {
return decisionServiceUrl;
}
/**
* Sets the value of {@link #decisionServiceUrl}.
* @param decisionServiceUrl - value
*/
public void setDecisionServiceUrl(String decisionServiceUrl) {
this.decisionServiceUrl = decisionServiceUrl;
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy