0

ASP.NET Core 8 MVC application uses cookie authentication defined in startup.cs:

services.AddDataProtection().PersistKeysToFileSystem(new DirectoryInfo(@"Voti"));

services.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme)
    .AddCookie(options =>
        {  
            options.DataProtectionProvider = DataProtectionProvider.Create(new DirectoryInfo(@"Voti"));
            options.Cookie = new CookieBuilder()
                {
                    Name = ".EevaAuth",
                    IsEssential = true,
                    SameSite = SameSiteMode.Strict
                };
            options.LoginPath = new PathString("/Account/LogOn");
            options.ReturnUrlParameter = "returnUrl";
            options.SlidingExpiration = true;
            options.ExpireTimeSpan = TimeSpan.FromDays(30);
       });

Controller parses its own log files. Log files contain auth

How to manually decrypt an ASP.NET Core Authentication cookie?

http request log files log http requests. Log contains authentication cookies in header like

Cookie: .EevaAuth=CfDJ8ArEl-fh9A1DvMRTXwPoRF9c7eL8Jfy0__CVs5Fm_zPCFzpDmZbQFE-Y9hqt5YbWMLwJo0jL99KPOVp1xp1rTm6FOgozhmZU6yAVY7KMzNDeb1MCrp7QqzlVABXkYPo-2nTgFDGEYTqp_2iKJ6Kb54eWFhV4tYHWCDSNdwvNWUS2R6uekt9q6nj2rz8hfA4K2uh1tAoW_NkJFfEbc8mYhOoIQrlnSv9ZUPafywn2EI2MR-33k08i-GqI6ZwU9oA7yndywhh_VwEq0oJ-xMm0vCpJsjQdzEjdKH-gJufGy-BdHeEmpzepvTiUjPWGl3XNIHtjzxvTF_J-78oou5173BgbGqggAHCf9BeGWbZL0LTlo54etO5QbSYtRFr3P3AHWg

Trying to decrypt cookie using code from How to manually decrypt an ASP.NET Core Authentication cookie?

public string DecryptCookie()
{ 
    var provider = DataProtectionProvider.Create(new DirectoryInfo(@"Voti"));
    string cookieValue = HttpContext.Request.Cookies[".EevaAuth"];
    var dataProtector = provider.CreateProtector(
        "Microsoft.AspNetCore.Authentication.Cookies.CookieAuthenticationMiddleware", ".EevaAuth", "v2");
    UTF8Encoding specialUtf8Encoding = new UTF8Encoding(false, true);
    byte[] protectedBytes = Base64UrlTextEncoder.Decode(cookieValue);
    byte[] plainBytes = dataProtector.Unprotect(protectedBytes);
    string plainText = specialUtf8Encoding.GetString(plainBytes);
    return plainText;
}

This code throws an exception:

System.Security.Cryptography.CryptographicException: The payload was invalid. For more information go to https://aka.ms/aspnet/dataprotectionwarning

at Microsoft.AspNetCore.DataProtection.Cng.CbcAuthenticatedEncryptor.DecryptImpl(Byte* pbCiphertext, UInt32 cbCiphertext, Byte* pbAdditionalAuthenticatedData, UInt32 cbAdditionalAuthenticatedData)
at Microsoft.AspNetCore.DataProtection.Cng.Internal.CngAuthenticatedEncryptorBase.Decrypt(ArraySegment1 ciphertext, ArraySegment1 additionalAuthenticatedData)
at Microsoft.AspNetCore.DataProtection.KeyManagement.KeyRingBasedDataProtector.UnprotectCore(Byte[] protectedData, Boolean allowOperationsOnRevokedKeys, UnprotectStatus& status)
at Microsoft.AspNetCore.DataProtection.KeyManagement.KeyRingBasedDataProtector.Unprotect(Byte[] protectedData)
at MyApp.Controllers.Erp.AboutController.DecryptCookie()

How to decrypt a .NET 8 cookie? Authentication is same application where it was created for other user

Update

This is single .ASP.NET 8 application running in different servers having different DNS names. Key file in Voti directory is same.

Code in answer throws Payload exception.

Tried also

var opt = httpContextAccessor.HttpContext.RequestServices
        .GetRequiredService<IOptionsMonitor<CookieAuthenticationOptions>>()
        .Get(CookieAuthenticationDefaults.AuthenticationScheme);
    //or use .Get("Cookies")
    opt.Cookie.Path = "/";
    opt.Cookie.Domain = "otherserver.com";
    AuthenticationTicket t = opt.TicketDataFormat.Unprotect(cookie);
    if (t == null)
      throw new Exception("This exception occurs always if cookie is from other server");
    // Works only for same server cookies:
    return t.Principal.Identity.Name;

This works in same server. For other server cookies Unprotect returns null.

How to get user name from other server cookie ?

1 Answer 1

1
 services.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme)
    .AddCookie(options =>
        {  
           ...

Refer to cookie authentication, when setting the cookie authentication using CookieAuthenticationDefaults.AuthenticationScheme, by default the AuthenticationScheme value is set to "Cookies".

So, when create a data protector, we need to use the "Cookies" scheme, instead of using ".EevaAuth".

To solve the problem, you can modify the code as below:

public string DecryptCookie()
{ 
    var provider = DataProtectionProvider.Create(new DirectoryInfo(@"Voti"));
    string cookieValue = HttpContext.Request.Cookies[".EevaAuth"];
    var dataProtector = provider.CreateProtector(
        "Microsoft.AspNetCore.Authentication.Cookies.CookieAuthenticationMiddleware", "Cookies", "v2");  //change the AuthenticationScheme value
    UTF8Encoding specialUtf8Encoding = new UTF8Encoding(false, true);
    byte[] protectedBytes = Base64UrlTextEncoder.Decode(cookieValue);
    byte[] plainBytes = dataProtector.Unprotect(protectedBytes);
    string plainText = specialUtf8Encoding.GetString(plainBytes);
    return plainText;
}

The result in my sample like this:

test result

Reference: cookie authentication and Share authentication cookies among ASP.NET apps

Sign up to request clarification or add additional context in comments.

9 Comments

To line replacement var opt = httpContextAccessor.HttpContext.RequestServices .GetRequiredService<IOptionsMonitor<CookieAuthenticationOptions>>().Get("Cookies"); return opt.TicketDataFormat.Unprotect(".EevaAuth").Principal.Identity.Name; also works. Is this OK?
If you can get the correct value, it is Ok. But when I test your code on my app, it shows the "System.NullReferenceException" exception, probably something wrong on my side. Besides, it seems that you just want to get the current login user's name, if that is the case, you can try to use var username = HttpContext.User.Identity?.Name;.
I tried your code but dataProtector.Unprotect(protectedBytes) throws The payload is invalid exception. How to fix this? Cookie is created in other server but key in Voti directory is same in both servers.
You can check the app versions, are they asp.net 8 apps? Also, since the app is hosted on different servers, do cookies use a different base path or domain? You might need to set the base paths (options.Cookie.Path = "/";) and domain (options.Cookie.Domain = ".contoso.com";). Refer to Share authentication cookies among ASP.NET apps.
This is single application running in different servers in different domains. Adding Cookie path and domain in my code still returns null. How to add domain and path to your code? It does not have options. I updated question.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.