16

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

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

另一篇文章介绍了 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.

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

4

3 回答 3

29

是的..我遇到了同样的问题。只需执行以下操作,它应该可以工作:

    app.SetDefaultSignInAsAuthenticationType(WsFederationAuthenticationDefaults.AuthenticationType );

    app.UseCookieAuthentication(new CookieAuthenticationOptions
    {
       AuthenticationType = WsFederationAuthenticationDefaults.AuthenticationType
    });
于 2014-04-24T15:21:09.000 回答
15

一段时间以来,我一直在努力解决这个问题,特别感谢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=“饼干”
  • WsFederationAuthenticationDefaults.AuthenticationType=“联邦”

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

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

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

当我在这里问这个问题时,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);
        }
    }
);

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

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

我希望这有帮助。

于 2014-12-12T13:43:01.393 回答
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,因为它会为您执行此操作。

于 2014-08-22T17:46:03.993 回答