jackrabbit-oak-issues mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From "Ian Boston (JIRA)" <j...@apache.org>
Subject [jira] [Commented] (OAK-6575) Provide a secure external URL to a DataStore binary.
Date Fri, 01 Sep 2017 07:35:00 GMT

    [ https://issues.apache.org/jira/browse/OAK-6575?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=16150168#comment-16150168

Ian Boston commented on OAK-6575:

Could you share the use case that creates a requirement for Sling or AEM to programmatically
decide between a CloudFrontSignedBinary and a S3SignedBinary and explicitly request one or
the other from Oak ?

The initial PoC introduced a new SignedBinary API to do the same as you sugest. After discussion
internally, rapidly moved to oak-dev it was proposed that URI or URL was used. The reasoning
behind this proposal was not fully exposed so I will share my view here:
1. Exposing APIs specific to each DS implementation would require that code in Sling or AEM
binds to all possible DS implementations which is undesirable.
2. Not adding new APIs became a requirement for this patch.
3. The DS implementation bundle should decide decide what type of signed URL, if any, can
be emitted on a binary by binary basis.
4. A deployer should be able to select which signed URL implementations are active, and possibly
which signed URLs are emitted based on path or properties of the binary.
5. The class that is emitted should cover all types of URI, not just URLs.

For this reason the discussions on oak-dev reached consensus on emitting a URI rather than
a new API interface implementation.

Initially I thought that was not the right decision, but the more I think about it, the code
in Sling or AEM only needs a URI and should not be forced to learn about the implementation
details of the selected datastore.

The current patch allows a DS implementation to implement many AdapterFactories, each one
capable of being configured to be active, and capable of emitting a signed URL on a case by
case basis. Code in Sling or AEM does not need to know what type of singed URL is available,
and must not be allowed to override a deployer in making that decision. For instance, a deployer
using CloudFront will typically not allow direct access to the S3 buckets when using CloudFront
shielding the S3 buckets from public access. Hence a deployer would only configure the CloudFront
AdapterFactory to be active ensuring that Oak could not be coerced by Sling or AEM code to
emit the wrong signed URL potentially deployment driven security policy.

There is one alternative implementation pattern that was briefly discussed and rejected. Each
DS implementation implement its own ServletFilter that when active performs a http redirect
for request to Binary values that should be redirected. This would be completely internal
to the DS implementation with no need for any OakConversionService or AdapterFactory pattern.
This was rejected as it would require teh DS implementations to bind to the Sling Resource
API in order to correctly resolve the OakValue.

So to recap.
the URI pattern emitted from a configurable AdapterFactory implementation which may emit a
null is adaption to its type of signed url supports the use case where there may be many implementations
of an external URI, signed or otherwise, by many DS implementations. It does this without
introducing new APIs and without exposing implementation details of any DS.

If you think there is some aspect of the use case that has not been considered, could you
detail that use case for consideration.

> Provide a secure external URL to a DataStore binary.
> ----------------------------------------------------
>                 Key: OAK-6575
>                 URL: https://issues.apache.org/jira/browse/OAK-6575
>             Project: Jackrabbit Oak
>          Issue Type: New Feature
>          Components: blob, core, jcr
>            Reporter: Ian Boston
>             Fix For: 1.8
> Where the DataStore is a DataStore that may be accessed over an independent API it would
be advantageous for Oak to provide a secure URL to allow direct, read only access to the current
immutable instance of that binary.  The term "secure" needs to be defined, but typically it
would a URL that is valid for a appropriately short length of time to ensure that the risk
of the URL being used by a user that it was not intended for, is minimised. It should also
ensure that anyone in possession of the URL could not use the information in the url to create
a valid URL or a valid URL to a different binary.
> One example of such a URL might be a AWS Signed URL as used by AWS CloudFront to access
private content. The signed url being signed by a private key known only to the Oak instance
and the the CloudFront or S3 instance. The signed url having a significantly low ttl so that
a redirect by the same client would work.  
> Oak should only emit these URLs to sessions that could otherwise read the binary directly
from Oak, and Oak should be in complete control of the nature of the url and the security
mechanisms applied to the URL.
> The viability of the approach has been investigated showing that given a JCR Binary it
is possible to get the Oak Blob Content Identifier using ValueImpl.getBlob((Value)jcrBinary).getContentIentifier()
and form there, knowing the way in which the DataStore implementation transforms that into
a pointer into the datastore implementation form a URL to be made secure.
> To achieve the above, internal implementation details specific to the Oak DataStore implementation
are required, hence this request to implement as a part of Oak rather than to reverse engineer
in some external project.
> Since API changes are often significant using the Sling AdapaterFactory approach would
allow a ServletFilter to selectively use the URL in a redirect, avoiding any new API methods
to existing Oak APIs. A new interface might be required, in the example below that interface
is SignedBinaryURL.
> {code}
> public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse,
FilterChain filterChain) throws IOException, ServletException {
>         if ( servletRequest instanceof SlingHttpServletRequest  && servletResponse
instanceof SlingHttpServletResponse) {
>             if ("GET".equals(((SlingHttpServletRequest) servletRequest).getMethod())){
>                 Resource resource = ((SlingHttpServletRequest) servletRequest).getResource();
>                 SignedBinaryURL url = resource.adaptTo(SignedBinaryURL.class);
>                 if (url != null) {
>                     ((SlingHttpServletResponse) servletResponse).sendRedirect(url.getURL());
>                     return;
>                 }
>             }
>         }
>         filterChain.doFilter(servletRequest, servletResponse);
>     }
> {code}
> If the AdapterFactory to go from Binary to SingedBinaryURL is not present then url will
always be null, and no-op. If it is present, and Oak decides no URL is appropriate, then no-op.
> Only if the Oak DS implementation being used supports the external URL and Oak decides
it is appropriate, will a url be available and a redirect performed.
> I have used AWS S3 URLs as an example, however the approach should be applicable (and
pluggable) to most REST based APIs to private binary content.

This message was sent by Atlassian JIRA

View raw message