I'm trying to build a Word add-on using the Office JS API that talks to an external web service (under my control).
I'm opening a dialog with ui.displayDialogAsync, which immediately redirects to the external server's login page (the redirect is to get around the same domain limitation).
When the user enters their login details correctly the server sends a session cookie back.
Unfortunately, in older versions of Word 2016, when the dialog is closed in Word, all session cookies are forgotten and any further requests sent to the web service from the add-on are rejected as no cookie is sent.
The problem exhibits itself in Volume licensed versions of Word 2016, but not in Office 365 versions of Word 2016, which seem to have a higher version / build number.
If I use Fiddler to view the requests / responses, I can see that the requests made from inside the dialog come from a different process ID to those made after the dialog closes.
I can't use persistent cookies for a combination of security reasons (once user closes the browser, the session needs to be terminated) and also persistent cookies seem to be shared with IE and we need to have independent sessions in IE and Word at the same time (some important state is stored in the cookie).
Has anyone else encountered this / know how to get around it.
The dialogs run in separate processes thats correct.
See for info: https://learn.microsoft.com/en-us/office/dev/add-ins/develop/dialog-api-in-office-add-ins
Note that:
"Store the information somewhere that is accessible to both the host window and dialog box. The two windows do not share a common session storage, but if they have the same domain (including port number, if any), they share a common local storage."
So option one: is to use local storage if you meet the requirements.
Option two: you could use a function called Office.context.ui.messageParent() to message your host (TaskPane) with a sessionId it needs to store and store it from the TaskPane
I see that starting with version 2107 build 14228.20250, dialogs opened from the Word desktop started sharing cookies with the sidebar automatically. I also checked it with Fiddler, now Word uses the same OS process to open a new dialog.
Related
I am working on a google chrome extension that takes-over control of Chrome's cookie management, and instead, my extension should manage the cookies.
What I did is the following:
at extension startup (after browser has started) it downloads from a cloud service cookies already stored for some URLs.
chrome.webNavigation.onCreatedNavigationTarget - here i establish (for given URL) if my extension will manage the cookies or not. If yes, I mark some internal variables to establish something like an "internal session". If I already have cloud-cookies for this URL, then I set them in the session variable, to be later used. If not, the session variable is simply initialized with blank data.
in chrome.webRequest.onBeforeRequest i do some checks if i have a session internally for given URL but nothing special here.
in chrome.webRequest.onBeforeSendHeaders - here is where i set the cookie header with what exists internally in the session variable (which is either something restored from cloud or the cookies received via set-cookie from the website)
in chrome.webRequest.onHeadersReceived i overwrite any already existing internal cookies (if any) with whatever new data was received from the website (via the set-cookie headers), so all future requests are updated
either when browser is idle or when the user closes the tab, cookies get uploaded to cloud-service, so later they can be restored.
Besides the above simplistic description that I mentioned, there's also a content script that runs from the extension's codespace, which injects and executes a javascript on the URL in order to override document.cookie setter and getter, in order to pass the cookies managed from background script to content area and viceversa (there's some communication between the 2 "channels", cookies get updated back and forth)
Things apparently work. I navigate to a URL, login with some credentials, cookies are handled/passed etc. I then close the tab, verify the cookies where sent to cloud-service, then restore the tab (via reopen previously closed tab) and test if navigation is still possible - and it is and is still managed by the background script, etc. Also verified by debugg inspector (navigated to application - storage - cookies) confirmed there are no cookies at all inside the browser. Even executing document.cookie from console, shows that there are some cookies being used, etc.
However, the last testing scenario, where i close the browser, reopen it... so it fetches the cookies again from the cloud service. At the point when I navigate again to URL-1, i see from my internal logging that:
the session has been created at step 2
at step 4 (onBeforeSendHeaders) cookies get added to request-headers like i expected, i then confirm this in Navigation-inspector by inspecting various requests to see if the cookies have been sent or not, etc.
But at the first onHeadersReceived i see that the cookies "have not been accepted" and they already been overwritten, like they never existed before... (obviously, I'm being asked again to login/etc) - totally not what I expected. It behaves like the request contained no cookies at all initially. (if then i login again... all navigation works great... all until i reopen the browser again).
What would you guys believe that could be the cause for this behavior?
I'm not an expert on how cookies get stored/passed/etc :(
My web site uses magic links for login, however, I have a problem on mobile (not sure about Android - haven't tried yet, but the problem exists at least on iOS): when a user receives the email say in the GMail app, the link opens in the embedded browser, meaning that cookies will not be passed to the "real" browser.
Is there a way to ensure the link in the email opens in the real system browser and therefore cookies are stored permanently?
(Essentially browser session isolation on iOS breaks a lot of things on the Internet, so surely there is a workaround?)
After some research: no, it is not possible to detect you are in an embedded browser, neither is it possible to enforce opening a link in the system one. Makes sense from security point of view.
However, I was asking the wrong question. The problem of a magic link login is solved differently: when starting a login process you can set a session cookie and create an associated DB record for it, marking it as blocked, i.e. not logged in.
At next step, when the magic link is opened in whatever browser you unblock the session in the DB. At this stage you can replace the login cookie with a real one, e.g. JWT, or continue using it as your main auth token.
If the user then returns to the real browser, you check the login cookie and act accordingly, keeping in mind that it may not be the browser where they validated the magic link. At this stage you can, again, replace the login cookie with your real auth cookie knowing that the session has been validated already.
I'm not entirely sure this is 100% safe, need to think about it more but at first glance it does look safe and seems to be pretty much the only way of handling magic links on mobile.
I develop a website and I need to store a private key on the client side.
How to securely store this variable on the client side?
Can I use sessionStorage?
(I would like this (variable) information to be accessible only to the current user. As soon as he closes his browser, the data will have to be deleted.)
Thank you.
At a top level, yes, sessionStorage will do what you need. To quote MDN’s page on sessionStorage:
A page session lasts as long as the browser is open, and survives over page reloads and restores.
Opening a page in a new tab or window creates a new session with the value of the top-level browsing context, which differs from how session cookies work.
Opening multiple tabs/windows with the same URL creates sessionStorage for each tab/window.
Closing a tab/window ends the session and clears objects in sessionStorage.
There are several things to be careful of though. Firstly, any connection to the server would need to be done securely. This necessitates an HTTPS connection, probably with TLS 1.2 or 1.3 at this point.
Secondly, you’ll need to make sure that the page environment is clean. This means that you can’t load 3rd party JavaScript that could exfiltrate the private key. At an absolute minimum, any third party JS you load will need to be audited first and then have an integrity attribute added to make sure it doesn’t change.
Finally, you probably would want to add something to destroy the key after the user has finished using the page. This could be warning them to close the page after they’ve finished using the system, or something more automatic like retiring the key after x minutes and getting the system to negotiate a new one in time. Obviously there’s a balance here between security and usability, but the best systems can do this in a user-transparent way.
I want to use the current logged in Windows AD account to authenticate with my web app. It's fine (desired, actually) to have the front end pass the authentication token (or whatever form that takes in AD) to the back end for validation with our SSO provider. But how do I get the AD information into the front end, so that it can be passed the back end? What does this info look like, how is it acquired, etc? I can't find any tutorials or guidance on the topic.
I know this is possible because I see it being done on other web apps, but I don't know how to do it myself and am having a very hard time finding a solution.
If you want seamless login (so the user doesn't have to type in their username/password) then you will want Windows Authentication. You can read about how it works here.
To make this work with Node.js Express you can use the NodeSSPI package. The documentation has examples on how to use it.
The browser will also have to trust your site before it will send credentials automatically. For IE and Chrome, that means adding the site to the list of Trusted Sites in the Internet Options. Firefox keeps its own list in the network.automatic-ntlm-auth.trusted-uris setting in about:config
Is there any way or possibility to update an apps code and have the client adopt it without reloading the app/website? I mean updating live application code, like adding or removing functionality.
The iPad asks for user permission every 24 hours for fullscreen webapps, for native apps it does not. Once you grant permission it will not ask again but if you reload the app, which you usually have to when you push an update, it will ask again if 24h passed.
We are installing iPads into Taxis and want to track connectivity around the city with geolocation data, but we can't do it reliably since the app would ask the guest for permission. We also would like to provide some location based features but wen can't do it because if one guest says "No", it will impact all next guests since the iPad only allows aksing twice and then you have to wait some time before you can ask for using Geolocation again,
By update the code I presume you mean live code reload or changing the modules loaded on a page without changing it.
This would require you to have an infrastructure library that allows you to either reload or add modules of code to your applications. ncore allows this
Next you would need a communication channel from the server or some other remote end point to send new modules or module reload commands to the client browser.
The concept being that you have a websocket open and you send one of two commands
add module : url
reload module : name
The app in the browser would then either load and add that module from an url or reload that module.
This is basically remote control over the state of an application in a users browser.