aspnet / Security

[Archived] Middleware for security and authorization of web apps. Project moved to https://github.com/aspnet/AspNetCore
Apache License 2.0
1.27k stars 600 forks source link

WS-Federation remote login failure ASP.NET Core 2.1+ #1873

Closed GoFightNguyen closed 5 years ago

GoFightNguyen commented 5 years ago

Context

ASP.NET Core 2.1 ASP.NET Core 2.2 Preview

The app is configured to use cookie authentication through WS-Federation. It is remote authentication. In the Startup.ConfigureServices I have this configuration

services.AddAuthentication(sharedOptions =>
            {
                sharedOptions.DefaultScheme = CookieAuthenticationDefaults.AuthenticationScheme;
                sharedOptions.DefaultSignInScheme = CookieAuthenticationDefaults.AuthenticationScheme;
                sharedOptions.DefaultChallengeScheme = WsFederationDefaults.AuthenticationScheme;
            })
            .AddWsFederation(options =>
            {
                options.MetadataAddress = "https://address/metadata.xml";
                options.Wtrealm = "urn:sp.Realm";
            })
            .AddCookie();

Problem

The first time context.ChallengeAsync() is invoked, the app flashes the remote authentication screen but then immediately directs to the default WsFederationOptions.CallbackPath, which is /signin-wsfed. It displays the following exception

System.Exception: An error was encountered while handling the remote login. ---> System.Exception: No message.
   --- End of inner exception stack trace ---
   at Microsoft.AspNetCore.Authentication.RemoteAuthenticationHandler`1.HandleRequestAsync()
   at Microsoft.AspNetCore.Authentication.AuthenticationMiddleware.Invoke(HttpContext context)
   at Microsoft.AspNetCore.StaticFiles.StaticFileMiddleware.Invoke(HttpContext context)
   at Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddleware.Invoke(HttpContext context)

After this, I can successfully see the remote authentication screen. Once I see the remote authentication screen, there are still two ways I see the same exception on the /signin-wsfed page

  1. Enter invalid credentials. This is despite my remote authentication having a workflow to handle this; the workflow is to prompt for credentials again.

  2. Cancel the login on step 2 of the multi-factor authentication. This is despite my remote authentication having a workflow to handle this; the workflow goes back to step 1 of the multi-factor authentication.

Expectation

I should not be directed from the remote authentication screen to the /signin-wsfed, especially with an exception. I expect to be at my remote authentication.

Tratcher commented 5 years ago

The initial auto redirect seems like an issue with your login provider. Can you capture a Fiddler trace to see if there's anything odd about the requests?

This is despite my remote authentication having a workflow to handle this;

Is that workflow handled entirely on the identity provider's site, or does it round trip through /signin-wsfed?

FYI that error comes from here.

GoFightNguyen commented 5 years ago

Regarding the initial auto redirect, I do see a difference in the remote authentication requests. The first request flows as follows:

Now, without stopping the app, I hit the Web API again. This time the remote authentication stays active. The request flows as follows:

The main difference I am seeing in the requests is:

Eilon commented 5 years ago

@GoFightNguyen if you can provide Fiddler (or similar) traces, that would be most helpful for us to investigate.

GoFightNguyen commented 5 years ago

I was working with our IdP and discovered it is rejecting the remote authentication request because it does not contain a wct field. Here is the request https://passportdev.domain.com/login/?wtrealm=urn%3Asp.Realm&wa=wsignin1.0&wreply=https%3A%2F%2Flocalhost%3A44399%2Fsignin-wsfed&wctx=CfDJ8PvrOyMP_WpGklq96IQEtSCkD_3VKjV7xhO8lsZa0ROi9BTDcPJFXyVBSQ2LnPF--5yAnza3iUGnbjt4HSLFgV_02ySGV06o9TZk74UXc_e9pU9fUxGKFR93LkwXwj3ivp8vGVYo6eQlNQaMUgpw7KLEinj8edepoFsrjxDZbnUjRkIv262a2_AIIxQG2f34BXX1zk-vViPrKWkOpxU0TD3eIG4URPjn-XJtMJ63d2zJxAxVY5-Q2TYGPq-YIJZVyQ

Looking at the WsFederationOptions class, it is not obvious to me how to set the wct.

blowdart commented 5 years ago

Hmm, wct is, by the spec, optional. @brentschmaltz can we get the identity model WSFed support to include a timestamp somehow?

Tratcher commented 5 years ago

Something like this, though you'd need to work out the correct date format.

           .AddWsFederation(options =>
            {
                ...
                options.Events.OnRedirectToIdentityProvider = context =>
                {
                    context.ProtocolMessage.Wct = DateTimeOffset.UtcNow.ToString();
                    return Task.CompletedTask;
                };
            })
GoFightNguyen commented 5 years ago

By setting the Wct, and having the IdP correct a couple of other issues, problem 1 is now resolved.

I believe problem 2, cancelling the login on step 2 of the multi-factor authentication, is also something specific with how this IdP handles a cancellation.

In other words, both problems were actually because of nuances with the IdP; neither issue was because of the WsFederation middleware. Thanks all for the help!