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

时间:2014-04-24 07:25:28

标签: authentication owin adfs katana

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

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

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

我尝试设置配置属性" MetadataAddress"和#34; 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.

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

3 个答案:

答案 0 :(得分:27)

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

    app.SetDefaultSignInAsAuthenticationType(WsFederationAuthenticationDefaults.AuthenticationType );

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

答案 1 :(得分: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 =" Cookie"
  • WsFederationAuthenticationDefaults.AuthenticationType ="联邦"

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

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

  • 通过返回HTTP 401响应
  • 在MVC控制器上使用[Authorize]属性
  • 通过调用OWIN上下文IAuthenticationManager的{​​{1}}方法(传递联盟中间件的标签)

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

Challenge

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

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

我希望这会有所帮助。

答案 2 :(得分: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,就像它为你做的那样。