9

Mam stronę internetową o nazwie internetowej, która wywołuje nową witrynę MVC6, nad którą pracujemy. Użytkownik zaloguje się, jak zawsze na stronie internetowej formularza, korzystając z uwierzytelniania formularzy, a następnie przekierowywany do nowej witryny MVC6. W MVC6 wiem, że powinienem używać uwierzytelniania plików cookie, ale nie mogę go odszyfrować. Podejrzewam, że to się zmieniło wokół web.config i machinekey, ale naprawdę utknąłem.MVC6 Odszyfrowywanie pliku cookie uwierzytelniania formularzy z innej strony internetowej

Oto, co zrobiłem.

mam skonfigurować uwierzytelnianie cookies następująco

 app.UseCookieAuthentication(options => 
     { 
      options.CookieName = "MyWebformsCookie"; 
      options.AutomaticAuthenticate = true; 
      options.AuthenticationScheme = "Cookies"; 
      options.TicketDataFormat = new MySecureDataFormat(); 
      options.DataProtectionProvider = new MyDataProtectionProvider(); 
      //options.CookieDomain = "localhost"; 
     }); 

Klasa jest następujący

public class MySecureDataFormat : ISecureDataFormat<AuthenticationTicket> 
{ 
    public string Protect(AuthenticationTicket data) 
    { 
     return string.Empty; 
    } 

    public string Protect(AuthenticationTicket data, string purpose) 
    { 
     return string.Empty; 
    } 

    public AuthenticationTicket Unprotect(string protectedText) 
    { 
     return null; 
    } 

    public AuthenticationTicket Unprotect(string protectedText, string purpose) 
    { 
     var ticket = FormsAuthentication.Decrypt(protectedText); 
     return null; 
    } 
} 

cookie jest odczytywany, a chroń metodę nazywa, ale to błędy na FormsAuthentication Metoda .Decrypt z błędem

Wystąpił wyjątek typu "System.Web.HttpException" w System.Web.dll, ale nie został obsłużony w kodzie użytkownika

Informacje dodatkowe: Nie można zweryfikować danych.

stos = w System.Web.Configuration.MachineKeySection.EncryptOrDecryptData (logiczna fEncrypt, bajt [] buf, bajt [] modyfikator początek Int32, długość Int32, logiczna useValidationSymAlgo, logiczna useLegacyMode, IVType ivType, logiczna signData) w System.Web.Security.FormsAuthentication.Decrypt (ciąg encryptedTicket) w WebApplication.Mvc.MySecureDataFormat.Unprotect (string protectedText, zastosowania łańcuchach) w C: \ SVNCode \ GlobalConnectV2 \ WebApplication.Mvc \ Startup.cs: linia 153
o Microsoft.AspNet.Authentication.Cookies.CookieAuthenticationHandler.d__9.MoveNext()

Więc to prowadzi mnie do przypuszczenia, że ​​jej nie czyta klucza maszynowego. Mam to w pliku web.config w folderze wwwroot

<configuration> 
    <system.webServer> 
    ... 
    </system.webServer> 
    <system.web> 
    <machineKey compatibilityMode="Framework20SP2" validation="SHA1" decryption="AES" validationKey="mykey" decryptionKey="dec" /> 
    </system.web> 
</configuration> 

To działa na wcześniejsze aplikacje MVC ale zgadywania coś się zmieniło w MVC6. Próbowałem również następujących, ale bez powodzenia

services.ConfigureDataProtection(configure => 
    { 
     configure.UseCryptographicAlgorithms(new Microsoft.AspNet.DataProtection.AuthenticatedEncryption.AuthenticatedEncryptionOptions() 
     { 
      EncryptionAlgorithm = Microsoft.AspNet.DataProtection.AuthenticatedEncryption.EncryptionAlgorithm.AES_256_CBC, 
      ValidationAlgorithm = Microsoft.AspNet.DataProtection.AuthenticatedEncryption.ValidationAlgorithm.HMACSHA256 
     }); 

    }); 

Jakaś radę?

Odpowiedz

8

Nie miałem radości próbując użyć FormsAuthentication.Decrypt() w aplikacji ASP.NET 5.

W końcu napisałem procedurę odszyfrowywania, opartą na dostępnej dokumentacji, a także sprawdzając źródłowy kod źródłowy, który Microsoft udostępnił dla sieci systemowej.

Zajęcia wymagane do odszyfrowania pliku cookie uwierzytelniania formularzy, który wykorzystuje SHA1 walidacji oraz AES do szyfrowania, można znaleźć na mojej GIST tutaj: https://gist.github.com/dazinator/0cdb8e1fbf81d3ed5d44

Gdy masz te można utworzyć niestandardową TicketFormat jak poprzednio :

public class FormsAuthCookieTicketFormat : ISecureDataFormat<AuthenticationTicket> 
{ 

    private LegacyFormsAuthenticationTicketEncryptor _Encryptor; 
    private Sha1HashProvider _HashProvider; 

    public FormsAuthCookieTicketFormat(string decryptionKey, string validationKey) 
    { 
     _Encryptor = new LegacyFormsAuthenticationTicketEncryptor(decryptionKey); 
     _HashProvider = new Sha1HashProvider(validationKey); 
    } 

    public string Protect(AuthenticationTicket data) 
    { 
     throw new NotImplementedException();    
    } 

    public string Protect(AuthenticationTicket data, string purpose) 
    { 
     throw new NotImplementedException(); 
    } 

    public AuthenticationTicket Unprotect(string protectedText) 
    { 
     throw new NotImplementedException(); 
    } 

    public AuthenticationTicket Unprotect(string protectedText, string purpose) 
    { 
     var ticket = _Encryptor.DecryptCookie(protectedText, _HashProvider); 

     var identity = new ClaimsIdentity("MyCookie"); 
     identity.AddClaim(new Claim(ClaimTypes.Name, ticket.Name)); 
     identity.AddClaim(new Claim(ClaimTypes.IsPersistent, ticket.IsPersistent.ToString())); 
     identity.AddClaim(new Claim(ClaimTypes.Expired, ticket.Expired.ToString())); 
     identity.AddClaim(new Claim(ClaimTypes.Expiration, ticket.Expiration.ToString())); 
     identity.AddClaim(new Claim(ClaimTypes.CookiePath, ticket.CookiePath)); 
     identity.AddClaim(new Claim(ClaimTypes.Version, ticket.Version.ToString()));   

     // Add some additional properties to the authentication ticket. 
     var props = new AuthenticationProperties(); 
     props.ExpiresUtc = ticket.Expiration.ToUniversalTime(); 
     props.IsPersistent = ticket.IsPersistent; 

     var principal = new ClaimsPrincipal(identity); 

     var authTicket = new AuthenticationTicket(principal, props, CookieDetails.AuthenticationScheme); 
     return authTicket; 
    } 

i drutu go tak:

var formsCookieFormat = new FormsAuthCookieTicketFormat(_DecryptionKeyText, _ValidationKeyText); 

     app.UseCookieAuthentication(options => 
     { 
      // shortened for brevity... 
      options.TicketDataFormat = formsCookieFormat ; 
      options.CookieName = "MyCookie";     
     }); 
+0

Dziękuję za rozwiązanie, to ułatwiło mi dzień. Czy mogę używać kodu źródłowego w moich projektach? Z góry bardzo dziękuję. – Anil

+0

Część kodu deszyfrowania jest niesamowita i działa dobrze. Próbuję użyć części Encryption Twojego kodu, Masz pewien problem z sprawdzaniem poprawności podpisu. Czy działa dobrze po twojej stronie? Czy masz jakieś działające przykłady udostępniania – Anil

+0

Szyfrowanie i odszyfrowywanie formularzyAuth Cookie działa teraz idealnie w AspDotNetCore +1 @Darrell – Anil

0

Po uwierzytelnieniu użytkownika, należy ustawić domenę pliku cookie uwierzytelniania na domenę drugiego poziomu, np. Parent.com (strona asp.net). Każda poddomena (witryna MVC) otrzyma pliki cookie domeny nadrzędnej na żądanie, więc uwierzytelnianie na każdym z nich jest możliwe, ponieważ będziesz mieć wspólny plik cookie do uwierzytelniania, z którym będziesz mógł pracować.

kod uwierzytelniania:

System.Web.HttpCookie authcookie = System.Web.Security.FormsAuthentication.GetAuthCookie(UserName, False); 
authcookie.Domain = "parent.com"; 
HttpResponse.AppendCookie(authcookie); 
HttpResponse.Redirect(System.Web.Security.FormsAuthentication.GetRedirectUrl(UserName, 
                    False)); 

Patrz pytanie Forms Authentication across Sub-Domains

i ASP.NET webforms and MVC authentication sharing via cookie

+0

Dzięki za szybką odpowiedź, jednak używam narzędzia wizualne cookies i widzi Domena cookie to moja strona asp.net. Ustawiłem cookiedomain tak, aby pasowało do opcji Cookie Authentication. Osiągnięto wartość zaszyfrowanego pliku cookie, po prostu nie mogę go odszyfrować – Punchmeister

+0

Czy jest to związane z dodaniem web.config; EnableViewStateMAC = false – Anil

+0

Jak robisz to corretly problem ten występuje również wtedy, gdy spełnione są następujące warunki: HKEY_LOCAL_MACHINE \ SYSTEM \ CurrentControlSet \ Control \ Lsa \ fipsalgorithmpolicy podklucz rejestru jest ustawiony na 1. ASP.NET 2.0 wykorzystuje RijndaelZarządzanie wdrażaniem algorytmu AES podczas przetwarzania danych stanu widoku. algorytm AES nie jest częścią sprawdzonych algorytmów kryptograficznych FIPS platformy Windows. zobacz https://support.microsoft.com/en-us/kb/911722 – Anil

3

Jest whole section of documentation on docs.asp.net o nazwie Replacing machineKey.

Ma to głównie związek z pakietem Microsoft.AspNet.DataProtection.SystemWeb.

Będziesz wtedy mógł ustawić klucz w kodzie lub w konfiguracji i móc odczytać te pliki cookie bezpośrednio z .

Oto przykładowy kod (z dokumentacją), w jaki sposób to zrobić:

public override void ConfigureServices(IServiceCollection services) 
{ 
    services.ConfigureDataProtection(configure => 
    { 
     configure.SetApplicationName("my-app"); 
     configure.PersistKeysToFileSystem(new DirectoryInfo(@"\\server\share\myapp-keys\")); 
     configure.ProtectKeysWithDpapi(); 
    }); 
} 

Oczywiście trzeba dodać wcześniej wspomniany pakiet na liście zależnościami i które mogą zmusić Cię do korzystania z systemu Windows (nie jestem pewien, ale kompiluje się w CoreClr).

Nie będzie to działać z istniejącym kluczem MachineKey, ale wygeneruje nowy zestaw, który pozwoli na rozpoczęcie pracy.

+1

Pytanie dotyczyło konkretnie witryny MVC 6 (ASP.NET 5) i jako takie nie ma pliku web.config. Łączona dokumentacja nie wyjaśnia, w jaki sposób korzystać z biblioteki DataProtection (np.e przez kod lub przez config) w tym scenariuszu. – Darrell

+0

To robi. Dodano fragment kodu ze strony dokumentacji i dodano więcej szczegółów. –

+2

Nie. Pakiet Microsoft.AspNet.DataProtection.SystemWeb jest przeznaczony specjalnie dla środowiska ASP.NET 4.5 (.net 4.5.1). Dokumentacja powiązana z tym programem dotyczy programu ASP.NET 4.5. Przeczytaj - ta cała sekcja jest faktycznie nazywana "zastępowaniem klucza komputera w ASP.NET 4.5.1" - przewiń w dół i przeczytaj komentarze poniżej, a zobaczysz, jak wyjaśniam się z chłopakami Microsoftu. Przeczytaj http://docs.asp.net/en/latest/security/data-protection/introduction.html, który mówi ci również, że Microsoft.AspNet.DataProtection.SystemWeb jest dla ASP.NET 4.X Możesz użyć DataProtection w ASP.NET 5 również, ale .. – Darrell