asp.net-coresingle-sign-onopenid-connect

Entra SSO returning a 302/502 in a .NET Core site


I have an issue getting SSO to work which is puzzling. The CallBackPath in the config below matches what is in Azure as the redirect uri, and I can see in the logs that user are being authenticated successfully. What happens then is they get a 302 in the network tab in dev tools, which becomes a 502 on the page.

I'm unsure if I'm missing anything, or have misconfigured things. Can anyone advise?

My config:

"Authentication": {
    "ClientId": "xxxxxx",
    "ClientSecret": "yyyyyyyy",
    "Authority": "https://login.microsoftonline.com/zzzzzzz",
    "CallbackPath": "/mypath/mypage",
    "Scope": "openid profile email"
},

the route to the login page where I want to initiate SSO:

[AllowAnonymous]
[Route("login")]
public IActionResult Login()
{
    return Challenge(new AuthenticationProperties(), OpenIdConnectDefaults.AuthenticationScheme);
}

and the relevant part from program.cs

.AddAuthentication(options =>
{
    options.DefaultScheme = CookieAuthenticationDefaults.AuthenticationScheme;
    options.DefaultChallengeScheme = OpenIdConnectDefaults.AuthenticationScheme;
})
.AddCookie()
.AddOpenIdConnect("OpenIdConnect", options =>
{
    options.ClientId = builder.Configuration["Authentication:ClientId"];
    options.ClientSecret = builder.Configuration["Authentication:ClientSecret"];
    options.Authority = builder.Configuration["Authentication:Authority"];
    options.CallbackPath = builder.Configuration["Authentication:CallbackPath"];
    options.ResponseType = "code";
    options.SkipUnrecognizedRequests = true;
    options.SaveTokens = true;
    options.Events = new OpenIdConnectEvents
    {
        OnTokenValidated = async context =>
        {
            // Log successful authentication
            var userId = context.Principal?.Claims.FirstOrDefault(c => c.Type == "name")?.Value
             ?? context.Principal?.Claims.FirstOrDefault(c => c.Type == "preferred_username")?.Value
             ?? "Unknown User";
            Log.Information("SSO Log - User {UserId} successfully authenticated via SSO.", userId);

            await Task.CompletedTask;
        },
        OnAuthenticationFailed = context =>
        {
            Log.Error("SSO Log - Authentication failed: {Error}", context.Exception.Message);
            return Task.CompletedTask;
        }
    };

});

Solution

  • I had a test with OP's code in a new .net 8 MVC application which worked well except the Login method in the controller. I added [Authorize] attribute on my controller class so that when I run the application, it would redirect to Microsoft sign in page and it will redirect back to my Home index page after signing succefully. But once I hit login method manually, I will trapped within an infinite redirection loop then gave me an error about sign in.

    I deduce the issue might relate to the redirection, therefore I make a change to the Login method return Challenge(new AuthenticationProperties { RedirectUri = Url.Content("~/accounts/home") }, OpenIdConnectDefaults.AuthenticationScheme); which adding a redirect url.

    In my test, it will make the flow to be redirecting to the callback path defined in appsetting.json after signing in successfully, in my side I set it to /home, then redirect to the url defined in return Challenge.

    enter image description here