Minhas palestras no TDC 2016 de São Paulo

(UPDATE 09/07/2016: Slides das palestras de .NET e Testes disponíveis no corpo do post)

Pessoal, nesta semana começa a edição de 2016 do The Developers Conference (TDC) em São Paulo.

Mais uma vez terei o privilégio de poder palestrar nesse que já é um dos maiores eventos (se não o maior evento) para desenvolvedores do Brasil. Será que vamos nos encontrar lá?

Continue lendo “Minhas palestras no TDC 2016 de São Paulo”

Dica de solução de erro de ADFS com ASP.NET MVC

image
228

ADFS é uma ferramenta bem bacana – em especial porque, com ele, podemos continuar usufruindo de Autenticação Integrada do Windows para aplicações Web hospedadas fora da empresa (como no Windows Azure) sem precisar expor nossos controladores de domínio ao mundo.

Junte-se a isso o fato de que ADFS oferece CBA (claims-based authentication) baseada em padrões (WS-Trust, WS-Federation) e temos aí uma ótima solução de autenticação interoperável e segura.

Entretanto, isso não quer dizer que seja fácil de implementar.

O problema

Para fazer uns testes com o ADFS (para uma prova de conceito que estou conduzindo), segui o excelente tutorial disponível em http://garymcallisteronline.blogspot.com.br/2013/01/aspnet-mvc-4-adfs-20-and-3rd-party-sts.html. Em linhas gerais:

  1. Criei um novo projeto ASP.NET MVC (Intranet Application);
  2. Configurei minha aplicação para conectar ao ADFS;
  3. Configurei o ADFS para criar a relação de confiança com a minha aplicação.

Até aqui, super-tranquilo. Não fosse o fato de que, quando tentei acessar meu website de teste, me deparei com o seguinte erro:

image
292

E agora? Como descobrir o problema? Meu primeiro reflexo foi logar no servidor de ADFS, abrir o Event Viewer e procurar pelo erro (no Event Viewer, vá a “Applications and Services LogsAD FSAdmin”). Porém, o que encontrei foi isto aqui:

The Federation Service encountered an error while processing the WS-Trust request.
Request type:
http://schemas.xmlsoap.org/ws/2005/02/trust/RST/Issue

Additional Data
Exception details:
Microsoft.IdentityServer.Framework.SecurityTokenService.FailedAuthenticationException: MSIS3055: The requested relying party trust ‘
https://<meu-pc>.lambda3.com.br/AdfsTest/’ is unspecified or unsupported. If a relying party trust was specified, it is possible the user does not have permission to access the relying party trust. —> Microsoft.IdentityServer.Service.Policy.PolicyServer.Engine.ScopeNotFoundPolicyRequestException: MSIS3020: The relying party trust with identifier ‘https://<meu-pc>.lambda3.com.br/AdfsTest/’ could not be located.
— End of inner exception stack trace —
at Microsoft.IdentityServer.Service.Policy.PolicyServer.Engine.PolicyStoreClient.PolicyModelStore.BeginGetScopeDescription(Uri scope, AsyncCallback callback, Object state)
at Microsoft.IdentityServer.Service.Policy.PolicyServer.Engine.PolicyRequestor.BeginGetScope(AsyncCallback callback, Object state)
at Microsoft.IdentityServer.Service.SecurityTokenService.MSISSecurityTokenService.BeginGetScope(ClaimsPrincipal principal, RequestSecurityToken request, AsyncCallback callback, Object state)
at System.IdentityModel.SecurityTokenService.BeginIssue(ClaimsPrincipal principal, RequestSecurityToken request, AsyncCallback callback, Object state)
at System.ServiceModel.Security.WSTrustServiceContract.DispatchRequestAsyncResult..ctor(DispatchContext dispatchContext, AsyncCallback asyncCallback, Object asyncState)
at System.ServiceModel.Security.WSTrustServiceContract.BeginDispatchRequest(DispatchContext dispatchContext, AsyncCallback asyncCallback, Object asyncState)
at System.ServiceModel.Security.WSTrustServiceContract.BeginProcessCore(Message requestMessage, WSTrustRequestSerializer requestSerializer, WSTrustResponseSerializer responseSerializer, String requestAction, String responseAction, String trustNamespace, AsyncCallback callback, Object state)

Microsoft.IdentityServer.Service.Policy.PolicyServer.Engine.ScopeNotFoundPolicyRequestException: MSIS3020: The relying party trust with identifier ‘https://<meu-pc>.lambda3.com.br/AdfsTest/’ could not be located.

Relying party trust could not be located”? Mas tenho certeza que fiz tudo certinho! Já tinha feito isso outras vezes…

Primeira coisa a fazer era ligar o log de diagnósticos do ADFS. Para isso, no Event Viewer, localize o log “Applications and Services LogsAD FS TracingDebug”. Clique nele com o botão direito e selecione Enable Log:

Habilitando o log diagnóstico do ADFS
244

Analisando o log de diagnósticos, encontrei apenas este (não muito útil) erro:

Failed to process returned scope with error:
MSIS3055: The requested relying party trust ‘http://<meu-pc>.lambda3.com.br/AdfsTest/’ is unspecified or unsupported. If a relying party trust was specified, it is possible the user does not have permission to access the relying party trust.
at System.IdentityModel.AsyncResult.End(IAsyncResult result)
at System.IdentityModel.TypedAsyncResult`1.End(IAsyncResult result)
at Microsoft.IdentityServer.Service.Policy.PolicyServer.Engine.PolicyStoreClient.PolicyModelStore.EndGetScopeDescription(IAsyncResult asyncResult)
at Microsoft.IdentityServer.Service.Policy.PolicyServer.Engine.PolicyRequestor.OnGetScopeDescriptionComplete(IAsyncResult asyncResult)

Considerando que:

  1. Eu tinha certeza que tinha especificado a relação de confiança; e
  2. Como era uma para fins de desenvolvimento, tinha dado acesso total a qualquer usuário.

Então a mensagem de erro não ajudava muito. Ja havia conferido inúmeras vezes as configurações do servidor e o web.config da minha aplicação de testes.

A solução

Foi quando me deu o estalo. “Como o ADFS é baseado em web service e, por extensão, em XML, será que ele é sensível à caixa?”

E aí reparei que:

Reparou a diferença? O nome do diretório estava com caixas diferentes! Foi só deixar tudo igual (no web.config e no ADFS) que, magicamente, a aplicação começou a funcionar:

image
484

Conclusão

Quando você for criar aplicações ASP.NET integradas ao ADFS, fique de olho na caixa dos seus URLs. Na dúvida, coloque tudo sempre em minúsculas!

Um abraço,
Igor

RegistryMonitor (ou “como monitorar alterações em chaves do Registry”)

Recentemente deparei-me com a seguinte situação:

Estou desenvolvendo um addin para o Outlook, e quero que ele tenha uma aparência consistente com o esquema de cores em uso no Office 2007 / 2010. Para isso, tenho dois requisitos:

  1. Preciso saber qual o esquema de cores (Preto, Azul, Prata) está atualmente selecionado;
  2. Caso o usuário mude o esquema de cores, preciso ser notificado para que meu addin possa reagir de acordo.

Com relação ao requisito número um, a resposta está no post “Setting the BackColor to match the Office 2007 color scheme”. Nele descobri que o tema atualmente selecionado está gravado em uma chave no Registry – extremamente fácil de ler a partir do meu addin.

Agora, o segundo requisito. Como saber se o usuário mudou o esquema de cores? Bom, não há nenhum evento para isso. O Office (neste caso, o Outlook) simplesmente muda o valor da chave no Registry e reflete as alterações na sua UI. Portanto, eu precisava de um mecanismo para monitorar o Registry e ser notificado em caso de alterações nas chaves HKEY_CURRENT_USERSoftwareMicrosoftOffice12.0CommonTheme (2007) ou HKEY_CURRENT_USERSoftwareMicrosoftOffice14.0CommonTheme (2010).

É aí que entra um excelente artigo no CodeProject:

RegistryMonitor – a .NET wrapper class for RegNotifyChangeKeyValue – CodeProject

Boa codificação!
Igor