use of org.opencastproject.urlsigning.common.Policy in project opencast by opencast.
the class GenericUrlSigningProviderTest method testSign.
@Test
public void testSign() throws UrlSigningException, ConfigurationException {
properties.put(GenericUrlSigningProvider.ID_PREFIX + ".1", KEY_ID);
properties.put(GenericUrlSigningProvider.URL_PREFIX + ".1", MATCHING_URI);
properties.put(GenericUrlSigningProvider.KEY_PREFIX + ".1", KEY);
properties.put(GenericUrlSigningProvider.ID_PREFIX + ".2", KEY_ID);
properties.put(GenericUrlSigningProvider.URL_PREFIX + ".2", RTMP_MATCHER);
properties.put(GenericUrlSigningProvider.KEY_PREFIX + ".2", KEY);
signer.updated(properties);
DateTime before = new DateTime(2020, 03, 01, 00, 46, 17, 0, DateTimeZone.UTC);
// Handles a policy without query parameters.
Policy withoutQuery = Policy.mkSimplePolicy(RESOURCE_PATH, before);
String result = signer.sign(withoutQuery);
logger.info(result);
assertEquals("http://www.opencast.org/path/to/resource.mp4?policy=eyJTdGF0ZW1lbnQiOnsiQ29uZGl0aW9uIjp7IkRhdGVMZXNzVGhhbiI6MTU4MzAyMzU3NzAwMH0sIlJlc291cmNlIjoiaHR0cDpcL1wvd3d3Lm9wZW5jYXN0Lm9yZ1wvcGF0aFwvdG9cL3Jlc291cmNlLm1wNCJ9fQ&keyId=theId&signature=5b45e678275e6bc7b06a579f7f42e9a7ea5c58f1da130701db532f121e363e98", result);
// Handles a policy with additional query parameters.
Policy withQuery = Policy.mkSimplePolicy(RESOURCE_PATH + "?queryparam=this", before);
result = signer.sign(withQuery);
logger.info(result);
assertEquals("http://www.opencast.org/path/to/resource.mp4?queryparam=this&policy=eyJTdGF0ZW1lbnQiOnsiQ29uZGl0aW9uIjp7IkRhdGVMZXNzVGhhbiI6MTU4MzAyMzU3NzAwMH0sIlJlc291cmNlIjoiaHR0cDpcL1wvd3d3Lm9wZW5jYXN0Lm9yZ1wvcGF0aFwvdG9cL3Jlc291cmNlLm1wND9xdWVyeXBhcmFtPXRoaXMifX0&keyId=theId&signature=0f9cab4393a5d0ebe2683124a92094c3ccf06ed07e87b8f60fa2bab3963bd462", result);
// Handles rtmp protocol
Policy withRtmp = Policy.mkSimplePolicy("rtmp://www.opencast.org/path/to/resource.mp4", before);
result = signer.sign(withRtmp);
logger.info(result);
assertEquals("rtmp://www.opencast.org/path/to/resource.mp4?policy=eyJTdGF0ZW1lbnQiOnsiQ29uZGl0aW9uIjp7IkRhdGVMZXNzVGhhbiI6MTU4MzAyMzU3NzAwMH0sIlJlc291cmNlIjoicnRtcDpcL1wvd3d3Lm9wZW5jYXN0Lm9yZ1wvcGF0aFwvdG9cL3Jlc291cmNlLm1wNCJ9fQ&keyId=theId&signature=0464d9672fa5cb62ed82e7a6c46db5552dcd76590cf11efa5ba5222f53f5bbaa", result);
}
use of org.opencastproject.urlsigning.common.Policy in project opencast by opencast.
the class UrlSigningFilterTest method testDeniedOnGone.
@Test
public void testDeniedOnGone() throws Exception {
String encryptionKeyId = "theKey";
String acceptedUrl = "http://accepted.com";
String acceptedKey = "ThisIsTheKey";
String acceptedIp = "10.0.0.1";
DateTime future = new DateTime(4749125399000L);
Policy policy = Policy.mkSimplePolicy(acceptedUrl, future);
String acceptedQueryString = ResourceRequestUtil.policyToResourceRequestQueryString(policy, encryptionKeyId, acceptedKey);
ResourceRequest acceptedRequest = new ResourceRequest();
acceptedRequest.setStatus(Status.Gone);
// Setup the Mock Url Signing Service
UrlSigningVerifier urlSigningVerifier = EasyMock.createMock(UrlSigningVerifier.class);
EasyMock.expect(urlSigningVerifier.verify(acceptedQueryString, acceptedIp, acceptedUrl, true)).andReturn(acceptedRequest);
EasyMock.replay(urlSigningVerifier);
UrlSigningFilter filter = new UrlSigningFilter();
filter.updated(matchAllProperties);
filter.setUrlSigningVerifier(urlSigningVerifier);
// Setup the Mock Request
HttpServletRequest request = EasyMock.createMock(HttpServletRequest.class);
EasyMock.expect(request.getMethod()).andStubReturn("GET");
EasyMock.expect(request.getRequestURL()).andStubReturn(new StringBuffer(acceptedUrl));
EasyMock.expect(request.getQueryString()).andStubReturn(acceptedQueryString);
EasyMock.expect(request.getRemoteAddr()).andStubReturn(acceptedIp);
EasyMock.replay(request);
HttpServletResponse response = EasyMock.createMock(HttpServletResponse.class);
// Setup the mock filter chain.
FilterChain chain = EasyMock.createMock(FilterChain.class);
EasyMock.replay(chain);
filter.doFilter(request, response, chain);
EasyMock.verify(chain);
}
use of org.opencastproject.urlsigning.common.Policy in project opencast by opencast.
the class ResourceRequestUtilTest method testAuthenticatePolicyMatchesSignature.
@Test
public void testAuthenticatePolicyMatchesSignature() throws Exception {
DateTime after = new DateTime(DateTimeZone.UTC);
after = after.minus(2 * 60 * 60 * 1000L);
DateTime before = new DateTime(DateTimeZone.UTC);
before = before.plus(2 * 60 * 60 * 1000L);
String nonMatchingResource = "http://other.com";
Policy nonMatchingPolicy = Policy.mkSimplePolicy(nonMatchingResource, before);
String matchingResource = "http://mh-allinone/";
Policy matchingPolicy = Policy.mkSimplePolicy(matchingResource, before);
String signature = PolicyUtils.getPolicySignature(matchingPolicy, key);
// Test non-existant encryption key is forbidden.
String wrongEncryptionKeyId = ResourceRequest.ENCRYPTION_ID_KEY + "=" + "WrongId" + "&" + ResourceRequest.POLICY_KEY + "=" + PolicyUtils.toBase64EncodedPolicy(matchingPolicy) + "&" + ResourceRequest.SIGNATURE_KEY + "=" + signature;
assertEquals(Status.Forbidden, ResourceRequestUtil.resourceRequestFromQueryString(wrongEncryptionKeyId, clientIp, matchingResource, properties, true).getStatus());
// Test non matching resource results is forbidden.
String nonMatching = ResourceRequest.ENCRYPTION_ID_KEY + "=organization&" + ResourceRequest.POLICY_KEY + "=" + PolicyUtils.toBase64EncodedPolicy(nonMatchingPolicy) + "&" + ResourceRequest.SIGNATURE_KEY + "=" + signature;
assertEquals(Status.Forbidden, ResourceRequestUtil.resourceRequestFromQueryString(nonMatching, clientIp, matchingResource, properties, true).getStatus());
// Test non-matching client ip results in forbidden.
Policy wrongClientPolicy = Policy.mkPolicyValidWithIP(matchingResource, before, "10.0.0.255");
String wrongClient = ResourceRequestUtil.policyToResourceRequestQueryString(wrongClientPolicy, keyId, key);
assertEquals(Status.Forbidden, ResourceRequestUtil.resourceRequestFromQueryString(wrongClient, clientIp, matchingResource, properties, true).getStatus());
// Test matching client ip results in ok.
Policy rightClientPolicy = Policy.mkPolicyValidWithIP(matchingResource, before, clientIp);
String rightClient = ResourceRequestUtil.policyToResourceRequestQueryString(rightClientPolicy, keyId, key);
assertEquals(Status.Ok, ResourceRequestUtil.resourceRequestFromQueryString(rightClient, clientIp, matchingResource, properties, true).getStatus());
// Test not yet DateGreaterThan results in gone
Policy wrongDateGreaterThanPolicy = Policy.mkPolicyValidFrom(matchingResource, before, before);
String wrongDateGreaterThan = ResourceRequestUtil.policyToResourceRequestQueryString(wrongDateGreaterThanPolicy, keyId, key);
assertEquals(Status.Gone, ResourceRequestUtil.resourceRequestFromQueryString(wrongDateGreaterThan, clientIp, matchingResource, properties, true).getStatus());
// Test after DateGreaterThan results in ok
Policy rightDateGreaterThanPolicy = Policy.mkPolicyValidFrom(matchingResource, before, after);
String rightDateGreaterThan = ResourceRequestUtil.policyToResourceRequestQueryString(rightDateGreaterThanPolicy, keyId, key);
assertEquals(Status.Ok, ResourceRequestUtil.resourceRequestFromQueryString(rightDateGreaterThan, clientIp, matchingResource, properties, true).getStatus());
// Test before DateLessThan results in gone
Policy wrongDateLessThanPolicy = Policy.mkSimplePolicy(matchingResource, after);
String wrongDateLessThan = ResourceRequestUtil.policyToResourceRequestQueryString(wrongDateLessThanPolicy, keyId, key);
assertEquals(Status.Gone, ResourceRequestUtil.resourceRequestFromQueryString(wrongDateLessThan, clientIp, matchingResource, properties, true).getStatus());
// Test matching results in ok.
String matching = ResourceRequest.ENCRYPTION_ID_KEY + "=" + keyId + "&" + ResourceRequest.POLICY_KEY + "=" + PolicyUtils.toBase64EncodedPolicy(matchingPolicy) + "&" + ResourceRequest.SIGNATURE_KEY + "=" + signature;
assertEquals(Status.Ok, ResourceRequestUtil.resourceRequestFromQueryString(matching, clientIp, matchingResource, properties, true).getStatus());
}
use of org.opencastproject.urlsigning.common.Policy in project opencast by opencast.
the class ResourceRequestUtilTest method testNonStrictResourceChecking.
@Test
public void testNonStrictResourceChecking() throws Exception {
DateTime before = new DateTime(DateTimeZone.UTC);
before = before.plus(2 * 60 * 60 * 1000L);
String hostname = "signed.host.com";
String path = "/path/to/resource";
String rtmpResource = "rtmp://" + hostname + path;
String httpResource = "http://" + hostname + path;
String portResource = "rtmp://" + hostname + ":8080" + path;
String differentHostnameResource = "rtmp://different.host.com" + path;
Policy differentScheme = Policy.mkSimplePolicy(rtmpResource, before);
String signature = PolicyUtils.getPolicySignature(differentScheme, key);
String differentSchemeQueryString = ResourceRequest.ENCRYPTION_ID_KEY + "=default&" + ResourceRequest.POLICY_KEY + "=" + PolicyUtils.toBase64EncodedPolicy(differentScheme) + "&" + ResourceRequest.SIGNATURE_KEY + "=" + signature;
assertEquals(Status.Ok, ResourceRequestUtil.resourceRequestFromQueryString(differentSchemeQueryString, clientIp, httpResource, properties, false).getStatus());
assertEquals(Status.Forbidden, ResourceRequestUtil.resourceRequestFromQueryString(differentSchemeQueryString, clientIp, httpResource, properties, true).getStatus());
assertEquals(Status.Ok, ResourceRequestUtil.resourceRequestFromQueryString(differentSchemeQueryString, clientIp, portResource, properties, false).getStatus());
assertEquals(Status.Forbidden, ResourceRequestUtil.resourceRequestFromQueryString(differentSchemeQueryString, clientIp, portResource, properties, true).getStatus());
assertEquals(Status.Ok, ResourceRequestUtil.resourceRequestFromQueryString(differentSchemeQueryString, clientIp, differentHostnameResource, properties, false).getStatus());
assertEquals(Status.Forbidden, ResourceRequestUtil.resourceRequestFromQueryString(differentSchemeQueryString, clientIp, differentHostnameResource, properties, true).getStatus());
}
use of org.opencastproject.urlsigning.common.Policy in project opencast by opencast.
the class ResourceRequestUtil method resourceRequestFromQueryString.
/**
* @param queryString
* The query string for this request to determine its validity.
* @param clientIp
* The IP of the client requesting the resource.
* @param resourceUri
* The base uri for the resource.
* @param encryptionKeys
* The available encryption key ids and their keys.
* @param strict
* If false it will only compare the path to the resource instead of the entire URL including scheme,
* hostname, port etc.
* @return ResourceRequest
*/
public static ResourceRequest resourceRequestFromQueryString(String queryString, String clientIp, String resourceUri, Properties encryptionKeys, boolean strict) {
ResourceRequest resourceRequest = new ResourceRequest();
List<NameValuePair> queryParameters = parseQueryString(queryString);
if (!getQueryStringParameters(resourceRequest, queryParameters)) {
return resourceRequest;
}
// Get the encryption key by its id.
String encryptionKey = encryptionKeys.getProperty(resourceRequest.getEncryptionKeyId());
if (StringUtils.isBlank(encryptionKey)) {
resourceRequest.setStatus(Status.Forbidden);
resourceRequest.setRejectionReason(String.format("Forbidden because unable to find an encryption key with ID '%s'.", resourceRequest.getEncryptionKeyId()));
return resourceRequest;
}
// Get Policy
Policy policy = PolicyUtils.fromBase64EncodedPolicy(resourceRequest.getEncodedPolicy());
resourceRequest.setPolicy(policy);
// return a Forbidden 403.
if (!policyMatchesSignature(policy, resourceRequest.getSignature(), encryptionKey)) {
resourceRequest.setStatus(Status.Forbidden);
try {
String policySignature = PolicyUtils.getPolicySignature(policy, encryptionKey);
resourceRequest.setRejectionReason(String.format("Forbidden because policy and signature do not match. Policy: '%s' created Signature from this policy '%s' and query string Signature: '%s'.", PolicyUtils.toJson(resourceRequest.getPolicy()).toJSONString(), policySignature, resourceRequest.getSignature()));
} catch (Exception e) {
resourceRequest.setRejectionReason(String.format("Forbidden because policy and signature do not match. Policy: '%s' and query string Signature: '%s'. Unable to sign policy because: %s", PolicyUtils.toJson(resourceRequest.getPolicy()).toJSONString(), resourceRequest.getSignature(), ExceptionUtils.getStackTrace(e)));
}
return resourceRequest;
}
// If the IP address is specified, check it against the requestor's ip, if it doesn't match return a Forbidden 403.
if (policy.getClientIpAddress().isPresent() && !policy.getClientIpAddress().get().getHostAddress().equalsIgnoreCase(clientIp)) {
resourceRequest.setStatus(Status.Forbidden);
resourceRequest.setRejectionReason(String.format("Forbidden because client trying to access the resource '%s' doesn't match the policy client '%s'", clientIp, resourceRequest.getPolicy().getClientIpAddress()));
return resourceRequest;
}
// If the resource value in the policy doesn't match the requested resource return a Forbidden 403.
if (strict && !policy.getResource().equals(resourceUri)) {
resourceRequest.setStatus(Status.Forbidden);
resourceRequest.setRejectionReason(String.format("Forbidden because resource trying to be accessed '%s' doesn't match policy resource '%s'", resourceUri, resourceRequest.getPolicy().getBaseUrl()));
return resourceRequest;
} else if (!strict) {
try {
String requestedPath = new URI(resourceUri).getPath();
String policyPath = new URI(policy.getResource()).getPath();
if (!policyPath.endsWith(requestedPath)) {
resourceRequest.setStatus(Status.Forbidden);
resourceRequest.setRejectionReason(String.format("Forbidden because resource trying to be accessed '%s' doesn't match policy resource '%s'", resourceUri, resourceRequest.getPolicy().getBaseUrl()));
return resourceRequest;
}
} catch (URISyntaxException e) {
resourceRequest.setStatus(Status.Forbidden);
resourceRequest.setRejectionReason(String.format("Forbidden because either the policy or requested URI cannot be parsed. Policy Path: '%s' and Request Path: '%s'. Unable to sign policy because: %s", policy.getResource(), resourceUri, ExceptionUtils.getStackTrace(e)));
return resourceRequest;
}
}
// value of 410.
if (new DateTime(DateTimeZone.UTC).isAfter(policy.getValidUntil().getMillis())) {
resourceRequest.setStatus(Status.Gone);
resourceRequest.setRejectionReason(String.format("The resource is gone because now '%s' is after the expiry time of '%s'", humanReadableFormat.print(new DateTime(DateTimeZone.UTC)), humanReadableFormat.print(new DateTime(policy.getValidUntil().getMillis(), DateTimeZone.UTC))));
return resourceRequest;
}
if (policy.getValidFrom().isPresent() && new DateTime(DateTimeZone.UTC).isBefore(policy.getValidFrom().get().getMillis())) {
resourceRequest.setStatus(Status.Gone);
resourceRequest.setRejectionReason(String.format("The resource is gone because now '%s' is before the available time of ", humanReadableFormat.print(new DateTime(DateTimeZone.UTC)), humanReadableFormat.print(policy.getValidFrom().get())));
return resourceRequest;
}
// If all of the above conditions pass, then allow the video to be played.
resourceRequest.setStatus(Status.Ok);
return resourceRequest;
}
Aggregations