Use OWIN Ws-Federation package to authenticate against ADFS 3.0

社会主义新天地 提交于 2019-12-02 22:00:33

Yeah.. I came across the same issue. Just do the following and it should work:

    app.SetDefaultSignInAsAuthenticationType(WsFederationAuthenticationDefaults.AuthenticationType );

    app.UseCookieAuthentication(new CookieAuthenticationOptions
    {
       AuthenticationType = WsFederationAuthenticationDefaults.AuthenticationType
    });
Tom Tregenna

I've been trying to get my head around this for a while now, and with thanks specifically to Lars Kemmann and Tratcher, I believe the accepted way of doing this is as follows:

app.SetDefaultSignInAsAuthenticationType(CookieAuthenticationDefaults.AuthenticationType);

app.UseCookieAuthentication(
    new CookieAuthenticationOptions { }
);

app.UseWsFederationAuthentication(
    new WsFederationAuthenticationOptions
    {
        Wtrealm = ConfigurationManager.AppSettings["ida:Wtrealm"],
        MetadataAddress = ConfigurationManager.AppSettings["ida:FedMetadataURI"]
    }
);

It seems counter-intuitive that you're configuring the default authentication type as 'Cookie Authentication' to get WsFederation to work, however these are really just strings used to identify each piece of middleware (this allows you to register the same type of middleware multiple times, for example), they evaluate as follows:

  • CookieAuthenticationDefaults.AuthenticationType = "Cookies"
  • WsFederationAuthenticationDefaults.AuthenticationType = "Federation"

What's happening here is that we're telling OWIN that the middleware labelled "Cookies" should be used by default to authenticate requests, we then add the CookieAuthentication middleware (by default this is labelled "Cookies" from the CookieAuthenticationDefaults.AuthenticationType value, so we don't have to write any additional code to set it up), finally we add the FederationAuthentication middleware (this is labelled by WsFederationAuthenticationDefaults.AuthenticationType - i.e. "Federation"), my understanding is that the Federation middleware utilises the Cookie middleware to manage its authentication-related cookies.

All that's left it to do is configure your app to invoke the middleware at a time of your choosing, this can be achieved in a number of ways, some of which are as follows:

  • By returning a HTTP 401 response
  • By using the [Authorize] attribute on an MVC Controller
  • By calling the OWIN Context IAuthenticationManager's Challenge method (passing in the label of your Federation middleware)

When I asked this question here, Lars answered with a neat example of how to request authentication for all requests, I then bundled it in to the OWIN pipeline as follows:

app.Use(
    (context, continuation) =>
    {
        if (
            (context.Authentication.User != null) &&
            (context.Authentication.User.Identity != null) &&
            (context.Authentication.User.Identity.IsAuthenticated)
        )
        {
            return continuation();
        }
        else
        {
            context.Authentication.Challenge(WsFederationAuthenticationDefaults.AuthenticationType);

            return Task.Delay(0);
        }
    }
);

Note that in the first example above, I moved the Wtrealm and MetadataAddress values into my config file for ease of maintenance, they are just simple application settings:

<appSettings>
    <add key="ida:Wtrealm" value="[app-uri]" />
    <add key="ida:FedMetadataURI" value="https://[adfs-server]/federationmetadata/2007-06/federationmetadata.xml" />
</appSettings>

I hope this helps.

Actually, you are just missing this line that is usually before the UseCookieAuthentication method call.

app.UseExternalSignInCookie(DefaultAuthenticationTypes.ExternalCookie);

in your case it would be

app.UseExternalSignInCookie(WsFederationAuthenticationDefaults.AuthenticationType);

This is what actually gets executed when you call UseExternalSignInCookie(...), externalAuthenticationType is what you pass in as the string parameter.

app.SetDefaultSignInAsAuthenticationType(externalAuthenticationType);
CookieAuthenticationOptions options = new CookieAuthenticationOptions();
options.AuthenticationType = externalAuthenticationType;
options.AuthenticationMode = AuthenticationMode.Passive;
options.CookieName = ".AspNet." + externalAuthenticationType;
options.ExpireTimeSpan = TimeSpan.FromMinutes(5.0);
app.UseCookieAuthentication(options);

So, if all you are setting is the AuthenticationType, you can safely just call UseExternalSignInCookie as it does it for you.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!