Share via


Recuperação de dados de um site com várias autenticações usando o OM Cliente e os Serviços Web no SharePoint 2010

Artigo original publicado no sábado, dia 2 de abril de 2011

Somente a linha de assunto desta postagem é grande, não é uma indicação do que vamos falar hoje. Esta postagem tratará de um problema que incomoda a mim e a outras pessoas há muito tempo. Recentemente, comecei a fazer perguntas às pessoas sobre este assunto e, coincidentemente, recebi um email de alguém que tinha acabado de receber informações sobre como resolver este problema.

 

Estou abordando somente as partes mais comuns deste cenário; existem várias reviravoltas que podem ser adicionadas a elas. O problema é recuperar dados de um site do SharePoint que esteja usando vários provedores de autenticação; neste cenário, suponha que um seja de declarações do Windows e o outro seja outra coisa - poderia ser a autenticação Baseada em Formulários ou a autenticação SAML. Com frequência, você irá querer recuperar dados de um site desses usando o OM Cliente ou os serviços Web do SharePoint, mas use a autenticação do Windows no lugar deles. O problema até este ponto sempre tem sido que mesmo quando você define suas credenciais do Windows na solicitação, ainda obtém Acesso Negado ao solicitar os dados.

 

A resolução subjacente para este problema é que, se você quiser acessar programaticamente um site do SharePoint que use vários provedores de autenticação com um conjunto de credenciais do Windows, será necessário adicionar outro cabeçalho à sua solicitação. O nome do cabeçalho precisa ser X-FORMS_BASED_AUTH_ACCEPTED e o valor precisa ser “f”. A adição desse cabeçalho pode ser um pouco menos direta para estes dois cenários comuns e, portanto, o resto da postagem explicará fazer isso com um código de exemplo.

 

Se você estiver usando o OM Cliente, precisará adicionar um manipulador de eventos para o evento ExecutingWebRequest. Veja um exemplo do código e sua aparência:

 

//criar o contexto do cliente

ClientContext ctx = new ClientContext(MixedUrlTxt.Text);

//configurar o manipulador que adicionará o cabeçalho

ctx.ExecutingWebRequest +=

new EventHandler<WebRequestEventArgs>(ctx_MixedAuthRequest);

//definir credenciais do windows

ctx.AuthenticationMode = ClientAuthenticationMode.Default;

ctx.Credentials = System.Net.CredentialCache.DefaultCredentials;

//obter o aplicativo web

Web w = ctx.Web;

//CARREGAR LISTAS COM TODAS AS PROPRIEDADES

var lists = ctx.LoadQuery(w.Lists);

//executar a consulta

ctx.ExecuteQuery();

//enumerar os resultados

foreach (List theList in lists)

{

//fazer algo com cada lista

}

 

E é aqui que a mágica acontece:

 

void ctx_MixedAuthRequest(object sender, WebRequestEventArgs e)

{

try

{

              //adicionar o cabeçalho que diz ao SharePoint para usar a Autenticação do Windows

              e.WebRequestExecutor.RequestHeaders.Add(

"X-FORMS_BASED_AUTH_ACCEPTED", "f");

       }

       catch (Exception ex)

       {

              MessageBox.Show("Erro ao configurar o cabeçalho de autenticação: " + ex.Message);

       }

}

 

Isto é tudo; este código é realmente muito fácil e acho que é auto-explicativo. Fazer o mesmo com uma referência a Serviço Web padrão é um pouco diferente. Para começar, vamos acompanhar o processo de adição de uma referência da Web de estilo padrão em um site do SharePoint para um projeto no Visual Studio 2010:

1. Clique com botão direito do mouse no nó Referência de Serviço e selecione Adicionar Referência de Serviço.

2. Clique no botão Avançado na parte inferior da caixa de diálogo.

3. Clique no botão Adicionar Referência da Web... na parte inferior da próxima caixa de diálogo.

4. Digite a Url para o serviço Web que deseja usar na caixa de edição da URL; por exemplo, para adicionar uma referência ao serviço Web Listas no site https://foo, eu colocaria isto como a URL: https://foo/_vti_bin/lists.asmx.

5. Pressione Enter ou clique no botão de seta verde para localizar a referência ao serviço Web, então digite um nome para sua referência de serviço Web na caixa de edição de nome de referência da Web e clique no botão Adicionar Referência.

 

Suas classes de referência e de proxy para sua referência devem ser criadas agora, mas será preciso adicionar outra classe parcial para adicionar o cabeçalho à sua solicitação de serviço Web. Comece adicionando uma nova classe ao seu projeto e chame-a sempre que quiser. Uma vez que você só deseja adicionar outros comportamentos - adicionando um cabeçalho à sua solicitação - vai querer transformá-la em uma classe parcial. Isso significa que você precisa copiar ambos o namespace e o nome da classe usados no proxy criado para sua referência da Web. Veja as etapas para fazer isso:

 

1. Clique no botão Mostrar Todos os Arquivos na janela do Gerenciador de Soluções no Visual Studio.

2. Clique no sinal de mais ao lado da referência de serviço Web para expandi-la.

3. Clique no sinal de mais ao lado do arquivo Reference.map para expandi-lo.

4. Clique duas vezes no arquivo Reference.cs para abri-lo.

5. Copie o namespace e cole-o em sua classe.

6. Copie o nome de classe, incluindo herança, e cole-o em sua classe como seu nome de classe. A classe de referência de serviço Web já é uma classe parcial e, portanto, não há alterações a fazer aqui.

 

Veja um exemplo da aparência da minha classe Reference.cs para minha referência de serviço Web:

namespace ClientOmAuth.listsWS {

    using System;

    using System.Web.Services;

    using System.Diagnostics;

    using System.Web.Services.Protocols;

    using System.ComponentModel;

    using System.Xml.Serialization;

   

   

    /// <remarks/>

    [System.CodeDom.Compiler.GeneratedCodeAttribute("System.Web.Services", "4.0.30319.1")]

    [System.Diagnostics.DebuggerStepThroughAttribute()]

    [System.ComponentModel.DesignerCategoryAttribute("code")]

    [System.Web.Services.WebServiceBindingAttribute(Name="ListsSoap", Namespace="https://schemas.microsoft.com/sharepoint/soap/")]

    public partial class Lists : System.Web.Services.Protocols.SoapHttpClientProtocol {

E isto é o que colei na classe que criei:

namespace ClientOmAuth.listsWS

{

       public partial class Lists : System.Web.Services.Protocols.SoapHttpClientProtocol

       {

       }

}

Você observará como ambos o namespace e os nomes de classe correspondem e que ambas as classes estão herdando do mesmo tipo de base.

 

Agora você precisa substituir o método GetWebRequest para poder adicionar o cabeçalho. Isto é feito simplesmente adicionando este código à sua classe parcial:

protected override System.Net.WebRequest GetWebRequest(Uri uri)

{

       System.Net.WebRequest wr = null;

       try

       {

              wr = base.GetWebRequest(uri);

              wr.Headers.Add("X-FORMS_BASED_AUTH_ACCEPTED", "f");

       }

       catch (Exception ex)

       {

              //um pouco de manipulação de erros aqui

       }

                          

       return wr;

}

 

A codificação para recuperar os dados por meio do serviço Web agora está exatamente igual a qualquer site do SharePoint de autenticação do Windows:

 

//criar o proxy do serviço Web e configurá-lo para usar minhas credenciais do Windows

listsWS.Lists lws = new listsWS.Lists();

lws.UseDefaultCredentials = true;

//obter o conjunto de listas

XmlNode xLists = lws.GetListCollection();

//enumerar resultados

foreach (XmlNode xList in xLists.ChildNodes)

{

//fazer algo com cada Lista

}

E isto é tudo. Você também pode aplicar estas informações à recuperação de dados via REST, usando as técnicas descritas aqui: https://blogs.technet.com/b/speschka/archive/2010/09/25/retrieving-rest-data-in-a-claims-based-auth-site-in-sharepoint-2010.aspx.

 

Esta é uma postagem de blog traduzida. Encontre o artigo original em Retrieving Data from a Multi Auth Site Using the Client OM and Web Services in SharePoint 2010