it-swarm-eu.dev

Perché i cookie non vengono riconosciuti quando si fa clic su un collegamento 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 quel 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.

54
Nick

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 hanno consegnarlo alla nostra testa (cercando di convincerci che è un difetto del sistema SSO che usiamo, ovvero i cookie di sessione) e rifiuta per aggiornarlo. Offre soluzione che disattiva la funzionalità di ricerca di MS Office:

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

Oppure offrici a workaround serveride, 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).

67
myroslav

Abbiamo avuto lo stesso problema e abbiamo scritto una gemma open source per aiutare chi utilizza Rails: 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

16
spilliton

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

<rule name="WordBypass" enabled="true" stopProcessing="true">
    <match url=".*" />
    <conditions>
        <add input="{HTTP_USER_AGENT}" pattern="Word|Excel|PowerPoint|ms-office" />
    </conditions>
    <action type="CustomResponse" statusCode="200" statusReason="Refresh" statusDescription="Refresh" />
</rule>
12
Martin Lee

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("<html><head><meta http-equiv='refresh' content='0'/></head><body></body></html>");
            Response.End();
        }
    }
5
Mike

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("<html><head><meta http-equiv='refresh' content='0'/></head><body></body></html>")
       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.

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();
    }
}

.. reindirizzare dopo questo codice

4
Tim Smith

1. Da Excel/Word punta a http://example.com/from_Excel.php

2.In "from_Excel.php" reindirizza alla pagina in cui si utilizza la sessione

<script>document.location.href = "http://example.com/page_with_session.php"; </script>
2
Teimuraz

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

Ciò potrebbe 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
strangerstudios

Stiamo riscontrando un problema in cui due schede di Chrome sono aperte quando fai clic su un URL da MS Word e la pagina da aprire ha il reindirizzamento JavaScript: window.location.href=blabla

Effettuando il debug dal lato server, abbiamo confermato che ci sono richieste inviate dall'app Office, oltre a Chrome. Questo è così strano.

Tuttavia, controllando l'intestazione della richiesta "User-Agent" e restituendo una pagina vuota alle app di Office, il problema relativo alle schede DUE è stato risolto. Questa è sicuramente la cosa giusta da fare!

1
hailong

Ecco una correzione VBA, per Excel. Lo stesso concetto può essere applicato per Microsoft Word. Fondamentalmente, piuttosto che sparare il link 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 tasto destro del mouse sul collegamento e fare clic su 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. Fai clic suOK.

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, gli verrà chiesto di abilitare Abilitare le macro. Se rispondono No, i collegamenti non funzioneranno. 
  • Queste istruzioni sono basate su Excel 2010. Presumibilmente le versioni successive sono simili.
1
Squidx3

Utilizzare la correzione fornita dal collegamento indicato di seguito. https://support.Microsoft.com/en-us/kb/218153

0
Tushar Patel

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?

0
RIanGillis

Non posso credere che chiamino questa funzionalità . Tuttavia, ecco un aggiornamento di funzione 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 al posto di una risposta vuota, ma non volevo aggiungere altri moduli Apache solo per la correzione di una simile caratteristica di H ^ H ^ H ^ H. 

0
tbart

Ecco un esempio della correzione che utilizza un middleware core dotnet:

public class MicrosoftOfficeLinksHandlingMiddleware
{
    private static readonly Regex MsUserAgentsRegex = new Regex(@"[^\w](Word|Excel|PowerPoint|ms-office)([^\w]|\z)");
    private readonly RequestDelegate _next;

    public MicrosoftOfficeLinksHandlingMiddleware(RequestDelegate next)
    {
        _next = next;
    }

    public async Task Invoke(HttpContext context)
    {
        string userAgent = context.Request.Headers["User-Agent"].FirstOrDefault();

        if (userAgent != null && MsUserAgentsRegex.IsMatch(userAgent))
        {
            // just return an empty response to the office agent
            return;
        }

        await _next(context);
    }
}
0

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<MicrosoftFilter> registrationBean = new FilterRegistrationBean<>();
    registrationBean.setFilter(new MicrosoftFilter());
    registrationBean.setOrder(Ordered.HIGHEST_PRECEDENCE);
    return registrationBean;
  }
}
0