wake-up-neo.net

Warum werden Cookies nicht erkannt, wenn auf einen Link von einer externen Quelle (z. B. Excel, Word usw.) geklickt wird

Mir ist aufgefallen, dass beim Klicken auf einen Link von außerhalb des Webbrowsers, z. B. von Excel oder Word, mein Sitzungscookie zunächst nicht erkannt wird, selbst wenn der Link in einem neuen Tab des gleichen Browserfensters geöffnet wird.

Der Browser erkennt sein Cookie schließlich, aber ich bin verwirrt, warum der ursprüngliche Link von Excel oder Word nicht funktioniert. Um es noch schwieriger zu machen, funktioniert das Klicken auf einen Link in Outlook.

Weiß jemand, warum dies passieren könnte? Ich verwende das Zend Framework mit PHP 5.3.

54
Nick

Dies liegt daran, dass MS Office die Komponente Hlink.dll verwendet, um zu suchen, ob der Link ein Office-Dokument oder etwas anderes ist. MS Office erwartet, dass das in Dokumenten verknüpfte Dokument ohne Hilfe eines externen Browsers geöffnet wird (mithilfe der Komponente Hlink.dll von IE6).

Wenn das Sitzungscookie die Website schützt, wird Hlink natürlich auf die Anmeldeseite umgeleitet und hat die HTML-Seite erreicht und kann diese nicht "verstehen", öffnet es sie in einem externen Browser. Beachten Sie, dass die ursprüngliche URL nicht geöffnet wird (erwartetes Verhalten), sondern das Ergebnis der Umleitung, selbst wenn dies die Umleitung war.

Microsoft hat diesen Fehler in der nicht unterstützten Komponente (Hlink.dll), anstatt den Fehler zu erkennen, den sie drehen Sie ihn auf den Kopf (um uns davon zu überzeugen, dass es sich um einen Fehler des von uns verwendeten SSO-Systems handelt, dh um Sitzungs-Cookies ) und weigert sich, es zu aktualisieren. Es bietet Problemumgehung, die die Suchfunktion deaktiviert von MS Office:

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

Oder bieten Sie uns an, den Server zu umgehen, um HTTP-Weiterleitungen zu vermeiden und in Javascript-Weiterleitungen oder META REFRESH-Weiterleitungen zu wechseln (d. H. Hlink soll Text-/HTML-Seite auf der ursprünglichen URL abrufen und einen externen Browser ausführen, um damit umzugehen).

70
myroslav

Wir hatten das gleiche Problem und haben einen Open-Source-Edelstein geschrieben, der den Anwendern von Rails helfen soll: https://github.com/spilliton/fix_Microsoft_links

Sie können den gleichen Ansatz verwenden, den wir für jedes Framework verwendet haben:

  1. Ermitteln Sie, ob der Benutzeragent von einem Microsoft-Produkt stammt
  2. Rendern Sie eine leere HTML-Seite mit einem Meta-Refresh-Tag, durch den der Browser die Seite mit den richtigen Cookies aktualisiert

Beispielcode hier: https://github.com/spilliton/fix_Microsoft_links/blob/master/lib/fix_Microsoft_links.rb

16
spilliton

Serverseitig funktionierte dies für mich in IIS (unter Verwendung einer Umschreibungsregel)

<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

Hier ist eine Lösung für C # ASP.NET basierend auf der obigen Antwort von Spilliton. Fügen Sie in Global.asax.cs Folgendes hinzu:

    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

Fix für 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

Es zwingt den Browser im Wesentlichen dazu, die Seite zu aktualisieren, sodass die Anfrage beim Benutzeragenten des Browsers und allen korrekten Cookies eingeht.

PHP-Lösung:

Dadurch wird verhindert, dass das MS-Produkt die Weiterleitung erkennt. MS startet daher einen Browser über den erforderlichen Link.

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

.. Weiterleitung nach diesem Code

4
Tim Smith

1.Von Excel/Word verweisen Sie auf http://example.com/from_Excel.php

2.In "from_Excel.php" umleiten auf die Seite, auf der Sie die Sitzung verwenden

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

Hier ist meine Lösung dafür in WordPress. Fügen Sie dies zu functions.php in Ihrem Design oder einer anderen Plugin-Datei hinzu. 

Dies kann hilfreich sein, wenn Ihr System wie WP abgemeldete Benutzer an eine Anmeldeseite mit einer Umleitung zu der Seite sendet, auf die sie zugreifen wollten. Word schickte Benutzer auf diese Seite, aber WP behandelte den Fall, in dem ein Benutzer bereits angemeldet war, nicht richtig. Dieser Code prüft, ob ein aktueller Benutzer vorhanden ist und eine Weiterleitung an param übergeben wurde. Wenn dies der Fall ist, wird eine Weiterleitung an den Ort umgeleitet.

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

Es gibt ein Problem, dass ZWEI Chrome-Registerkarten geöffnet werden, wenn Sie in MS Word auf eine URL klicken und die zu öffnende Seite eine JavaScript-Umleitung hat: window.location.href=blabla

Durch das Debuggen auf der Serverseite haben wir bestätigt, dass neben Chrome auch Anforderungen von der Office-App gesendet werden. Das ist so komisch.

Wenn Sie jedoch den Anforderungsheader "User-Agent" überprüfen und eine leere Seite an Office-Apps zurückgeben, wurde das Problem mit den ZWEI Registerkarten behoben. Das ist definitiv das Richtige!

1
hailong

Hier ist ein VBA-Update für Excel. Dasselbe Konzept kann für Microsoft Word angewendet werden. Anstatt den Link aus Excel heraus abzufeuern, führt der Code den Link aus einer Shell aus .. .. Hier ist der Code:

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. Klicken Sie mit der rechten Maustaste für die Excel-Tabelle, die die Links enthält, auf die Blattregisterkarte, und klicken Sie auf Code anzeigen. Der VBA-Editor wird angezeigt.
  2. Fügen Sie den Code in das Fenster ein und schließen Sie den Editor.
  3. Ändern Sie jeden Link auf der Seite, sodass er einfach auf die Zelle verweist, in der er sich befindet. Gehen Sie dazu folgendermaßen vor:
  4. Klicken Sie mit der rechten Maustaste auf den Link und klicken Sie auf Hyperlink bearbeiten. Ein Fenster zum Bearbeiten von Hyperlinks wird angezeigt.
  5. Klicken Sie auf In dieses Dokument einfügen.
  6. Klicken Sie auf den Blattnamen.
  7. Geben Sie für Geben Sie die Zellenreferenz ein, und geben Sie eine Zellenreferenz ein (z. B. A4).
  8. Klicken Sie auf OK.

Ein paar Anmerkungen:

  • Sie müssen das Arbeitsblatt als Makro-Arbeitsblatt speichern (. Xlsm). Wenn Benutzer die Tabelle öffnen, werden sie aufgefordert, Makros zu aktivieren. Wenn sie mit Nein antworten, funktionieren die Links nicht. 
  • Diese Anweisungen basieren auf Excel 2010. Vermutlich sind spätere Versionen ähnlich.
1
Squidx3

Verwenden Sie den von Microsoft angegebenen Link unten. https://support.Microsoft.com/en-us/kb/218153

0
Tushar Patel

Ich musste dieses Problem für eine ASP.NET-Website lösen, wollte aber nur Javascript/jQuery verwenden:

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

Ich habe die gup-Funktion von: Wie bekomme ich den Wert vom URL-Parameter?

0
RIanGillis

Ich kann nicht glauben, dass sie das als Feature bezeichnen.

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]

Vielleicht ist es nicht die beste Leistung, da die gesamte Seite anstelle einer leeren Antwort gesendet wird, aber ich wollte kein weiteres Apache-Modul hinzufügen, nur um eine solche idio-Funktion zu beheben. 

0
tbart

Hier ist ein Beispiel für die Fehlerbehebung mit einer Dotnet-Core-Middleware:

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

So umgehen Sie dies mit Java und Spring über einen Filter:

/**
 * 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;
  }
}