Note
Access to this page requires authorization. You can try signing in or changing directories.
Access to this page requires authorization. You can try changing directories.
Recentemente, reparei um problema fora do comum ao usar o Serviço de Repositório Seguro (SSS) em um provedor de declarações personalizadas em que estava trabalhando. Na realidade, esse é um cenário interessante porque eu estava fazendo o que muita gente quer fazer: aumento de declarações. Eu precisava me conectar a uma fonte da dados remota para poder consultar informações adicionais sobre cada usuário e depois usar isso para determinar quais declarações aumentar ou não.
Como guia geral para usar fontes de dados em provedores de declarações personalizadas, é importante lembrar que o assembly do provedor de declaração personalizada continuará se mantendo ativado na memória pelo processo SharePoint STS. Isso torna muito mais fácil a recuperação de "informações" (quer seja um conjunto de dados, um conjunto de credenciais, etc.) por meio do armazenamento delas em uma variável de nível de classe, e depois elas ficam disponíveis para uso até o próximo IISRESET. A grande limitação aqui é que nem todos os recursos do farm do SharePoint podem estar disponíveis para você quando a classe do provedor de declaração personalizada for instanciada, e essa é a moral da história de hoje.
Nesse caso em particular, eu queria recuperar os dados do SSS do construtor para o meu provedor de declaração personalizada, e depois ia fazer outras coisas com eles; no meu caso, eu estava criando uma WindowsIdentity de um domínio em uma confiança unilateral para que eu pudesse usá-la para criar um contexto de representação com permissões para consultar o Active Directory remoto. Onde o problema ocorreu foi quando eu tentei fazer uma coisa com a referência para o SSS no construtor e ela SEMPRE expirava. Não importava qual método era chamado no SSS, ela simplesmente sempre falhava após 60 segundos com um erro de tempo limite.
Para consertar, bastou mover o código para fora do construtor. O mesmo código exato funcionou perfeitamente quando chamado do override do método FillClaimsForEntity. Foi por pura sorte e usando o método de tentativa e erro que eu descobri isso, então me pareceu uma boa dica para compartilhar.
Já que estamos falando sobre esse problema em particular (fazer logon em um domínio remoto e representação), então acho que vale a pena demonstrar um outro padrão que usei como solução, e uma pegadinha.
Conforme descrito acima, como o assembly permanece carregado no processo STS, é possível "manter ativadas" as variáveis de nível de classe. Como por motivos óbvios eu não queria ficar fazendo logon repetidamente no domínio remoto quando precisava consultá-lo, criei uma variável de nível de classe para a minha WindowsIdentity. O padrão ficou mais ou menos assim:
- Veja se já recuperou as credenciais SSS
- Caso negativo, execute o código que:
- Recupera as credenciais do SSS
- Usa a API LogonUser para fazer logon no domínio remoto usando as credenciais do SSS
- Instancia a variável WindowsIdentity para que tenha as credenciais do usuário remoto
- Caso negativo, execute o código que:
- Verifique se a variável WindowsIdentity é nula ou não
- Se não for, execute o código que:
- Cria uma nova instância de um WindowsImpersonationContext de WindowsIdentity.Impersonate()
- Consulta o domínio remoto
- Chama Undo em WindowsImpersonationContext
- Se não for, execute o código que:
Esse padrão parece funcionar bem e é o melhor desempenho que eu consegui até agora. Agora aqui está a pegadinha: você não quer chamar Impersonate() na instância WindowsIdentity e por isso NÃO chama Undo em WindowsImpersonationContext depois. Se você não desfizer a representação, então pelo que sei o site não vai renderizar mais. Adicione e o evento Undo e tudo voltará ao normal.
Esta é uma postagem de blog traduzida. Consulte o artigo original em Using Secure Store Service in a Custom Claims Provider with SharePoint 2010