Perché i cookie non vengono riconosciuti quando si fa clic su un link da un’origine esterna (ad esempio Excel, Word, ecc.)

Ho notato che quando si fa clic su un collegamento esternamente dal browser Web, ad esempio da Excel o Word, il cookie di sessione viene inizialmente non riconosciuto, anche se il collegamento si apre in una nuova scheda della stessa finestra del browser.

Il browser finisce per riconoscere il suo cookie, ma sono perplesso sul motivo per cui il collegamento iniziale da Excel o Word non funziona. Per renderlo ancora più difficile, fare clic su un collegamento funziona bene da Outlook.

Qualcuno sa perché questo potrebbe accadere? Sto usando Zend Framework con PHP 5.3.

Questo perché MS Office utilizza il componente Hlink.dll per cercare se il collegamento è un documento di Office o altro. MS Office prevede di aprire il documento collegato all’interno dei documenti senza l’ausilio di browser esterni (utilizzando il componente Hlink.dll di IE6).

Se il cookie di sessione protegge il sito Web, Hlink viene naturalmente reindirizzato alla pagina di accesso e dopo aver raggiunto la pagina HTML e non è in grado di “capirlo” lo apre in un browser esterno. Si noti che non apre l’URL originale (comportamento previsto) ma il risultato del reindirizzamento, anche se era il reindirizzamento 302.

Microsoft ha quel bug nel componente non supportato (Hlink.dll), invece di riconoscere il bug che ci ha messo in testa (cercando di convincerci che è un difetto del sistema SSO che usiamo, ovvero i cookie di sessione) e si rifiuta di aggiornarlo. Offre soluzioni alternative che distriggersno la funzionalità di ricerca di MS Office:

HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\ Office\9.0\Common\Internet\ForceShellExecute:DWORD=1 

Oppure offrirci soluzioni alternative, per evitare reindirizzamenti HTTP e modifiche ai reindirizzamenti Javascript o ai reindirizzamenti META REFRESH (ad esempio per avere Hlink sulla pagina di testo / html sull’URL originale e farlo funzionare con un browser esterno per gestirlo).

Abbiamo avuto lo stesso problema e abbiamo scritto una gem open source per aiutare chi utilizza i binari: https://github.com/spilliton/fix_microsoft_links

Puoi usare lo stesso approccio che abbiamo usato su qualsiasi framework:

  1. Rileva se l’agente utente proviene da un prodotto Microsoft
  2. Renderizza una pagina html vuota con un tag meta aggiornamento che farà sì che il browser aggiorni la pagina con i cookie corretti

Esempio di codice qui: https://github.com/spilliton/fix_microsoft_links/blob/master/lib/fix_microsoft_links.rb

Lato server questo ha funzionato per me in IIS (utilizzando una regola di riscrittura)

        

Correzione per VB.NET:

 Dim userAgent As String = System.Web.HttpContext.Current.Request.UserAgent If userAgent.Contains("Word") Or userAgent.Contains("Excel") Or userAgent.Contains("PowerPoint") Or userAgent.Contains("ms-office") Then System.Web.HttpContext.Current.Response.Clear() System.Web.HttpContext.Current.Response.Write("") System.Web.HttpContext.Current.Response.End() End If 

In pratica obbliga il browser ad aggiornare la pagina, quindi la richiesta arriva con l’agente utente del browser e tutti i cookie corretti.

Ecco una soluzione per C # ASP.NET basata sulla risposta di spilliton sopra. In Global.asax.cs, aggiungere quanto segue:

  private static string MSUserAgentsRegex = @"[^\w](Word|Excel|PowerPoint|ms-office)([^\w]|\z)"; protected void Application_OnPostAuthenticateRequest(object sender, EventArgs e) { if (System.Text.RegularExpressions.Regex.IsMatch(Request.UserAgent, MSUserAgentsRegex)) { Response.Write(""); Response.End(); } } 

Soluzione PHP:

Ciò impedisce al prodotto MS di riconoscere il reindirizzamento. MS quindi avvia un browser dal collegamento richiesto.

 if (isset($_SERVER['HTTP_USER_AGENT'])) { $http_user_agent = $_SERVER['HTTP_USER_AGENT']; if (preg_match('/Word|Excel|PowerPoint|ms-office/i', $http_user_agent)) { // Prevent MS office products detecting the upcoming re-direct .. forces them to launch the browser to this link die(); } } 

.. redirect dopo questo codice

Ecco la mia soluzione per questo in WordPress. Aggiungi questo a functions.php nel tuo tema o in un altro file di plugin.

Ciò può essere utile se il tuo sistema, come WP, invia utenti disconnessi a una pagina di accesso con un reindirizzamento alla pagina a cui stavano tentando di accedere. Word inviava gli utenti a questa pagina, ma WP non gestiva correttamente il caso in cui un utente era già loggato. Questo codice controlla se c’è un utente corrente e un reindirizzamento al parametro passato. In tal caso, reindirizza al redirect_to posizione.

 function my_logged_in_redirect_to() { global $current_user; if($current_user->ID && $_REQUEST['redirect_to']) { wp_redirect($_REQUEST['redirect_to']); exit; } } add_action('wp', 'my_logged_in_redirect_to'); 

1. Da Excel / Word Point a http://example.com/from_excel.php

2.In “from_excel.php” reindirizza alla pagina in cui usi la sessione

  

Ecco una correzione VBA, per Excel. Lo stesso concetto può essere applicato per Microsoft Word. Fondamentalmente, piuttosto che sparare il collegamento da Excel, il codice esegue il collegamento all’interno di una shell. Ecco il codice:

 Private Sub Worksheet_FollowHyperlink(ByVal objLink As Hyperlink) Application.EnableEvents = False Dim strAddress As String strAddress = "explorer " & objLink.TextToDisplay Dim dblReturn As Double dblReturn = Shell(strAddress) Application.EnableEvents = True End Sub 
  1. Per il foglio Excel che contiene i collegamenti, fare clic con il pulsante destro del mouse sulla scheda del foglio e fare clic su Visualizza codice . Viene visualizzato l’editor VBA.
  2. Incolla il codice nella finestra e chiudi l’editor.
  3. Modifica ogni link nella pagina in modo che punti semplicemente alla cella in cui si trova. Per fare ciò:
  4. Fare clic con il pulsante destro del mouse sul collegamento e selezionare Modifica collegamento ipertestuale . Viene visualizzata una finestra Modifica collegamento ipertestuale.
  5. Fai clic su Inserisci in questo documento .
  6. Fai clic sul nome del foglio.
  7. Per Digitare il riferimento di cella , immettere un riferimento di cella (ad esempio A4).
  8. Clicca OK .

Un paio di note:

  • Dovrai salvare il foglio di calcolo come foglio di calcolo abilitato per le macro (.xlsm). Quando gli utenti aprono il foglio di calcolo, verrà chiesto loro di abilitare le macro. Se rispondono No, i collegamenti non funzioneranno.
  • Queste istruzioni sono basate su Excel 2010. Presumibilmente le versioni successive sono simili.

Ho dovuto risolvere questo problema per un sito ASP.NET ma volevo solo usare javascript / jQuery:

 var isCoBrowse = ('<%= Session["user"].ToString().ToLower() %>' != '0'); if (isCoBrowse && window.location.href.indexOf('ReturnUrl=') >= 0 && window.location.href.indexOf('dllCheq') == -1) { //redirect to the ReturnUrl & add dllCheq to the URI var toRedirect = decodeURIComponent(gup('ReturnUrl', window.location.href)) + '&dllCheq'; window.location = toRedirect; } 

Ho ottenuto la funzione gup da: Come ottenere il valore dal parametro URL?

Utilizzare la correzione fornita dal collegamento fornito da microsoft in basso. https://support.microsoft.com/en-us/kb/218153

Non posso credere che chiamino questa caratteristica. Tuttavia, ecco un featurefix per Apache:

 RewriteEngine On # Send a 200 to MS Office so it just hands over control to the browser # It does not use existing session cookies and would be redirected to the login page otherwise # https://www.wimpyprogrammer.com/microsoft-office-link-pre-fetching-and-single-sign-on/ RewriteCond %{HTTP_USER_AGENT} ;\sms-office(\)|;) RewriteRule .* - [R=200,L] 

Potrebbe non essere la migliore per quanto riguarda le prestazioni, dato che l’intera pagina viene inviata invece di una risposta vuota, ma non volevo aggiungere altri moduli Apache solo per risolvere una simile caratteristica di H ^ H ^ H ^ H.

Ecco come risolvere questo problema con Java e Spring tramite un filtro:

 /** * To see why this is necessary, check out this page: * https://support.microsoft.com/en-gb/help/899927. */ public class MicrosoftFilter extends OncePerRequestFilter { @Override protected void doFilterInternal(final HttpServletRequest request, final HttpServletResponse response, final FilterChain filterChain) throws ServletException, IOException { //Serve up a blank page to anything with a Microsoft Office user agent, forcing it to open the //URL in a browser instead of trying to pre-fetch it, getting redirected to SSO, and losing //the path of the original link. if (!request.getHeader("User-Agent").contains("ms-office")) { filterChain.doFilter(request, response); } } } /** * Security configuration. */ @Configuration public class SecurityConfiguration { @Bean public FilterRegistrationBean microsoftFilterRegistrationBean() { FilterRegistrationBean registrationBean = new FilterRegistrationBean<>(); registrationBean.setFilter(new MicrosoftFilter()); registrationBean.setOrder(Ordered.HIGHEST_PRECEDENCE); return registrationBean; } } 

Sospetto che si tratti di come si impostano i cookie.

A causa della natura di come è stato creato il web, example.com non è visto come lo stesso dominio di www.example.com ; di conseguenza: puoi accedere a www.example.com e non aver effettuato l’accesso su example.com .

Quindi, in altre parole, controlla l’URL nel tuo file word o excel – è lo stesso dominio di come sei loggato nel tuo browser?

Ci sono due correzioni / soluzioni a questa incoerenza dei cookie: 1. redirect chiunque tenti di caricare il tuo sito senza www. alla stessa pagina con il www. (o viceversa), o 2. quando si imposta il cookie, assicurarsi di specificare l’argomento del dominio come “.example.com”. Il punto iniziale indica che il cookie deve essere valido anche per tutti i sottodomini di quel dominio.

Sospetto che la ragione per cui il browser alla fine lo riconosce è che probabilmente alla fine finirai per atterrare su un URL con la stessa struttura di dominio di come sei loggato.

Spero che questo ti aiuti.