使用OWIN Ws-Federation包对ADFS 3.0进行身份验证

问题描述 投票:14回答:3

我有一个MVC内部网站点,需要使用AD帐户进行身份验证。

我设置ADFS 3.0(Win Server 2012 R2)并按照this设置ADFS信赖方信任。

This其他帖子介绍了Ws-Federation OWIN组件,我想使用它。它提到了如何连接到Azure AD,但没有关于ADFS的任何内容。

我尝试设置配置属性“MetadataAddress”和“Wtrealm”以匹配我在ADFS中配置但在运行时我收到错误:

A default value for SignInAsAuthenticationType was not found in IAppBuilder Properties. 
This can happen if your authentication middleware are added in the wrong order, or if one is missing.

我正在寻找正确的方法删除此错误

authentication owin adfs katana
3个回答
26
投票

是的..我遇到了同样的问题。只需执行以下操作即可:

    app.SetDefaultSignInAsAuthenticationType(WsFederationAuthenticationDefaults.AuthenticationType );

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

14
投票

我一直试图解决这个问题一段时间,特别感谢Lars KemmannTratcher,我相信这样做的可接受方式如下:

app.SetDefaultSignInAsAuthenticationType(CookieAuthenticationDefaults.AuthenticationType);

app.UseCookieAuthentication(
    new CookieAuthenticationOptions { }
);

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

您将默认身份验证类型配置为“Cookie身份验证”以使WsFederation工作似乎是违反直觉的,但这些只是用于识别每个中间件的字符串(这允许您注册相同类型的中间件多个例如,他们评估如下:

  • CookieAuthenticationDefaults.AuthenticationType =“Cookies”
  • WsFederationAuthenticationDefaults.AuthenticationType =“联邦”

这里发生的事情是我们告诉OWIN默认情况下应该使用标记为“Cookies”的中间件来验证请求,然后我们添加CookieAuthentication中间件(默认情况下,它从CookieAuthenticationDefaults.AuthenticationType值标记为“Cookies”,所以我们不要我必须编写任何其他代码来设置它,最后我们添加了FederationAuthentication中间件(这是由WsFederationAuthenticationDefaults.AuthenticationType标记 - 即“联邦”),我的理解是联邦中间件利用Cookie中间件来管理其与身份验证相关的cookie 。

剩下要做的就是配置你的应用程序在你选择的时候调用中间件,这可以通过多种方式实现,其中一些方法如下:

  • 通过返回HTTP 401响应
  • 通过在MVC控制器上使用[Authorize]属性
  • 通过调用OWIN Context IAuthenticationManagerChallenge方法(传递你的联邦中间件的标签)

当我问这个问题here时,Lars回答了一个如何为所有请求请求身份验证的简洁示例,然后我将其捆绑到OWIN管道中,如下所示:

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);
        }
    }
);

请注意,在上面的第一个示例中,我将Wtrealm和MetadataAddress值移动到我的配置文件中以便于维护,它们只是简单的应用程序设置:

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

我希望这有帮助。


1
投票

实际上,您只是错过了通常在UseCookieAuthentication方法调用之前的这一行。

app.UseExternalSignInCookie(DefaultAuthenticationTypes.ExternalCookie);

在你的情况下,它会

app.UseExternalSignInCookie(WsFederationAuthenticationDefaults.AuthenticationType);

这是在调用UseExternalSignInCookie(...)时实际执行的内容,externalAuthenticationType是您作为字符串参数传入的内容。

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);

因此,如果你设置的只是AuthenticationType,你可以安全地调用UseExternalSignInCookie,就像它为你做的那样。

© www.soinside.com 2019 - 2024. All rights reserved.