Closed benjamingeer closed 5 years ago
we could implement it by not allowing direct access to Sipi, but only through Knora which will then talk to Sipi. Basically, create an authorization proxy route.
But that would still require an extra HTTP request (and triplestore query) per image, which is what we have already. The only difference would be the order of the requests: client -> Knora -> Sipi instead of the current client -> Sipi -> Knora.
After the token expires (10 minutes or so), the tokens would need to be refreshed somehow. We need a per image authorization route anyway. The question is who is going to do the refreshing.
If we use the IIIF Authorization API then the client (IIIF viewer) needs to implement this feature, which if they have implemented the Authorization API they should have already done so.
Let's assume viewers work with appended JWT tokens to the image URL, then the viewer will work for 10 minutes (or whatever the lifetime of the token is). After that, the whole page needs to be refreshed so that all image URLs with fresh tokens can be requested.
In case 1 only those tokens will be refreshed (and also initially requested), for images that are actually viewed. In case 2 all image tokens need to be refreshed every single time.
I think that case 1 is going to generating less traffic.
This is not clear to me yet. In the case of (1), how does the viewer get the token representing the user's permissions on the image? And how does it send that token to Sipi? Or do you mean that in (1), no token is involved, and we use cookies instead?
in case (1) the viewer would go to the authentication endpoint specified in the manifest file to get the token and then use this token to access Sipi. Since we apparently can set a different authentication endpoint for each image, we can generate a token with permissions specific to each image.
Now the most important thing is that the viewer handles token expiration, i.e. re-authenticates itself for every image when the token expires.
maybe a quick Skype call?
Yes, I’ll call you in 20 minutes or so.
So it looks like that using the IIIF Authentication API is not going to be trivial. After talking to @benjamingeer, we decided that the fastest way would be to use session cookies like in Salsah1.5
, and let Sipi ask Knora for the user's permissions for each requested image. Knora will cache this information so that the load on the triplestore should not be too high.
The implementation would involve changing V2
authentication to also create a session cookie. Then all HTML img
tag requests should automatically include this information when talking to Sipi.
@gfoo would this be alright with you for your February release?
I‘ve read the IIIF Authentication API spec and @benjamingeer you where right. Both cookies and tokens are used. Cookies for Content Resources (image) and tokens for Description Resources (info,json).
So our proposed first step of adding session creation to V2
authentication alongside token is completely in line with the IIIF spec.
So it means that I can use a Sipi image URL directly in the html img src
attribute if I use the v2 auth
endpoint (what I do actually) ?
Sipi and Knora being not the same server you are taking about Third-party cookies?
So it means that I can use a Sipi image URL directly in the html
img src
attribute if I use thev2 auth
endpoint (what I do actually) ?
Yes, that would be the goal.
Sipi and Knora being not the same server you are taking about Third-party cookies?
The Sipi and Knora API endpoint need to be under the same domain, e.g., api.example.com
and iiif.example.com
. This is how we already deploy.
The Sipi and Knora API endpoint need to be under the same domain
I thought the client had to log into Knora first, then log into Sipi, so Sipi could set a cookie containing the same session ID. Isn't this what the Sipi script Knora_login.lua
is for?
thought the client had to log into Knora first, then log into Sipi, so Sipi could set a cookie containing the same session ID. Isn't this what the Sipi script Knora_login.lua is for?
Not anymore. I changed it in November or so for V1
. The client only needs to login into Knora and the same cookie will then be used by Sipi.
The Knora_login.lua
and Knora_logout.lua
are not used anymore. The calls to those routes are commented out in Salsah1
.
OK great. In that case, could you please delete those scripts?
If somebody, for whatever reason, want's to have API on one domain and SIpi on another, then he would/could theoretically use those. But I don't think that we need to support this use case.
I will delete them.
@subotic : so the browser is supposed to automatically send the session cookie received from knora
to both knora
and sipi
? (if they are in the same domain)
Yes, exactly.
Just tested #1165 and it works fine (don't know if Sipi correctly use the cookies sent by the browser to check the permissions but I can now see correctly the Sipi images from my Angular app)
Sipi should already use it. It is the way the Salsah1.5
GUI is working.
Ok, it works from Salsah (dev stack) after having manually removed the cookie because logout seems to not do that, is something that I have to do (remove cookie) from my app when I logout from Knora using DELETE /v2/authentication
or is it the Knora's responsibility?
@gfoo , removing cookies is tricky as the http protocol defines only set-cookie
and no remove-cookie
. That leaves us with the only choice of override an existing cookie and changing the expiry date, but there is no guaranty that the browser will react as expected.
@subotic : I don't get the same result, using stock docker images dhlabbasel/webapi:4.0.0
and dhlabbasel/salsah1:4.0.0
, login into knora doesn't add the domain directive, I see:
set-cookie: KnoraAuthentication=[cookie]; Path=/
where I expected and additional ; Domain=.example.com
should I use another tag?
or is it the Knora's responsibility?
Yes, Knora should send the same cookie with the changed expire date. What I have found, is that with Safari I need to refresh the browser to see that the cookie was removed.
where I expected and additional ; Domain=.example.com
Good catch. This needs to be set. The current implementation wouldn't work in production.
where I expected and additional ; Domain=.example.com
Good catch. This needs to be set. The current implementation wouldn't work in production.
should be fixed in #1170
finally, not so sure that it works very well with Angular through their HttpClient, it worked a first time but not anymore :(
Cookies are a browser functionality. I don't think that it matters if Angular is used or not. Which browser are you using for testing? I find Safari better for the cookie stuff, as you can see the whole HTTP response header including the set-cookie header.
If you want to quickly test login/logout with Angular without dev env: https://stackblitz.com/edit/angular-ea4gsz
This seems to work. I had to download and run it locally, because of the blocked mixed content (stackblitz is https and localhost is http).
You could make another button to check with Knora: GET /v2/authentication
tries to authenticate the user and tells you the result.
I updated the project, I can see the Set-Cookie: KnoraAuthentication=eyJ...
in the response header by my browser definitely does not store the cookie.
I think that the cookie is there. Just to see it, you need to refresh the page.
It works now because I added withCredentials=true :| (updated stackblitz) Maybe it is related to #1170 ?
This is not related directly to Angular HttpClient but to XMLHttpRequest, see this test: https://gist.github.com/gfoo/6d9f449b55d4ae19fe8ecfcbfa1f70d8
For me, with or without withCredentials=true
makes a difference.
withCredentials=true
Ah, yes. Now that you mention it. I have fallen for this one in the past. We have this set in Salsah1
(https://github.com/dhlab-basel/Knora/blob/ac2c9bafc4d211f126660cbf10e9f8330b1cb614/salsah1/src/public/js/01_salsah_api.js#L60-L62)
Would it help to document that somewhere?
@kilchenmann For a future reference, don't forget to set withCredentials=true
, when dealing with cookies.
Would it help to document that somewhere?
It is, kinda: https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest/withCredentials ;-)
If someone writes it's own services, then this would be a thing that they should know. If they use our library, then this will be already set correctly.
Don't know if it is clear but I use http://0.0.0.0:3333
as Knora base url to get cookie working from my Angular app, but as related in #1174 and #1130 my Sipi container for an unknown reason cannot access to (no more true) I use container name in docker compose file.0.0.0.0
, so
Yes, this is how it should work locally.
Is this issue resolved? Can we close it?
yes, thanks.
The Knora API server can use JWT to authorise a user to upload files to Sipi, as well as to view files stored in Sipi.
Parts:
1165
1166
1169