FormsAuthentication icon indicating copy to clipboard operation
FormsAuthentication copied to clipboard

Debugging/troubleshooting in .Net Core 3.1

Open mwittmann opened this issue 5 years ago • 4 comments

I'm trying to integrate this into a .Net Core 3.1 app so it can accept a forms authentication cookie from a legacy .Net 4.5 web app. I believe I've set things up properly in ConfigureServices() (excerpt below). All configuration values including the cookie name and encryption/decryption keys and methods match the .Net 4.5 app.

However, when I access an [Authorize] protected controller action, none of the Synercoding.FormsAuthentication or FormsAuthHelper code is called to validate the existing authentication cookie created by the .Net 4.5 web app. Tracing into the .Net Core code, I see that in the Microsoft.AspNetCore.Authorization.AuthorizationMiddleware.Invoke() method, var authorizeResult = await policyEvaluator.AuthorizeAsync(policy, authenticateResult, context, resource: endpoint); always returns authorizeResult.Challenged. (Unfortunately, I cannot step into the AuthorizeAsync() method itself to inspect its processing.) The context.ChallengeAsync() method tries to redirect to the login page (which doesn't exist), but in the process of trying to set up that redirect, the FormsAuthenticationDataFormat() constructor is called, and the set method of the Microsoft.AspNetCore.Http.CookieBuilder.Name property is called with the "MyAuthCookie" configuration value -- so I see the configuration kicking in at that point. (The Microsoft.AspNetCore.Http.CookieBuilder.Name get method is called shortly thereafter, returning "MyAuthCookie").

I'm puzzled why none of the Synercoding.FormsAuthentication code is called to try to validate the existing cookie before trying to redirect to the login page. I can see that the "MyAuthCookie" .Net 4.5 authentication cookie does exist in the HttpContext object with the value generated by the .Net 4.5 app.

Any suggestions for how to debug or troubleshoot the configuration would be very welcome.

Here's the ConfigureServices() excerpt:

using System;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
using Microsoft.AspNetCore.Authentication;
using Microsoft.AspNetCore.Authentication.Cookies;
using Synercoding.FormsAuthentication;
// ...stuff omitted...

// ...in ConfigureServices()...
var formsAuthConfig = Configuration.GetSection("FormsAuthentication");
var formsAuthOptions = new FormsAuthenticationOptions()
{
	DecryptionKey = formsAuthConfig.GetValue<string>("DecryptionKey"),
	ValidationKey = formsAuthConfig.GetValue<string>("ValidationKey"),
	EncryptionMethod = formsAuthConfig.GetValue<EncryptionMethod>("EncryptionMethod"),
	ValidationMethod = formsAuthConfig.GetValue<ValidationMethod>("ValidationMethod"),
};
services.AddAuthentication(options =>
{
	options.DefaultAuthenticateScheme = CookieAuthenticationDefaults.AuthenticationScheme;
	options.DefaultChallengeScheme = CookieAuthenticationDefaults.AuthenticationScheme;
	options.DefaultSignInScheme = CookieAuthenticationDefaults.AuthenticationScheme;
})
.AddCookie(options =>
{
	options.Cookie.Name = "MyAuthCookie";
	options.AccessDeniedPath = formsAuthConfig.GetValue<string>("AccessDeniedPath");
	options.LoginPath = formsAuthConfig.GetValue<string>("LoginPath");
	options.ReturnUrlParameter = formsAuthConfig.GetValue<string>("ReturnUrlParameter");
	options.TicketDataFormat = new FormsAuthenticationDataFormat<AuthenticationTicket>(
		formsAuthOptions,
		FormsAuthHelper.ConvertCookieToTicket,
		FormsAuthHelper.ConvertTicketToCookie
		);
});

mwittmann avatar May 06 '20 07:05 mwittmann

Update: I discovered that my Startup.cs Configure() method was missing app.UseAuthentication();:

app.UseRouting();
app.UseAuthentication(); // <== was missing
app.UseAuthorization();

Now, as expected, Synercoding.FormsAuthentication code is called to decrypt the Forms Auth cookie. However, tracing through, I see that Unprotect() fails (returns null). Specifically, in Synercoding.FormsAuthentication.Encryption.NetFXCryptoService.Unprotect(), the following test fails:

if (!CryptoUtil.BuffersAreEqual(
    buffer1: protectedData, buffer1Offset: ivByteCount + encryptedPayloadByteCount, buffer1Count: signatureByteCount,
    buffer2: computedSignature, buffer2Offset: 0, buffer2Count: computedSignature.Length))
{
    // the computed signature didn't match the incoming signature, which is a sign of payload tampering
    return null;
}

It now seems to be the basic matter of the decryption failing, although I've triple-checked to verify the decryption and validation keys and methods match between the .Net 4.x web app and the Synercoding.FormsAuthentication configuration. How can I troubleshoot this further?

mwittmann avatar May 11 '20 20:05 mwittmann

Hi,

Can you try with this version?

https://www.nuget.org/packages/Synercoding.FormsAuthentication/3.1.0-alpha01

If the decryption error persists, could you create a minimal, reproducible example?

For example by including a validation and decryption key (freshly generated if possible, not a great idea to post production keys here ;-) ).

synercoder avatar May 19 '20 01:05 synercoder

I have the same question,But this problem only appears on my computer. If I copy my program to another computer, it works.

My PC: Windows 10 2004 19041.572 NET Framework 4.8.04084 NET Core 3.1.9 (SSO Project Running in NET Framework, my Project running in NET Core)

another computer: Windows Server 2019 NET Framework 4.7.03190 NET Core is not installed

About a month ago, my program was running normally on my computer. I can't confirm why it's not working right now.

QianMoXi avatar Oct 24 '20 02:10 QianMoXi

If the SSO project running in NET Core with Synercoding.FormsAuthentication, verification is also normal

QianMoXi avatar Oct 24 '20 02:10 QianMoXi