Подтвердить что ты не робот

Почему файлы cookie не распознаются при нажатии ссылки из внешнего источника (например, Excel, Word и т.д.)

Я заметил, что когда ссылка вызывается извне из веб-браузера, например из Excel или Word, что мой сеансовый файл изначально непризнан, даже если ссылка открывается на новой вкладке того же окна браузера.

В конечном итоге браузер узнает о своем cookie, но я озадачен тем, почему эта начальная ссылка из Excel или Word не работает. Чтобы сделать его еще более сложным, щелчок по ссылке отлично работает в Outlook.

Кто-нибудь знает, почему это может произойти? Я использую Zend Framework с PHP 5.3.

4b9b3361

Ответ 1

Это связано с тем, что MS Office использует компонент Hlink.dll для поиска, если ссылка является документом Office или чем-то еще. MS Office планирует открыть документ, связанный внутри документов, без помощи внешнего браузера (используя компонент Hlink.dll IE6).

Если cookie cookie защищает веб-сайт, Hlink, естественно, перенаправляется на страницу входа в систему, и, достигнув HTML-страницы и неспособной "понять", она открывается во внешнем браузере. Обратите внимание, что он открывает не оригинальный URL (ожидаемое поведение), а результат перенаправления, даже если он был перенаправлен на 302.

У Microsoft есть эта ошибка в неподдерживаемом компоненте (Hlink.dll), вместо того, чтобы распознать ошибку, перевернуть ее на голову (пытается убедите нас, что это недостаток системы SSO, которую мы используем, т.е. файлы cookie сеансов) и отказывается ее обновлять. Он предлагает обходной путь, который отключает функциональность поиска в MS Office:

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

Или предложите нам обходные серверы, чтобы избежать перенаправления HTTP и изменения в переадресации Javascript или перенаправлений META REFRESH (т.е. чтобы Hlink получить текст/html-страницу по исходному URL-адресу и заставить запустить внешний браузер для ее обработки).

Ответ 2

У нас была такая же проблема, и мы писали камень с открытым исходным кодом, чтобы помочь тем, кто использует рельсы: https://github.com/spilliton/fix_microsoft_links

Вы можете использовать тот же подход, который мы использовали в любой среде:

  • Обнаружение, если пользовательский агент из продукта Microsoft
  • Извлеките пустую страницу html с тегом meta refresh, который заставит браузер обновить страницу с помощью правильных файлов cookie.

Пример кода здесь: https://github.com/spilliton/fix_microsoft_links/blob/master/lib/fix_microsoft_links.rb

Ответ 3

На стороне сервера это работало для меня в IIS (с использованием правила перезаписи)

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

Ответ 4

Вот решение для С# ASP.NET, основанного на ответе spilliton выше. В Global.asax.cs добавьте следующее:

    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

Исправлено для 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

В основном это заставляет браузер обновлять страницу, поэтому запрос приходит с помощью агента пользователя браузера и всех правильных файлов cookie.

Ответ 6

Решение PHP:

Это предотвращает распознавание перенаправления MS-продуктом. Поэтому MS запускает браузер из необходимой ссылки.

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

.. перенаправить после этого кода

Ответ 7

1. Из выражения excel/word в http://example.com/from_excel.php

2.In "from_excel.php" перенаправлять на страницу, где вы используете сеанс

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

Ответ 8

Мы видим проблему в том, что при щелчке URL-адреса в MS Word открывается две вкладки Chrome, а на открываемой странице перенаправляется JavaScript: window.location.href=blabla

Отладкой со стороны серверов мы подтвердили, что помимо приложения Chrome отправляются запросы из приложения Office. Это так странно.

Но в любом случае, проверив заголовок запроса "Пользователь-агент" и вернув пустую страницу в приложения Office, наша проблема с двумя вкладками была решена. Это определенно правильно!

Ответ 9

Вот мое решение для этого в WordPress. Добавьте это в functions.php в свою тему или в другой файл плагина.

Это может быть полезно, если ваша система, например WP, отправляет зарегистрированных пользователей на страницу входа с перенаправлением на страницу, к которой они пытались получить доступ. Word отправлял пользователей на эту страницу, но тогда WP не правильно обрабатывал случай, когда пользователь уже вошел в систему. Этот код проверяет, есть ли текущий пользователь и передан параметр redirect_to. Если это так, он перенаправляется в местоположение redirect_to.

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

Ответ 10

Здесь исправление VBA для Excel. Та же концепция может быть применена для Microsoft Word. В принципе, вместо того, чтобы отключить ссылку из Excel, код выполняет ссылку изнутри оболочки. Здесь код:

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
  • Для листа Excel, содержащего ссылки, щелкните правой кнопкой мыши вкладку листа и нажмите Просмотреть код. Появится редактор VBA.
  • Вставьте код в окно и закройте редактор.
  • Измените каждую ссылку на странице, чтобы она просто указывала на ячейку, в которой она находится. Для этого:
  • Щелкните правой кнопкой мыши ссылку и нажмите Изменить гиперссылку. Появится окно "Редактировать гиперссылку".
  • Нажмите Место в этом документе.
  • Нажмите имя листа.
  • Для Введите ссылку на ячейку, введите ссылку на ячейку (например, A4).
  • Нажмите ОК.

Несколько примечаний:

  • Вам нужно будет сохранить таблицу в виде таблицы с поддержкой макросов (.xlsm). Когда пользователи открывают электронную таблицу, им будет предложено включить макросы. Если они ответят "Нет", ссылки не будут работать.
  • Эти инструкции основаны на Excel 2010. Предположительно, более поздние версии схожи.

Ответ 11

Я не могу поверить, что они называют это функцией. Однако, вот исправление для 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]

Не может быть наилучшей производительности, так как вся страница отправляется вместо пустого ответа, но я не хотел добавлять другие модули Apache только для исправления такой идиотической функции ^ H ^ H ^ H ^ H.

Ответ 12

Вот пример исправления с использованием промежуточного программного обеспечения ядра 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);
    }
}

Ответ 13

Мне пришлось решить эту проблему для сайта ASP.NET, но я только хотел использовать 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;
}

Я получил функцию gup: Как получить значение из параметра URL?

Ответ 15

Вот как обойти это с Java и Spring через фильтр:

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

Ответ 17

Компьютеры никогда suck.they не делают, как они supost к do.they хороши только для просмотра порно играть в игры, которые будут гнить мозг Но все же мы все еще трахаться с пока мы не сойти с ума

Ответ 18

Решение NGINX ниже:

if ($http_user_agent ~* Word|Excel|PowerPoint|ms-office) {
    return 200 '<html><head><meta http-equiv="refresh" content="0"/></head><body></body></html>';
}

Вы можете поместить его в блок server или location. Работает как шарм.

Ответ 19

Я подозреваю, что это вопрос того, как вы настраиваете файлы cookie.

Из-за характера создания веб-сайта example.com не рассматривается как тот же домен, что и www.example.com; следовательно: вы можете войти в систему www.example.com и не войти в систему example.com.

Иными словами, проверьте URL в своем слове или файле excel - это тот же домен, что и вы вошли в свой браузер?

Есть два исправления/решения этой непоследовательности cookie: 1. перенаправлять всех, кто пытается загрузить ваш сайт без www. на ту же страницу с www. (или наоборот), или 2. Когда вы устанавливаете файл cookie, не забудьте указать аргумент домена как ".example.com". Ведущая точка указывает, что файл cookie должен быть действительным и для всех поддоменов этого домена.

Я подозреваю причину, по которой браузер, в конце концов, признает, что это потому, что вы, вероятно, в конечном итоге попадаете на URL с той же структурой домена, что и вы вошли в систему.

Надеюсь, что это поможет.