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

[Announcement] WsFederation 2.0.0-preview1 out of band release #1473

Closed Tratcher closed 6 years ago

Tratcher commented 7 years ago

WsFederation preview support is now available for ASP.NET Core 2.0.0. The Microsoft.AspNetCore.Authentication.WsFederation 2.0.0-preview1 package is available at https://www.nuget.org/packages/Microsoft.AspNetCore.Authentication.WsFederation/. This is a standalone preview that targets netstandard2.0 and should work with existing ASP.NET Core 2.0.0 applications (.NET Core 2.0 or .NET 4.6.1). A non-preview ASP.NET Core 2.0.0 compatible package will follow once we’ve addressed your feedback.

The code is available at https://github.com/aspnet/security/tree/rel/2.0.0-ws-preview1 and issues can be filed at https://github.com/aspnet/security/issues. Please give us a 👍 from the reactions menu on this post if you have successfully used this component and are ready for the final release.

This component is a port from Microsoft.Owin.Security.WsFederation and uses many of the same mechanics. It has also been updated to integrate with ASP.NET Core 2.0’s authentication model. See the samples below.

Aside from updating the usage pattern to match ASP.NET Core, there are also some functional changes to be aware of. A. This component no longer checks every form post request for sign-in messages by default. Sign-in callbacks are restricted to the "/signin-wsfed" path by default. The CallbackPath can be changed to the application root “/” used by some auth providers if you also enable SkipUnrecognizedRequests to allow sharing that request path with other components. B. This component no longer allows unsolicited logins by default. That WsFederation protocol feature is susceptible to XSRF attacks. See the AllowUnsolicitedLogins option to opt into that feature if your application requires it.

Samples:

For applications only using WsFederation (similar to using OpenIdConnect):

    public void ConfigureServices(IServiceCollection services)
    {
        services.AddAuthentication(sharedOptions =>
        {
            sharedOptions.DefaultScheme = CookieAuthenticationDefaults.AuthenticationScheme;
            sharedOptions.DefaultSignInScheme = CookieAuthenticationDefaults.AuthenticationScheme;
            sharedOptions.DefaultChallengeScheme = WsFederationDefaults.AuthenticationScheme;
        })
        .AddWsFederation(options =>
        {
            options.Wtrealm = Configuration["wsfed:realm"];
            options.MetadataAddress = Configuration["wsfed:metadata"];
        })
        .AddCookie();
    }

    public void Configure(IApplicationBuilder app)
    {
       app.UseAuthentication();

                     // …
    }

For applications using WsFederation with Identity:

        services.AddAuthentication()
            .AddWsFederation(options =>
            {
                options.Wtrealm = Configuration["wsfed:realm"];
                options.MetadataAddress = Configuration["wsfed:metadata"];
            });
ashgadala commented 7 years ago

Wonderful....! Yay...!

gtresoldi commented 7 years ago

Hi, I've tried to use WsFederation with ADFS server 2016. Here my configuration:

services.AddAuthentication() .AddWsFederation(options => { options.Wtrealm = "https://localhost:44312"; options.MetadataAddress = "https://adfsserver2016/FederationMetadata/2007-06/FederationMetadata.xml" I get this exception. Exception.txt

This is my metadata file FederationMetadata.txt

Anyone can help me? Thanks

Compufreak345 commented 7 years ago

I've got the same issue like @gtresoldi with an ADFS on Windows Server 2012 R2

Hi, I've tried to use WsFederation with ADFS server 2016. Here my configuration:

services.AddAuthentication() .AddWsFederation(options => { options.Wtrealm = "https://localhost:44312"; options.MetadataAddress = "https://adfsserver2016/FederationMetadata/2007-06/FederationMetadata.xml" I get this exception. Exception.txt

This is my metadata file FederationMetadata.txt

Anyone can help me? Thanks

Should we file a seperate issue for this problem or is there any other solution?

Thanks & best regards, Christoph

Tratcher commented 7 years ago

@gtresoldi @Compufreak345 I've filed https://github.com/AzureAD/azure-activedirectory-identitymodel-extensions-for-dotnet/issues/786 for your parser issue.

ashgadala commented 7 years ago

@Tratcher FYI. same parser issue as above.

lolofx commented 7 years ago

Great news :)

reicher001 commented 7 years ago

@Tratcher Looks like I am getting the same parser issue too.

Zoxive commented 7 years ago

Any timeline for wsignoutcleanup1.0 support?

Tratcher commented 7 years ago

@Zoxive this one? https://github.com/aspnet/Security/issues/1425. We're considering it but there's no specific timeline. The current focus is porting over existing functionality from Katana.

Zoxive commented 7 years ago

@Tratcher Kinda, when our single signon provider wants to sign out all the sub applications each application gets a SignoutCleanup action

For now im doing something like this inside the WsFederationHandler HandleRemoteAuthenticateAsync

 // Handle SignoutCleanup
if (Request.Query.TryGetValue("wa", out var wa))
{
    if (wa == WsFederationConstants.WsFederationActions.SignOutCleanup)
    {
        await _authenticationService.SignOutAsync(Request.HttpContext, Options.SignInScheme, null);
        return HandleRequestResult.Handle();
    }    
}

You could do something similar with middleware etc, but we already have a custom WsFederation fork to support dotnetcore. (soon as all features are met we can remove our custom proj)

Tratcher commented 7 years ago

@Zoxive how is that different from #1425? That sounds like what we'd implement. OIDC has something similar.

jmezach commented 7 years ago

Is there any guidance on how we could share FedAuth cookies between existing ASP.NET full framework applications and ASP.NET Core apps? As far as I can see this just enables an ASP.NET Core application to authenticate against a WSFed STS. We are looking for a way to re-use existing FedAuth cookies so that we can move part of our applications to ASP.NET Core without having to rewrite existing code.

Tratcher commented 7 years ago

@jmezach It depends on what components your ASP.NET apps were using. If it was the Microsoft.Owin WsFederation provider then there is a way to share cookies. https://docs.microsoft.com/en-us/aspnet/core/security/data-protection/compatibility/cookie-sharing

arc2018 commented 7 years ago

I get this error when I start the application. it is not able to complete the configuration from Federation Metadata. if I enter the metadata url on the browser I am able to see the xml, but only issue I see is that there is a certificate error, which I override on the browser. would that be an issue causing this?

my config:

 public void ConfigureServices(IServiceCollection services)
        {
            services.AddMvc();
            services.AddAuthentication(sharedOptions =>
                        {
                            sharedOptions.DefaultScheme = CookieAuthenticationDefaults.AuthenticationScheme;
                            sharedOptions.DefaultSignInScheme = CookieAuthenticationDefaults.AuthenticationScheme;
                            sharedOptions.DefaultChallengeScheme = WsFederationDefaults.AuthenticationScheme;
                        })
                       .AddWsFederation(options =>
                       {
                           options.Wtrealm = @"http://localhost:3230/";// Configuration["wsfed:realm"];
                           options.MetadataAddress = @"https://DevIDPServer/sts/Metadata.xml";// Configuration["wsfed:metadata"];
                       })
                       .AddCookie();

        }

app.UseAuthentication();

----------------------Errors-----------------------------

System.InvalidOperationException: IDX10803: Unable to obtain configuration from: 'https://DevIDPServer/sts/Metadata.xml'. ---> Microsoft.IdentityModel.Xml.XmlReadException: IDX13004: Security token type role descriptor is expected.
   at Microsoft.IdentityModel.Protocols.WsFederation.WsFederationMetadataSerializer.ReadEntityDescriptor(XmlReader reader)
   at Microsoft.IdentityModel.Protocols.WsFederation.WsFederationMetadataSerializer.ReadMetadata(XmlReader reader)
   at Microsoft.IdentityModel.Protocols.WsFederation.WsFederationConfigurationRetriever.<GetAsync>d__4.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at System.Runtime.CompilerServices.ConfiguredTaskAwaitable`1.ConfiguredTaskAwaiter.GetResult()
   at Microsoft.IdentityModel.Protocols.ConfigurationManager`1.<GetConfigurationAsync>d__24.MoveNext()
   --- End of inner exception stack trace ---
   at Microsoft.IdentityModel.Protocols.ConfigurationManager`1.<GetConfigurationAsync>d__24.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at Microsoft.AspNetCore.Authentication.WsFederation.WsFederationHandler.<HandleChallengeAsync>d__3.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at Microsoft.AspNetCore.Authentication.AuthenticationHandler`1.<ChallengeAsync>d__53.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at Microsoft.AspNetCore.Authentication.AuthenticationService.<ChallengeAsync>d__11.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at Microsoft.AspNetCore.Mvc.ChallengeResult.<ExecuteResultAsync>d__14.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker.<InvokeResultAsync>d__19.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker.<InvokeFilterPipelineAsync>d__17.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker.<InvokeAsync>d__15.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at Microsoft.AspNetCore.Builder.RouterMiddleware.<Invoke>d__4.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddleware.<Invoke>d__7.MoveNext()
Tratcher commented 7 years ago

@arc2018 yes https cert errors are expected to fail the metadata download. However, that's a strange inner exception. I've ask @brentschmaltz about it on your other thread: https://github.com/AzureAD/azure-activedirectory-identitymodel-extensions-for-dotnet/issues/804

To ignore cert errors you need to hook into the backchannel like this: options.BackchannelHttpHandler = new HttpClientHandler() { ServerCertificateCustomValidationCallback = (_, __, ___, ___) => true };

arc2018 commented 7 years ago

@Tratcher thank you for your response. I added the BackchannelHttpHandler, but that did not make any difference, I get the same error. this is the new code: `public void ConfigureServices(IServiceCollection services) { services.AddMvc(); services.AddAuthentication(sharedOptions => { sharedOptions.DefaultScheme = CookieAuthenticationDefaults.AuthenticationScheme; sharedOptions.DefaultSignInScheme = CookieAuthenticationDefaults.AuthenticationScheme; sharedOptions.DefaultChallengeScheme = WsFederationDefaults.AuthenticationScheme; }) .AddWsFederation(options => { options.Wtrealm = @"http://localhost:3230/";// Configuration["wsfed:realm"]; options.MetadataAddress = @"https://DevIDPServer/sts/Metadata.xml";// Configuration["wsfed:metadata"]; options.BackchannelHttpHandler = new HttpClientHandler() { ServerCertificateCustomValidationCallback = (req, cert, er, t) => true }; }) .AddCookie();

    }

` I created a test full framework 4.5 asp.net web app pointing to the same IDP and it works without any issue on the same machine. here is my web config on the 4.5 application. We are using SecureAuth as our identity provider.

`

</system.identityModel>

`
Tratcher commented 7 years ago

Please reopen you AzureAd bug then. They can investigate the exception.

arc2018 commented 7 years ago

@Tratcher thank you. I reopened it.

lzandman commented 7 years ago

I'm getting a similar issue as @arc2018. Is it possible to bypass the metadata XML file retrieval and configure this thing manually?

Tratcher commented 7 years ago

Yes you can set the options.Configuration property, but building it by hand is non trivial. If you manage please share a sample.

Zoxive commented 7 years ago

@Tratcher @lzandman Not to bad for us. This is what we use.

// Created our own custom WsFederationSettings dto
public class WsFederationSettings
{
    public string Issuer { get; set; }
    public string TokenEndpoint { get; set; }
    public IEnumerable<string> SigningKeys { get; set; }
    public string Realm { get; set; }
}

// Load from section "WsFederation" in our appsettings.json file
var settings = Configuration.GetSection("WsFederation").Get<WsFederationSettings>();

var config = new WsFederationConfiguration
{
    Issuer = settings.Issuer,
    TokenEndpoint = settings.TokenEndpoint,
};
foreach (var signKey in settings.SigningKeys)
{
    var cert = new X509Certificate2(Convert.FromBase64String(signKey));

    var key = new X509SecurityKey(cert);
    config.SigningKeys.Add(key);
}
o.Configuration = config;
o.Wtrealm = settings.Realm;
o.TokenValidationParameters = new TokenValidationParameters
{
    ValidAudience = settings.Realm
};
///rest of your options
lzandman commented 7 years ago

Thanks @Tratcher @Zoxive. Will try!

lzandman commented 7 years ago

Using a nightly build I got things partially working. After succesful authentication in ADFS the browser is redirected to ".../signin-wsfed". This returns a 302 response, where I see the ".AspNetCore.Correlation.WsFederation..." cookie is being removed and a new cookie ".AspNetCore.Cookies" is set. Then the browser is redirected to the initial controller endpoint (a web API with Authorize attribute set) that started the authentication process. However, my code is never called. Instead another authentication process is triggered, sending the browser back to ADFS. The repeats itself six times, ending with a "MSIS7042: The same client browser session has made '6' requests in the last '0' seconds." error.

So it appears the request to my Web API endpoint isn't seen as a valid authenticated request. The only cookie it receives is the ".AspNetCore.Cookies" cookie. Is that OK? Does that cookie contain all authentication/session data required?

poke commented 7 years ago

@lzandman Unless the WsFed authentication handler does something completely different (which I don’t expect it to do), the authentication stack works as follows in ASP.NET Core:

  1. You hit an authorized route without proper authentication.
  2. The challenge authentication scheme is executed (this would be WsFed)
  3. WsFed does its thing my redirecting to the ADFS, that then posts back to /signin-wsfed
  4. WsFed retrieves the information from the ADFS’ POST request, creates an identity and passes it on to the Cookie authentication handler
  5. The cookie authentication handler persists the identity in a cookie and completes the authentication process, redirecting back to the original URL.
  6. The original route is being requested again, this time with the identity in a cookie; the cookie authentication handler uses that cookie to restore the identity for the current request.

So the WsFed authentication handler only runs for the authentication process, but the identity is persisted using the cookie authentication handler. So what you are seeing is correct: There will be only the cookie from the cookie authentication handler.

If you end up with an authentication loop, then something should be off with your configuration. Maybe your authorization policy is set improperly. Could you show debug logs from the application starting at the time where you hit your secured endpoint?

lzandman commented 7 years ago

@poke I hadn't set an explicit policy. I just wanted the caller of my controller to be authenticated. So I used the Authorize attribute without specifying a policy.

I then tried to implement authorization based on the beginning of this article (the RequireAuthenticatedUser policy). That that also doesn't seem to work. Still the same loop.

The debug output doesn't seem to include anything helpful. Is there a way to get more debug info on the authentication/authorization process?

lzandman commented 7 years ago

@poke Fixed it! Turns out the problem was that ordering seems to matter in the Configure() method in Startup.cs. My code originally was like this:

public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
{
    if (env.IsDevelopment())
    {
        app.UseDeveloperExceptionPage();
    }

    loggerFactory.AddDebug();
    app.UseMvc();
    app.UseAuthentication();
}

But the UseMvc() call needs to be at the end (or at least below the UseAuthentication() call.

public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
{
    if (env.IsDevelopment())
    {
        app.UseDeveloperExceptionPage();
    }

    loggerFactory.AddDebug();
    app.UseAuthentication();
    app.UseMvc();
}

Now it seems everything is working fine!

poke commented 7 years ago

@lzandman Yes, the UseAuthentication should be very early in your Configure to make sure that the authentication middleware runs very early. Having it after MVC would mean that it will never run for MVC routes (since the MVC middleware terminates the request), so the user will never be authenticated there. Glad you could resolve this :)

lzandman commented 7 years ago

Got another question. In our regular .Net web apps that use WS-Federation we specify a certificate thumbprint. The certificate itself is not installed in the store on the machine. The metadata file or the manual method of configuring this new WS-Federation package (as presented by @Zoxive code sample above) both require the actual X509Certficate2 data to be present. Am I missing something here? Is it possible to configure this using only the certificate thumbprint?

I did find some code to obtain a certificate from the Store by its thumbprint, but since I do not have the certificate installed locally, I cannot use that method.

arc2018 commented 7 years ago

@lzandman can you share me the nightly build download link?

lzandman commented 7 years ago

@arc2018 I got it from this website. You can also add their NuGet feed to Visual Studio's Package Manager (be sure to check preview builds):

https://www.myget.org/F/azureadwebstacknightly/api/v3/index.json

Tratcher commented 7 years ago

@brentschmaltz https://github.com/aspnet/Security/issues/1473#issuecomment-339346039 ?

brentschmaltz commented 7 years ago

@lzandman you need the certificate. The thumbprint would need additional information pointing to a cert store.

lzandman commented 7 years ago

Another question: In our regular Asp.Net MVC apps we've implemented custom sliding session logic that works by hooking into the FederatedAuthentication.SessionAuthenticationModule.SessionSecurityTokenReceived event. Based on some logic either nothing happens, a new session security token is created or the user gets signed out. This SessionSecurityTokenReceived event is triggered for every request.

I'm trying to do something similar in our AspnetCore app using this experimental ws-fed package. I've hooked into the WSFederationOptions Events (MessageReceived, SecurityTokenReceived, SecurityTokenValidated, etc). But these events don't get called for every request. They are only called when an ADFS roundtrip was made (at start and after token lifetime has passed; i.e. when "/signin-wsfed" is called.)

Does anybody know where i should hook into for our custom sliding session logic?

poke commented 7 years ago

@lzandman As per my explanation above, the WSFed authorization handler won’t run if the cookie authentication scheme is able to reconstruct the claims identity from the stored cookies. So hooking into WSFed here will not work since it simply won’t run at all. You would have to hook into the cookie authentication scheme here.

I’m not sure if there’s a good way to hook into it though, I haven’t tried looking for it yet. I personally use a custom authorization handler to implement a custom session that exists parallel to the actual authentication process. But hooking into the cookie authentication scheme might be a pretty good way to do it, if it allows doing so.

lzandman commented 7 years ago

Update: using this Microsoft document I found out the OnValidatePrincipal event seems like the proper location to put our custom stuff. However, when our custom logic decides a new cookie should be created, I call the HttpContext.SignInAsync() extension method. This results in the following exception:

InvalidOperationException: No IAuthenticationSignInHandler is configured to handle sign in for the scheme: WsFederation

Anyone have any idea what I'm missing?

Tratcher commented 7 years ago

@lzandman You're calling SignIn with the wrong scheme, you should be using the cookie auth scheme.

lzandman commented 7 years ago

@Tratcher Yes, that was the problem. Originally I had put that code inside a WsFederation event handler. There I figured I had to use the WsFederation scheme. Now that I'm working from a cookie auth event handler, I had to use that scheme. Thanks :-)

lzandman commented 7 years ago

So, it seems I've got everything working. Except for signing out. I use the following code:

context.RejectPrincipal();
await context.HttpContext.SignOutAsync(CookieAuthenticationDefaults.AuthenticationScheme);

The browser is redirected to the ADFS server, to the following URL:

https://myadfsserver.com/adfs/ls/?wtrealm=https%3A%2F%2Flocalhost%3A44304%2F&wa=wsignin1.0&wreply=https%3A%2F%2Flocalhost%3A44304%2Fsignin-wsfed&wctx=...

Then it's sent to the "/signin-wsfed" url and it's authenticated again. Then it is redirected to the Web API endpoint and allowed access. Any ideas? I had expected it to get redirected to the ADFS using a wsignout action.

Tratcher commented 7 years ago

SignOutAsync(CookieAuthenticationDefaults.AuthenticationScheme); only removes the local cookie. If you also want a remote sign-out then you should add a second call to sign out for the WsFederation scheme.

lzandman commented 7 years ago

@Tratcher That sounds plausible. But do you have any sample code? I tried this:

await context.HttpContext.SignOutAsync(CookieAuthenticationDefaults.AuthenticationScheme);
await context.HttpContext.SignOutAsync(WsFederationDefaults.AuthenticationScheme);

But that didn't do anything...

Tratcher commented 7 years ago

You're right, that's beyond the capabilities of that event. The problem is that the request continues to execute normally (e.g. it proceeds to process /foo/bar). To cause a remote signout you'd have to call signout like above And terminate the request. For that level of control you're going to need to move the logic to your own middleware.

poke commented 7 years ago

@Tratcher I assume the short-circuiting behavior for authorization doesn’t work there because we only have access to the HTTP context instead of the authorization filter context? A real shame that we cannot terminate the request early there then. I have something very similar implemented with custom MVC filters but moving it into authentication events would have made a lot of sense (to decouple it from MVC in my case).

Tratcher commented 7 years ago

It's a control flow problem, the event does not have a flag that lets you terminate the request.

lzandman commented 7 years ago

@Tratcher So when writing custom middleware, how would I get access to certain values that are available inside authentication events? E.g. I need the values of context.Properties.IssuedUtc and context.Properties.ExpiresUtc.

Tratcher commented 7 years ago

HttpContext.AuthenticateAsync() returns a result object with both user and properties.

brentschmaltz commented 7 years ago

@Tratcher what happens when you call HttpContext.AuthenticateAsync() inside MiddleWare. What does the calls graph look like?

poke commented 7 years ago

@brentschmaltz HttpContext.AuthenticateAsync() gets the AuthenticationService from DI and calls AuthenticationService.AuthenticateAsync(). That then gets the handler for the default authentication scheme and calls AuthenticateAsync on that handler.

This is basically the same thing that happens when the MVC AuthorizeFilter runs.

And btw. calling AuthenticateAsync early in a middleware will not make subsequent calls do the same thing again. The result will be cached internally, so all that happens with calling it in custom middleware is that it runs a bit earlier.

lzandman commented 7 years ago

@Tratcher Thanks! I've got it working now. The only issue I'm seeing now is that there's a wsignoutcleanup1.0 request on /signin-wsfed that returns a 500 status. I think @Zoxive messages above imply that this functionality hasn't yet been implemented, right?

lzandman commented 7 years ago

@Zoxive You mention that you've implemented custom wsignoutcleanup1.0 handing inside WsFederationHandler HandleRemoteAuthenticateAsync. How did you do that? Is that an event I can hook into?

lzandman commented 7 years ago

Another potential issue: I've placed custom cookie authentication events inside a custom class that inherits from CookieAuthenticationEvents and specify that class using the EventsType property of CookieAuthenticationOptions as specified in this Microsoft document.

I tried to apply the same pattern to the WsFederationEvents class, but noticed it doesn't contain any virtual members that I can override in my own custom class. It only inherits one overrideable virtual member, TicketReceived, from its base class RemoteAuthenticationEvents. So it seems this pattern isn't applicable and the WsFederationOptions.EventsType property mechanism cannot be used. Is this a bug?