Migrando para o ASP.NET Core? Não é necessário migrar todo o projeto de uma única vez, utilize migrações modulares e compartilhe o Cookie de autorização de usuários.
O ASP.NET Core está pronto e muitas demandas de migração de projetos ASP.NET 4.X para a nova plataforma irão surgir. Como planejar e executar esta migração?
Uma migração total pode ser complexa, afinal vai exigir a alocação de diversas pessoas e enquanto isto as duas aplicações precisarão receber futuras implementações. Alguns projetos são tão grandes que simplesmente não seriam migrados se esta fosse a única alternativa, seria impossível atender as duas demandas simultaneamente.
Por que não ter duas aplicações?
Não há motivos para uma migração total se sua aplicação já funciona bem. Portar parcialmente módulos da aplicação para um projeto ASP.NET Core é uma alternativa bem mais interessante e que vai exigir muito menos esforço.
Imagine que em sua aplicação o módulo de gestão de Produtos funciona no ASP.NET MVC 5 e o módulo de gestão de Clientes no ASP.NET Core, o usuário final mal poderá perceber a diferença!
Integração de dados entre duas aplicações.
Certo! Posso migrar parcialmente, mas como faço a integração entre os dados que estão em aplicações diferentes?
Uma aplicação que utiliza uma boa arquitetura e uma boa modelagem estratégica pode facilmente integrar diversas entidades através dos ORM’s. Se a aplicação possuir uma modelagem DDD cada Bounded Context resolve seus próprios problemas, migre um BC de cada vez! (está mais fácil do que você imagina).
Compartilhando o usuário entre duas aplicações
Este é o grande foco da abordagem que apresento, como realizar uma integração para uma aplicação ASP.NET Core compartilhar o mesmo usuário de uma aplicação ASP.NET MVC 5.
Disponibilizei um novo repositório no meu GitHub com o projeto AspNetInterop este projeto implementa exatamente este cenário onde duas aplicações ASP.NET Core 1.1 e ASP.NET MVC 5 compartilham o mesmo Usuário, Cookies, Claims e Token para o AntiForgery.
Para reproduzir este projeto você precisa utilizar alguns Nuget Packages
- ASP.NET MVC 5
- Instale o pacote Microsoft.Owin.Security.Interop
- ASP.NET Core
- Instale o pacote Microsoft.AspNetCore.DataProtection.Extensions
Utilize o mesmo Cookie entre as aplicações
Esta abordagem faz a utilização do ASP.NET Identity, mas é possível produzir o mesmo resultado utilizando somente as classes do Microsoft.Owin.Security.
O importante é setar o mesmo cookie entre as duas aplicações:
services.AddIdentity<ApplicationUser, IdentityRole>(options => { options.Cookies = new Microsoft.AspNetCore.Identity.IdentityCookieOptions { ApplicationCookie = new CookieAuthenticationOptions { AuthenticationScheme = "Cookie", LoginPath = new PathString("/Account/Login/"), AccessDeniedPath = new PathString("/Account/Forbidden/"), AutomaticAuthenticate = true, AutomaticChallenge = true, CookieName = ".AspNet.SharedCookie" // If you have subdomains use this config: CookieDomain = "localhost" }; }) .AddEntityFrameworkStores<ApplicationDbContext>() .AddDefaultTokenProviders();
É necessário que as aplicações rodem no mesmo nome de domínio, se você tiver sub-dominios para cada aplicação basta setar a raíz do domínio em CookieDomain.
Selecione um repositório para Data Protection
O exemplo está utilizando um diretório como repositório, mas o ASP.NET Core 1.1 já suporta Redis, Azure Blob Storage e Azure Key Vault.
No ASP.NET MVC 5 além de configurar o Identity para utilizar o mesmo cookie (verifique implementação no código fonte) é necessário configurar o AntiForgery para que o usuário consiga utilizar a mesma chave entre as aplicações, para isto é necessário esta configuração no Global.asax
AntiForgeryConfig.UniqueClaimTypeIdentifier = ClaimTypes.NameIdentifier;
O AntiForgery faz a validação baseada em claims e no cookie do usuário logado.
Migre o módulo de gestão de usuários primeiro
Para utilizar este recurso é importante que esteja utilizando o ASP.NET Core com o ASP.NET Identity 3.0, portanto eu sugiro que este seja o primeiro módulo a ser migrado. A implementação deste projeto compartilha a mesma base do ASP.NET Identity entre as aplicações.
Esta implementação foi baseada no repositório idunno.CookieSharing do qual o Scott Hanselman faz parte dos integrantes. O projeto que disponibilizo no repositório AspNetInterop é uma melhoria da implementação original, no meu projeto as melhorias implementadas foram:
- Utilização do ASP.NET Identity ao invés do Cookie Middleware
- Implementação de controle de acesso com base em claims para o ASP.NET Core e ASP.NET MVC 5 (cada um possui uma implementação diferente devido a forma de autorizar usuários no ASP.NET Core ter mudado)
- Compartilhamento do Cookie no AntiForgery
- CRUD’s de entidades em cada aplicação
- Navegação integrada para o usuário não notar a mudança
Este projeto não conta com divisão em camadas para implementar separação de responsabilidades de Dados, Negócios e etc, porém é muito simples de implementar, pois isto não gera impacto na implementação existente.
Código fonte
Caso esteja interessado em conhecer mais sobre ASP.NET, DDD, Padrões de Arquitetura como CQRS, Event Sourcing e boas práticas de desenvolvimento não deixe de conferir as ementas dos meus cursos:
Vamos continuar a troca de experiências, deixe seu comentário abaixo. Se gostou e concorda com o artigo, compartilhe com seus colegas para transmitirmos o conhecimento para o máximo de pessoas possíveis.
Parabéns pela material, seria possível fazer algo semelhante com o sistema atual feito em webforms ?
Olá com webforms não seria possível devido as diferenças de plataforma.
Abs!
Como sugerido no projeto Equinox, utilizando Identity Server, poderia ainda continuar usando normalmente a autenticação e migrando os outros BC 😀
IdentityServer++
Mas não deixa de ser uma ótima solução para projetos que utilizam asp.net identity usando cookies
Att
Olá Eduardo:
Para um novo projeto você recomendaria começar a usar o Core 1.1 ou usar MVC 5?
Abs!
Bem interessante
Valeu pelo artigo Eduardo, me deu um norte, mas ainda tenho dúvida se é possível implementar uma web api em .net core utilizando a autenticação (cookie) da aplicação .net mvc, os dois web api e aplicação .net mvc, estarão em subdomínios diferente. Valeu!