[Seaside] A session-aware kind of FileLibrary - how/where to start

Jupiter Jones jupiter.jones at mail.com
Thu Apr 1 20:39:36 UTC 2021


Hi Joachim,

Not sure why email clients think my messages are spam… I’m starting to think it’s personal :) That said, today I’m getting bounces back from the seaside mailing list so I’m copying this to you directly since this may nott make it to the list.

> And I wonder if a separate WAFileHandler might decouple things a little more, like allowing for parallel execution of requests?

Yes and no :) If you’re deploying in GemStone and running multiple gems, you’ll get “effective" parallel execution for free and each gem will be able to lookup the _s key. If you’re deploying in Pharo, then you’ll need to save the _s keys (and any other information needed for validation) in a DB so that each Pharo instance can find them. This adds a layer of complexity and will likely negate any speed advantage gained through parallel execution.

All the solutions offered can work well. It really depends on the use case, production environment and scaling requirements. As Karsten mentioned,  typically in production you don’t want to serve files from the image - this doesn’t scale well, and becomes more problematic the larger the files. Rather you have nginx (or whatever http server you use) serve the files directly.

In that case, the FileLibrary is only providing urls, not serving content, so best to check user access before rendering the initial URL. This still doesn’t help if access security is the goal, since once the user has the URL, they can distribute it or use it anytime they like.

Another alternative that solves some of these issues, is having nginx validate file permissions via seaside when a file is accessed. This scales better since the image is only required to validate requests, and the http server delivers the file.

This also works if you want to validate files that aren’t in FileLibraries since it’s based on a url path, or if you want to allow WebDAV access so your users can mount a server directory on their desktop but still have fine-grain access control validated via seaside.

A example of how to perform a simple validation for a specific FileLibrary is something like:

nginx.conf:

upstream seaside_http {
	server localhost:8383;
}

location ~ /files/MyFileLibrary {
	auth_request /seasideAuth;
}

location = /seasideAuth {
	proxy_pass 				http://seaside_http/seasideAuth <http://seaside_http/seasideAuth>;
	proxy_pass_request_body 	off;
	proxy_set_header 			Content-Length 		"";
	proxy_set_header 			X-Original-URI 		$request_uri;
}

Then create a handler and register in seaside as ’seasideAuth'

WARequestHandler subclass: ‘NginxAuthRequestHandler’.
WAAdmin register: NginxAuthRequestHandler as: ’seasideAuth’.

The methods in NginxAuthRequestHandler would be something like:

handleFiltered: aRequestContext
	[  self handleAuthorisation: aRequestContext ]
		on: Error
		do: [ :ex | aRequestContext responseGenerator forbidden ]

handleAuthorisation: aRequestContext 
	self canAccessUri: (aRequestContext request headers at: ‘original-uri’).
		ifTrue: [ aRequestContext responseGenerator respond ]
		ifFalse: [ aRequestContext responseGenerator forbidden ]

canAccessUri: aUri
	“do whatever needed to confirm access”
	^ true

Again, this is incomplete, but you’ll get the idea. If you’re looking up sessions you’ll still need to add the _s key to the download url.

Cheers,

J

> On 1 Apr 2021, at 3:59 pm, jtuchel at objektfabrik.de wrote:
> 
> Jupiter,
> 
> 
> sorry for my late reply. For some reason, your answer was moved to my spam folder and I just found it there between lots of pharma and crypto tips...
> 
> While I see where you are headed with this, I wonder if there are differences between the approaches. I have the feeling a separate WAFileHandler might have the advantage of being more decoupled from the components that consume/refer/use files. And I wonder if a separate WAFileHandler might decouple things a little more, like allowing for parallel execution of requests?
> 
> Joachim
> 
> 
> 
> 
> 
> 
> 
> 
> Am 30.03.21 um 14:23 schrieb Jupiter Jones:
>> This may be a little left-field, but if you want a more integrated approach you could try something like:
>> 
>> 
>> renderContentOn: canvas
>> 	canvas anchor
>> 		url: (self fileAccessUtlFroFile: #restrictedAccessFile);
>> 		with: ‘Download'
>> 
>> 
>> fileAccessUrlForFile: fileIdentifier
>> 	^self renderContext actionUrl copy
>> 		addField:
>> 			(self renderContext callbacks
>> 				store: (WAActionCallback on: [ self processFileAccessCallbackForFile: fileIdentifier ]));
>> 		yourself.
>> 
>> 
>> processFileAccessCallbackForFile: fileIdentifier
>> 	(self session isUserAllowedToDownloadFile: fileIndeitifier) ifTrue: [
>> 		self requestContext response redirectTo: (self actualUrlForFile: fileIdentifier)
>> 	]
>> 
>> 
>> You could also serve the file directly in the response rather than #redirectTo: if you wanted added security.
>> 
>> The above is incomplete, but perhaps fits the brief.
>> 
>> Cheers,
>> 
>> Jupiter
>> 
>>> On 30 Mar 2021, at 8:18 pm, jtuchel at objektfabrik.de wrote:
>>> 
>>> Hi,
>>> 
>>> 
>>> There are situations in which I feel like after 10+ years of using Seaside, I am still a newbie. (well, same for Smalltalk after 25+ years, so this may be normal).
>>> 
>>> I would like to implement some kind of FileLibrary that is aware of the current session and only delivers files to logged-on users.
>>> 
>>> It seems like the best starting point for this is to subclass WARequestHandler and register it with WAAdmin. So the first thing I did was implement handleFiltered: aRequestContext. Unfortunately, neither aRequestContext nor self return a WASession, although I entered _s and _k form a logged in session into the address bar of my Browser. This may be a naive approach, but as a fist test case this seemed like a good idea ;-)
>>> 
>>> Now the question I ask myself is: how do I teach my WARequestHandler subclass the trick of knowing/finding the current session. Do I add some Filter? Is subclassing WARequestHandler the wrong idea anyways? (I started my experiments with a subclass of WAFileLibrary, but that also didn't get me anywhere...).
>>> 
>>> I am not asking for a ready-made solution. I'd rather try to understand a little more about Seasides innards here...
>>> 
>>> Any pointers? Kick-off ideas what to look at?
>>> 
>>> 
>>> tia,
>>> 
>>> 
>>> Joachim
>>> 
>>> 
>>> 
>>> 
>>> -- 
>>> -----------------------------------------------------------------------
>>> Objektfabrik Joachim Tuchel          mailto:jtuchel at objektfabrik.de
>>> Fliederweg 1                         http://www.objektfabrik.de
>>> D-71640 Ludwigsburg                  http://joachimtuchel.wordpress.com
>>> Telefon: +49 7141 56 10 86 0         Fax: +49 7141 56 10 86 1
>>> 
>>> 
>>> _______________________________________________
>>> seaside mailing list
>>> seaside at lists.squeakfoundation.org
>>> http://lists.squeakfoundation.org/cgi-bin/mailman/listinfo/seaside
>> _______________________________________________
>> seaside mailing list
>> seaside at lists.squeakfoundation.org
>> http://lists.squeakfoundation.org/cgi-bin/mailman/listinfo/seaside
> 
> 
> -- 
> -----------------------------------------------------------------------
> Objektfabrik Joachim Tuchel          mailto:jtuchel at objektfabrik.de
> Fliederweg 1                         http://www.objektfabrik.de
> D-71640 Ludwigsburg                  http://joachimtuchel.wordpress.com
> Telefon: +49 7141 56 10 86 0         Fax: +49 7141 56 10 86 1
> 
> 
> _______________________________________________
> seaside mailing list
> seaside at lists.squeakfoundation.org
> http://lists.squeakfoundation.org/cgi-bin/mailman/listinfo/seaside

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.squeakfoundation.org/pipermail/seaside/attachments/20210402/735a0444/attachment-0001.html>


More information about the seaside mailing list