Skip to content

Commit

Permalink
Adding changes to the Caching mechanism to support any object type
Browse files Browse the repository at this point in the history
  • Loading branch information
rnavagamuwa committed Mar 26, 2019
1 parent f650377 commit 914eb69
Show file tree
Hide file tree
Showing 6 changed files with 119 additions and 38 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
import org.springframework.util.ResourceUtils;
import org.springframework.web.client.RestTemplate;
import org.springframework.ws.transport.http.HttpComponentsMessageSender;
import org.wso2.spring.security.abac.cache.Cache;
import org.wso2.spring.security.abac.cache.CacheManager;
import org.wso2.spring.security.abac.cache.EhCacheManager;
import org.wso2.spring.security.abac.exception.AttributeEvaluatorException;
Expand All @@ -36,6 +37,7 @@
import java.io.InputStream;
import java.security.KeyStore;
import java.util.ArrayList;
import java.util.Base64;
import java.util.Collections;
import java.util.List;
import java.util.Optional;
Expand All @@ -58,13 +60,16 @@ public class XacmlAttributeHandler implements AttributeHandler {
private static String KEY_STORE_PASSWORD;
private static String CERT_ALIAS;

private CacheManager responseCacheManager;
private SSLContext sslContext;
private HttpHeaders restHeaders;
private List<Header> soapHeaders;
private CustomSSLHttpClientFactory customSSLHttpClientFactory;
private EntitlementServiceClient entitlementServiceClient;

private Cache<String, String> authCache;
private Cache<String, JAXBElement<EntitledResultSetDTO>> entitlementServiceCache;
private Cache<String, JSONObject> apiResourceListCache;

public XacmlAttributeHandler() {

try {
Expand Down Expand Up @@ -111,7 +116,10 @@ public XacmlAttributeHandler() {
//todo use mutual SSL
soapHeaders.add(new BasicHeader("Authorization", "Basic YWRtaW46YWRtaW4="));

this.responseCacheManager = new EhCacheManager();
CacheManager cacheManager = EhCacheManager.getInstance();
this.authCache = cacheManager.getCache("authCache", String.class, String.class, 60, 100);
this.entitlementServiceCache = cacheManager.getCache("entitlementCache", String.class, JAXBElement.class, 60, 100);
this.apiResourceListCache = cacheManager.getCache("apiResourceList", String.class, JSONObject.class, 60, 100);

Jaxb2Marshaller marshaller = new Jaxb2Marshaller();
marshaller.setContextPath("org.wso2.spring.security.abac.soaputils.wsdl");
Expand Down Expand Up @@ -142,7 +150,7 @@ public XacmlAttributeHandler() {
@Override
public boolean authorize(String authRequest) {

String cachedResponse = this.responseCacheManager.get(authRequest);
String cachedResponse = this.authCache.get(authRequest);

if (cachedResponse == null) {

Expand All @@ -161,7 +169,7 @@ public boolean authorize(String authRequest) {
return false;
}
cachedResponse = response.getBody().toString();
this.responseCacheManager.putIfAbsent(authRequest, cachedResponse);
this.authCache.putIfAbsent(authRequest, cachedResponse);
}

JSONObject responseObj = new JSONObject(cachedResponse);
Expand All @@ -183,39 +191,56 @@ public boolean authorize(String authRequest) {
@Override
public Optional<JSONObject> getApiResourceList() {

String cachedResponse = this.responseCacheManager.get(XACML_PDP_RESOURCE_LIST_URL);
JSONObject cachedObject = this.apiResourceListCache.get(XACML_PDP_RESOURCE_LIST_URL);

if (cachedResponse == null) {
if (cachedObject != null) {

HttpClient client = HttpClients.custom()
.setSSLContext(sslContext)
.build();
return Optional.of(cachedObject);
}

RestTemplateBuilder restTemplateBuilder = new RestTemplateBuilder().requestFactory(() ->
new HttpComponentsClientHttpRequestFactory(client));
RestTemplate rt = restTemplateBuilder.build();
HttpClient client = HttpClients.custom()
.setSSLContext(sslContext)
.build();

HttpEntity<String> entity = new HttpEntity<>(this.restHeaders);
RestTemplateBuilder restTemplateBuilder = new RestTemplateBuilder().requestFactory(() ->
new HttpComponentsClientHttpRequestFactory(client));
RestTemplate rt = restTemplateBuilder.build();

ResponseEntity response = rt.getForEntity(XACML_PDP_RESOURCE_LIST_URL, String.class, entity);
HttpEntity<String> entity = new HttpEntity<>(this.restHeaders);

if (response.getStatusCode() != HttpStatus.OK || response.getBody() == null) {
ResponseEntity response = rt.getForEntity(XACML_PDP_RESOURCE_LIST_URL, String.class, entity);

return Optional.empty();
}
cachedResponse = response.getBody().toString();
this.responseCacheManager.putIfAbsent(XACML_PDP_RESOURCE_LIST_URL, cachedResponse);
if (response.getStatusCode() != HttpStatus.OK || response.getBody() == null) {

return Optional.empty();
}
return Optional.of(new JSONObject(cachedResponse));

return Optional.of(this.apiResourceListCache.putIfAbsent(XACML_PDP_RESOURCE_LIST_URL,
new JSONObject(response.getBody().toString())));

}

@Override
public JAXBElement<EntitledResultSetDTO> getEntitledAttributes(String subjectName, String resourceName,
String subjectId, String action,
boolean enableChildSearch) {

return this.entitlementServiceClient.
getEntitledAttributes(subjectName, resourceName, subjectId, action, enableChildSearch).getReturn();
String key = Base64
.getEncoder()
.encodeToString(subjectName
.concat(resourceName)
.concat(subjectId)
.concat(action)
.concat(String.valueOf(enableChildSearch)).getBytes());

JAXBElement<EntitledResultSetDTO> resultSet = this.entitlementServiceCache.get(key);

if (resultSet != null) {
return resultSet;
}

return this.entitlementServiceCache.putIfAbsent(key, this.entitlementServiceClient.
getEntitledAttributes(subjectName, resourceName, subjectId, action, enableChildSearch).getReturn());

}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,14 @@
import org.springframework.util.ResourceUtils;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import org.wso2.spring.security.abac.cache.Cache;
import org.wso2.spring.security.abac.cache.EhCacheManager;
import org.wso2.spring.security.abac.exception.AttributeEvaluatorException;

import java.io.IOException;
import java.io.StringWriter;
import java.nio.charset.StandardCharsets;
import java.util.Base64;
import java.util.Iterator;
import javax.servlet.http.HttpServletRequest;

Expand All @@ -24,9 +27,25 @@ public class XacmlAuthRequestBuilder implements AuthRequestBuilder {

private static String ATTRIBUTE_CONFIG_FILE_NAME = "xacmlConfig.json";

private Cache<String, String> requestBuilderCache;

public XacmlAuthRequestBuilder() {

this.requestBuilderCache = EhCacheManager.getInstance().getCache("requestBuilderCache",
String.class, String.class, 60, 100);
}

@Override
public String createAuthRequest(String policyName, String jsonKeyValuePairs) {

String key = Base64.getEncoder().encodeToString(policyName.concat(jsonKeyValuePairs).trim().getBytes());

String cachedRequest = this.requestBuilderCache.get(key);

if (cachedRequest != null) {
return cachedRequest;
}

VelocityContext vc = generateVelocityData(jsonKeyValuePairs);

String xacmlRequest;
Expand Down Expand Up @@ -57,7 +76,7 @@ public String createAuthRequest(String policyName, String jsonKeyValuePairs) {
policyName);
}

return xacmlRequest;
return this.requestBuilderCache.putIfAbsent(key, xacmlRequest);
}

private VelocityContext generateVelocityData(String jsonKeyValuePairs) {
Expand Down
11 changes: 11 additions & 0 deletions sdk/src/main/java/org/wso2/spring/security/abac/cache/Cache.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package org.wso2.spring.security.abac.cache;

/**
* @author Randika Navagamuwa
*/
public interface Cache<K, V> {

V get(K key);

V putIfAbsent(K key, V value);
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,5 @@
*/
public interface CacheManager {

String get(String cahceKey);

String putIfAbsent(String key, String value);
Cache getCache(String cacheName, Class<?> key, Class<?> value, long expiryInMuntues, long maxEntries);
}
31 changes: 31 additions & 0 deletions sdk/src/main/java/org/wso2/spring/security/abac/cache/EhCache.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
package org.wso2.spring.security.abac.cache;

/**
* @author Randika Navagamuwa
*/
public class EhCache implements Cache {

private org.ehcache.Cache cache;

public EhCache(org.ehcache.Cache cache) {

this.cache = cache;
}

public org.ehcache.Cache getCache() {

return this.cache;
}

@Override
public Object get(Object key) {

return this.cache.get(key);
}

@Override
public Object putIfAbsent(Object key, Object value) {

return this.cache.putIfAbsent(key, value);
}
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
package org.wso2.spring.security.abac.cache;

import org.ehcache.Cache;
import org.ehcache.CacheManager;
import org.ehcache.config.builders.CacheConfigurationBuilder;
import org.ehcache.config.builders.CacheManagerBuilder;
Expand All @@ -14,31 +13,29 @@
*/
public class EhCacheManager implements org.wso2.spring.security.abac.cache.CacheManager {

private static String CACHE_NAME = "policyRequestCache";
private static long EXPIRY_IN_MINUTUES = 60;
private static long MAX_ENTRIES = 100;

private CacheManager cacheManager;
private Cache<String, String> cache;

public EhCacheManager() {
private EhCacheManager() {

cacheManager = CacheManagerBuilder.newCacheManagerBuilder().build();
cacheManager.init();

cache = cacheManager.createCache(CACHE_NAME, CacheConfigurationBuilder
.newCacheConfigurationBuilder(String.class, String.class, ResourcePoolsBuilder.heap(MAX_ENTRIES))
.withExpiry(ExpiryPolicyBuilder.timeToLiveExpiration(Duration.ofMinutes(EXPIRY_IN_MINUTUES)))
.build());
}

public String get(String cahceKey) {
public static org.wso2.spring.security.abac.cache.CacheManager getInstance() {

return this.cache.get(cahceKey);
return new EhCacheManager();
}

public String putIfAbsent(String key, String value) {
@Override
public Cache getCache(String cacheName, Class<?> key, Class<?> value, long expiryInMuntues, long maxEntries) {

return this.cache.putIfAbsent(key, value);
return new EhCache(cacheManager.createCache(cacheName, CacheConfigurationBuilder
.newCacheConfigurationBuilder(key, value, ResourcePoolsBuilder.heap(maxEntries))
.withExpiry(ExpiryPolicyBuilder.timeToLiveExpiration(Duration.ofMinutes(expiryInMuntues)))
.build()));
}
}

0 comments on commit 914eb69

Please sign in to comment.