Search code examples
owinkatanaws-federation

OWIN WS-FED Passive signout of identity provider


So I have a solution that is using Microsoft.Owin.Security.WsFederation 3.0.0-rc2 and I'm trying to get Passive sign-out calling back to the identity provider to log out of there as well as my application (so I don't get a redirect loop just logging it back in).

I'm currently using WAAD as the WS-Fed endpoint.

app.UseCookieAuthentication(new CookieAuthenticationOptions
{
    AuthenticationType = DefaultAuthenticationTypes.ApplicationCookie,
    LoginPath = new PathString("/login")
});

app.SetDefaultSignInAsAuthenticationType(DefaultAuthenticationTypes.ApplicationCookie);

app.UseExternalSignInCookie(DefaultAuthenticationTypes.ExternalCookie);

app.UseWsFederationAuthentication(new WsFederationAuthenticationOptions
{
    AuthenticationMode = Microsoft.Owin.Security.AuthenticationMode.Passive,
    AuthenticationType = WsFederationAuthenticationDefaults.AuthenticationType,
    Wtrealm = ConfigurationManager.AppSettings["WSFEDRealm"],
    MetadataAddress = ConfigurationManager.AppSettings["WSFEDMetadataAddress"]
});

I can get it working fine if I use active but it would be nice to have the option of using passive as well.

I am signing out using:

_authenticationManager.SignOut();

I think it has something to do with these lines in the signout helper

if (revoke.AuthenticationTypes == null || revoke.AuthenticationTypes.Length == 0)
{
    return authenticationMode == AuthenticationMode.Active ? revoke : null;
}

But I'm unsure of how I add to the revoke.AuthenticationTypes dictionary?


Solution

  • A potential solution is to manually force the signout1.0 request

    var wsConfiguration = await _wsConfigurationManager.GetConfigurationAsync(HttpContext.GetOwinContext().Request.CallCancelled);
    var message = new WsFederationMessage
    {
        IssuerAddress = wsConfiguration.TokenEndpoint,
        Wtrealm = ConfigurationManager.AppSettings["WSFEDRealm"],
        Wreply = Url.Action("Index", "Home", null, Request.Url.Scheme),
        Wa = "wsignout1.0"
    };
    

    I then have a binding in my ninject module for the wsfederation configuration

    Bind<IConfigurationManager<WsFederationConfiguration>>().ToMethod((c) =>
    {
        var owinContext = HttpContext.Current.GetOwinContext().Authentication;
            return new ConfigurationManager<WsFederationConfiguration>(ConfigurationManager.AppSettings["WSFEDMetadataAddress"]);
    }).InSingletonScope();
    

    I'm not 100% happy with this solution as it means there are two running configuration managers for the metadata, but it is a working solution.