Kit de integração de Declarações, Azure e SharePoint Parte 2

Kit de integração de Declarações, Azure e SharePoint Parte 2

Esta é a parte 2 de uma série de 5 partes sobre o Kit CASI (Integração de Declarações, Azure e SharePoint). A Parte 1 deu uma visão geral introdutória de toda a estrutura e solução e descreveu o que a série vai testar e abranger. Nesta postagem, vamos focalizar o padrão da abordagem:

1. Usar um aplicativo WCF personalizado como o front-end de dados e conteúdo

2. Torná-lo orientado a declarações

3. Fazer algumas alterações adicionais para poder move-lo para cima na nuvem do Windows Azure

Usando o WCF

A principal hipótese da estrutura Kit CASI é que todos os dados de aplicativos usam um aplicativo WCF como o front-end. Assim como todo aplicativo personalizado, esta é uma parte que você, o desenvolvedor, precisará criar. Não é necessário praticamente nenhum conhecimento específico sobre o SharePoint para esse parte do projeto – qualquer desenvolvedor .NET que consiga usar o Visual Studio para criar um aplicativo WCF poderá fazer isso. Se a sua meta primordial for hospedar o serviço WCF no Windows Azure, é altamente recomendável usar o kit de desenvolvimento do Windows Azure para baixar os modelos de criação de aplicativos Azure e então começar do zero a criação de um aplicativo WCF. Não há, aqui, nenhuma limitação importante ao entendimento da versão atual do Kit CASI. O kit CASI efetivamente só oferece suporte ao envio de tipos centrais de dados .NET como parâmetros para os métodos WCF. Assim, cadeias de caracteres, boolianos, inteiros e datas funcionam bem, porém, não há um método para passar uma classe personalizada como parâmetro. Se for preciso fazer isso, é recomendável criar o parâmetro como uma cadeia de caracteres e desserializar o parâmetro para XML antes de chamar o método WCF, serializando-o, depois, para uma instância de objeto no código do WCF. Além disso, não há qualquer limitação significativa que eu tenha detectado até o momento, mas certamente uma lista de necessidades surgirá muito em breve, na esteira desta cuja adoção e uso são mais gerais. Como uma breve observação à parte, o kit atual é composto, na verdade, apenas por minhas próprias ideias referentes à versão 1.0, sobre como podemos alinhavar esses aspectos. O kit foi projetado para atender aos cenários centrais que eu imaginei e decidi que eram importantes. Não tenho dúvidas de que haverá bastante espaço para melhorias conforme as pessoas o utilizem.

Torná-lo orientado a declarações

Depois de criado o aplicativo WCF, a próxima etapa será torná-lo orientado a declarações. Para essa etapa, o crédito não é absolutamente meu – peguei o caminho desde o início e indicarei a você a excelente postagem de blog, composta de quatro partes, que o Eric White, da equipe do Office, elaborou para descrever como integrar declarações do SharePoint a um aplicativo WCF. Pressupondo que você já criou seu serviço WCF, vou começar com a parte 2 da série de blogs do Eric, em https://blogs.msdn.com/b/ericwhite/archive/2010/05/13/determining-caller-identity-within-a-wcf-web-service.aspx. Além disso, você DEVE continuar e executar as etapas que ele descreve na parte 3, em https://blogs.msdn.com/b/ericwhite/archive/2010/06/18/establishing-trust-between-a-wcf-web-service-and-the-sharepoint-2010-security-token-service.aspx começando com a seção intitulada Procedimento: Estabelecer confiança entre o serviço Web e o SharePoint Server. Você precisa executar todas as etapas desse ponto em diante: copiar efetivamente a impressão digital do certificado de assinatura do token STS do SharePoint e copiar isto e algumas outras informações no arquivo web.config do aplicativo WCF. Eu não seguiria as etapas SSL da parte 3 passo a passo, porque o uso de um certificado autoassinado não será realmente útil quando o aplicativo for hospedado no Windows Azure. Se você não tiver nada disponível, então precisará fazer isso, mas, em geral, você deve planejar a obtenção de um certificado SSL adequado de uma autoridade de certificação apropriada ao seu aplicativo WCF do Windows Azure. OBSERVAÇÃO: Você NÃO precisa executar as etapas da parte 4 do blog do Eric. Agora que as etapas descritas acima foram executadas, você tem um aplicativo WCF funcional e orientado a declarações do SharePoint. No fase final desta postagem, orientarei você no passo a passo das etapas adicionais que são necessárias para mover para cima no Windows Azure.

Fazer funcionar no Windows Azure

Agora que o seu aplicativo WCF Azure já está funcionando, há alguns outros aspectos que precisam ser cuidados para que o aplicativo continue a oferecer suporte a autenticações baseadas em declarações e a tokens por meio do WIF (Windows Identity Framework) e também para hospedá-lo na nuvem do Windows Azure. Vamos neutralizar a lista aqui:

1. Configure o projeto WebRole (ou seja, o seu projeto WCF) para usar um diretório virtual local para depuração. Acho isso mais fácil de trabalhar do que o servidor de desenvolvimento VS.NET, para elementos que usam certificados, o que certamente preferirá fazer. Para alterar isso, clique duas vezes nas propriedades do projeto WebRole e clique na guia Web. Selecione o botão de opção “Use Local IIS Web server” (Usar Servidor Web do IIS Local) e clique no botão Create Virtual Directory (Criar Diretório Virtual). Depois de criado o diretório virtual, feche as propriedades do projeto.

2. Adicione uma referência ao Microsoft.Identity no projeto WebRole. Você DEVE alterar a referência para Copy Local = true (Copiar Local = verdadeiro) e Specific Version = false (Especificar Versão = falso). É necessário copiar o assembly WIF na nuvem com o pacote do aplicativo.

3. Obtenha este hotfix de WCF: https://code.msdn.microsoft.com/KB981002/Release/ProjectReleases.aspx?ReleaseId=4009 para Win2k8 R2, https://code.msdn.microsoft.com/KB971842/Release/ProjectReleases.aspx?ReleaseId=3228 para Win2k8.

4. Você DEVE adicionar este atributo à classe WCF: [ServiceBehavior(AddressFilterMode = AddressFilterMode.Any)]. Por exemplo, a classe tem esta aparência:

namespace CustomersWCF_WebRole

{

    [ServiceBehavior(AddressFilterMode = AddressFilterMode.Any)]

    public class Customers : ICustomers

    {

5. Você DEVE incluir os seguintes dados de configuração no elemento de comportamento usado pelo serviço. Isso corrige problemas que podem ocorrer com atribuições aleatórias de porta no ambiente do Azure. Para testar isso localmente, é preciso obter o hotfix descrito no item 3, acima:

      <useRequestHeadersForMetadataAddress>

            <defaultPorts>

              <add scheme="http" port="80" />

              <add scheme="https" port="443" />

            </defaultPorts>

          </useRequestHeadersForMetadataAddress>

Aqui está um exemplo de contexto do web.config do meu serviço WCF:

    <behaviors>

      <serviceBehaviors>

        <behavior name="CustomersWCF_WebRole.CustomersBehavior">

          <federatedServiceHostConfiguration name="CustomersWCF_WebRole.Customers"/>

          <serviceMetadata httpGetEnabled="true" httpsGetEnabled="true"/>

          <serviceDebug includeExceptionDetailInFaults="false"/>

          <useRequestHeadersForMetadataAddress>

            <defaultPorts>

              <add scheme="http" port="80" />

              <add scheme="https" port="443" />

            </defaultPorts>

          </useRequestHeadersForMetadataAddress>

        </behavior>

      </serviceBehaviors>

    </behaviors>

6. Carregue primeiro o certificado SSL que você está usando para o aplicativo WCF no portal do desenvolvedor do Azure. OBSERVAÇÃO: A classe base Kit CASI é conectada para usar SSL, portanto, você DEVE implementar o suporte a SSL no seu aplicativo WCF do Windows Azure. Otimisticamente, esse deve ser um requisito esperado para passar dados possivelmente confidenciais entre um serviço de nuvem e o farm do SharePoint. A seguir, adicione o certificado às propriedades de função do Azure no Visual Studio, clicando duas vezes no nome de projeto WebRole (na pasta Roles (Funções)). Para mim, o uso de um certificado curinga funcionou bem. Entretanto, é preciso um certificado PFX. Certifique-se de exportar todos os certificados da cadeia ao criar o arquivo PFX. O Azure os expandirá todos quando você carregá-lo no portal do desenvolvedor.

7. O certificado SSL deve ser algumNome.seuNomeDns.com, mesmo que todos os aplicativos do Azure estejam hospedados em cloudapp.net. Por exemplo, o meu certificado SSL era um certificado curinga para *.vbtoys.com. No DNS, criei um registro CNAME chamado azurewcf.vbtoys.com e ele referenciava myAzureApp.cloudapp.net. Dessa forma, quando faço uma conexão com https://azurewcf.vbtoys.com, meu certificado funciona porque minha solicitação e meu certificado SSL são para *.vbtoys.com, mas o DNS redireciona minha solicitação com base no registro CNAME, que é myAzureApp.cloudapp.net.

8. No seu projeto Azure, clique duas vezes no nome de projeto WebRole (na pasta Roles (Funções)) e defina essas propriedades da seguinte forma:

a. Guia Configuration (Configuração): desmarque Launch browser (Iniciar o navegador) para: ponto de extremidade HTTP e HTTPS

b. Guia Certificates (Certificados): adicione o certificado que você vai usar para SSL no seu serviço. Por exemplo, no meu laboratório, uso um certificado curinga que é emitido pelo meu domínio para todos os meus servidores Web, por isso, adicionei aqui o certificado curinga.

c. Guia Endpoints (Pontos de Extremidade): marque a caixa de HTTP e HTTPS (os nomes devem ser HttpIn e HttpsIn, respectivamente). Na seção HTTPS, a lista suspensa de nomes de certificados SSL agora deve conter o certificado SSL que você adicionou na etapa b.

9. Se você tiver um método WCF que retorne scripts, a marca de script deverá incluir o atributo DEFER para que isso funcione corretamente ao usar a Web Part incluída com o Kit CASI ou se a sua própria função JavaScript atribuí-la ao innerHTML de uma marca. Por exemplo, a marca de script deve ter esta aparência: <script defer language='javascript'>

10. Se você tiver um método WCF que retorne conteúdo incluindo outras marcas de formatação, como <estilo>, você precisará encapsulá-las em uma marca <pre>, caso contrário, elas não serão processadas corretamente ao usar a Web Part incluída com o Kit CASI ou se a sua própria função JavaScript atribuí-las ao innerHTML de uma marca. Por exemplo, o conteúdo que retorna uma marca de estilo deve ter esta aparência: <pre><style>.foo {font-size:8pt;}</style></pre>

Estas são as etapas necessárias para configurar o aplicativo WCF para hospedagem no Azure. Aqui estão algumas dicas adicionais que talvez sejam úteis e, em alguns casos, necessárias, dependendo da sua implementação:

1. Use o nome totalmente qualificado ao criar o endereço de ponto de extremidade que consome o serviço, ou seja, nomeMáquina.foo.com, em vez de somente nomeMáquina Isso fará a transição de maneira mais tranquila para o formato final hospedado no Windows Azure e, também, poderá eliminar erros ocorridos quando o seu certificado SSL foi designado para usar um nome de domínio totalmente qualificado.

2. PODE ser conveniente adicionar este atributo: httpsGetEnabled="true" a este elemento: <serviceMetadata httpGetEnabled="true" />, se quiser o obter seu WSDL sobre o SSL. Contudo, atualmente há um bug no SharePoint Designer que impede o uso de SSL para WSDL.

3. Para obter dicas de depuração e conexão de dados, consulte minha postagem em https://blogs.technet.com/b/speschka/archive/2010/09/19/azure-development-tips-for-debugging-and-connection-strings.aspx.

4. Na maioria dos casos, você deve pressupor que o namespace do seu serviço WCF será https://tempuri.org. Para obter instruções sobre como alterá-lo, leia a postagem em https://blogs.infosupport.com/blogs/edwinw/archive/2008/07/20/WCF_3A00_-namespaces-in-WSDL.aspx.

O serviço WCF concluído

Se você tiver executado todas as etapas de configuração acima e tiver implantado o aplicativo WCF no Windows Azure, quando um usuário fizer uma chamada para esse serviço WCF de um site do SharePoint, você também obterá o token completo desse usuário, com todas as declarações associadas a ele. Vale a pena observar que, após a realização dessas alterações, o serviço WCF também funcionará no local, assim, é muito fácil testar, caso você queira tentar algumas alterações incrementais antes de subir o aplicativo na nuvem. O token de usuário permite que você execute algumas ações realmente interessantes no seu serviço WCF. Por exemplo, no serviço WCF, é possível enumerar todas as declarações de um usuário e, com base nelas, tomar qualquer tipo de decisão referente a permissões refinadas. Aqui está um exemplo de uso de LINQ baseado no conjunto de declarações do usuário para determinar se o usuário atual é um administrador, pois, se ele for um administrador, algum nível adicional de detalhes será retornado na solicitação:

//procurar identidades baseadas em declarações

IClaimsIdentity ci =

System.Threading.Thread.CurrentPrincipal.Identity as IClaimsIdentity;

if (ci != null)

{

//verificar se há declarações antes de executar

       if (ci.Claims.Count > 0)

       {

       //procurar uma declaração de grupo de admin de domínio

var eClaim = from Microsoft.IdentityModel.Claims.Claim c in ci.Claims

              where c.ClaimType ==

"https://schemas.microsoft.com/ws/2008/06/identity/claims/role" &&

                     c.Value == "Domain Admins"

                     select c;

              //verificar se obtemos uma correspondência

              if (eClaim.Count() > 0)

              //há uma correspondência, portanto, esse usuário tem a declaração Admins de Domínio

                     //fazer algo aqui

}

}

O que também é interessante é que você pode criar demandas de permissão diretamente nos seus métodos WCF. Por exemplo, vamos supor que você tenha um método WCF que consulte um repositório de dados e retorne uma lista de diretores executivos. Você não quer disponibilizar essa informação para todos os funcionários, mas somente para os gerentes de vendas. Um jeito bem inteligente e fácil de implementar isso é com a demanda PrincipalPermission no método. Assim:

//a lista de CEOs do cliente não deve ser compartilhada com todas as pessoas,

//portanto, mostrá-la somente para as pessoas da função Gerente de Vendas

[PrincipalPermission(SecurityAction.Demand, Role = "Sales Managers")]

public string GetCustomerCEOs()

{

//seu código vai aqui

}

Agora, se alguém tentar chamar esse método e não tiver uma declaração para “Gerentes de Vendas”, ele obterá um acesso negado se estiver executando o código que tenta chamar o método. Muito legal!

Também é importante entender que isso não pode ser falsificado. Por exemplo, você não pode simplesmente criar seu próprio domínio em um laboratório, adicionar uma conta a ele e criar uma função Gerente de Vendas a ser adicionada a essa conta. O motivo por que isso não funcionará está nas etapas que você executou quando estudou o blog do Eric White (na seção acima, intitulada Torná-lo orientado a declarações). Relembrando, você adicionou a impressão digital do certificado de assinatura de token usado pelo STS do SharePoint. Isso significa que, quando uma declaração chega no seu aplicativo WCF, ela procura o token a ser assinado pela chave pública do STS do SharePoint. Somente o STS do SharePoint pode assiná-lo com essa chave pública, pois ele é a única entidade que tem a chave privada desse certificado de assinatura de token. Isso garante que somente uma pessoa autenticada nesse farm do SharePoint poderá usar o serviço WCF, e os usuários terão somente as declarações concedidas a eles no momento do logon. O que também é interessante é que esse recurso inclui não apenas as declarações concedidas aos usuários no momento da autenticação no diretório de usuários, mas TAMBÉM algumas outras declarações concedidas a eles por meio do aumento de declarações no SharePoint, com qualquer provedor de declarações personalizadas. Portanto, esta é efetivamente uma solução ponta a ponta totalmente integrada.

Próximas etapas

Na próxima postagem, começarei a descrever a classe base personalizada e a Web Part incluída no Kit CASI, as quais permitirão que você se conecte ao novo aplicativo Azure WCF com mais rapidez e facilidade. Além disso, a partir desse ponto, vou usar um serviço WCF que escrevi para o CASI Kit como uma forma de demonstrar a funcionalidade. Estou anexando a esta postagem o arquivo .cs que usei para esse serviço. Você não poderá usá-lo como está, mas o incluí para que você possa ver os vários métodos que ele contém, o tipo de dados e como determinados recursos foram implementados nesse kit. Principalmente durante as próximas postagens, você me verá usando os métodos a) GetAllCustomersHtml, b) GetCustomerCEOs e c) GetAllCustomers. Eles são interessantes porque a) retornam HTML (o que será, na prática, o tipo de retorno preferido para exibição de dados em Web Parts), b) usam uma demanda PrincipalPermission e c) mostram como você pode retornar um tipo de classe personalizada do seu aplicativo WCF e usar o mesmo tipo de classe avançada depois de obter esses dados novamente no SharePoint com o CASI Kit.

Esta é uma postagem de blog traduzida. O artigo original está em The Claims, Azure and SharePoint Integration Toolkit Part 2