Por que os cookies não são reconhecidos quando um link é clicado de uma fonte externa (ou seja, Excel, Word, etc…)

Percebi que quando um link é clicado externamente no navegador da Web, como no Excel ou no Word, esse cookie de session é inicialmente não reconhecido, mesmo que o link seja aberto em uma nova guia na mesma janela do navegador.

O navegador acaba reconhecendo seu cookie, eventualmente, mas estou confuso sobre o motivo pelo qual esse link inicial do Excel ou Word não funciona. Para torná-lo ainda mais desafiador, clicar em um link funciona bem no Outlook.

Alguém sabe por que isso pode estar acontecendo? Estou usando o Zend Framework com PHP 5.3.

Isso ocorre porque o MS Office está usando o componente Hlink.dll para pesquisar se o link é um documento do Office ou outra coisa. MS Office espera abrir o documento vinculado dentro de documentos sem o auxílio do navegador externo (usando o componente Hlink.dll do IE6).

Se o cookie de session protege o site, o Hlink naturalmente está sendo redirecionado para a página de login e, tendo atingido a página HTML e não sendo capaz de “entender”, ele é aberto no navegador externo. Observe que ele não abre o URL original (comportamento esperado), mas o resultado do redirecionamento, mesmo que seja um redirecionamento 302.

A Microsoft tem esse bug no componente não suportado (Hlink.dll), em vez de reconhecer o bug que eles transformam em nossa cabeça (tentando nos convencer de que é falha do sistema SSO que usamos, ou seja, cookies de session) e se recusa a atualizá-lo. Ele oferece uma solução alternativa que desativa a funcionalidade de pesquisa do MS Office:

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

Ou nos ofereça soluções alternativas no servidor, para evitar redirecionamentos HTTP e mudar para redirecionamentos Javascript ou redirecionamentos META REFRESH (ou seja, ter o Hlink para obter a página text / html na URL original e fazer com que ele execute um navegador externo para lidar com isso).

Nós tivemos esse mesmo problema e escrevemos uma gem de código aberto para ajudar aqueles que usam rails: https://github.com/spilliton/fix_microsoft_links

Você pode usar a mesma abordagem que usamos em qualquer estrutura:

  1. Detectar se o agente do usuário é de um produto da Microsoft
  2. Renderizar uma página html em branco com uma tag de atualização meta que fará com que o navegador atualize a página com os cookies corretos

Exemplo de código aqui: https://github.com/spilliton/fix_microsoft_links/blob/master/lib/fix_microsoft_links.rb

Lado do servidor isso funcionou para mim no IIS (usando uma regra de reescrita)

        

Correção para 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 

Isso basicamente força o navegador a atualizar a página, então a solicitação é enviada com o agente do usuário do navegador e todos os cookies corretos.

Aqui está uma solução para o C # ASP.NET com base na resposta do spilliton acima. Em Global.asax.cs, adicione o seguinte:

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

Solução PHP:

Isso impede que o produto MS reconheça o redirecionamento. A MS, portanto, lança um navegador a partir do link necessário.

 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 após este código

Aqui está a minha solução para isso no WordPress. Adicione isto a functions.php no seu tema ou outro arquivo de plugin.

Isso pode ser útil se o seu sistema, como o WP, enviar usuários desconectados para uma página de login com um redirecionamento para a página que eles estavam tentando acessar. O Word estava enviando usuários para esta página, mas o WP não estava manipulando adequadamente o caso em que um usuário já estava logado. Esse código verifica se há um usuário atual e um redirect_to param passado. Em caso afirmativo, ele redireciona para o local de redirecionamento_para.

 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. Do excel / word aponte para http://example.com/from_excel.php

2. Em “from_excel.php” redirect para a página onde você usa a session

  

Aqui está uma correção do VBA, para o Excel. O mesmo conceito pode ser aplicado ao Microsoft Word. Basicamente, em vez de triggersr o link de dentro do Excel, o código executa o link de dentro de um shell. Aqui está o código:

 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. Para a planilha do Excel que contém os links, clique com o botão direito do mouse na guia da planilha e clique em View Code . O editor do VBA é exibido.
  2. Cole o código na janela e feche o editor.
  3. Modifique cada link na página para que simplesmente aponte de volta para a célula em que ele está. Para fazer isso:
  4. Clique com o botão direito do mouse no link e clique em Editar hiperlink . Uma janela Editar hiperlink é exibida.
  5. Clique em colocar neste documento .
  6. Clique no nome da folha.
  7. Para Digite a referência de célula , insira uma referência de célula (por exemplo, A4).
  8. Clique em OK

Um par de notas:

  • Você precisará salvar a planilha como uma planilha habilitada para macro (.xlsm). Quando os usuários abrirem a planilha, eles serão solicitados a ativar as macros. Se eles responderem, os links não funcionarão.
  • Estas instruções são baseadas no Excel 2010. Presumivelmente, as versões posteriores são semelhantes.

Eu tive que resolver esse problema para um site asp.net, mas eu só queria usar 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; } 

Eu tenho a function gup de: Como obter o valor do parâmetro URL?

Use correção fornecida pela microsoft dado link abaixo. https://support.microsoft.com/pt-br/kb/218153

Eu não posso acreditar que eles chamam isso de recurso. No entanto, aqui está um featurefix para o 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] 

Pode não ser o melhor desempenho, já que toda a página é enviada em vez de uma resposta vazia, mas eu não queria adicionar outros módulos do Apache apenas para consertar esse recurso de idiota ^ H ^ H ^ H.

Aqui está como resolver isso com Java e Spring através de um 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; } } 

Eu suspeito que isso é uma questão de como você está definindo o cookie (s).

Devido à natureza de como a web foi criada, example.com não é visto como o mesmo domínio que www.example.com ; portanto: você pode estar logado em www.example.com e não estar logado em example.com .

Então, em outras palavras, verifique o URL em sua palavra ou arquivo do Excel – é o mesmo domínio de como você está logado no seu navegador?

Existem duas correções / soluções para essa inconsistência de cookie: 1. redirect qualquer um que tente carregar seu site sem o www. para a mesma página com o www. (ou vice-versa) ou 2. quando você estiver configurando o cookie, especifique o argumento de domínio como “.example.com”. O ponto principal indica que o cookie também deve ser válido em todos os subdomínios desse domínio.

Eu suspeito que o motivo pelo qual o navegador o reconhece é que você provavelmente acabará caindo em uma URL com a mesma estrutura de domínio de como você está logado.

Espero que isto ajude.