Authentication 使用OWIN Ws-Federation包根据ADFS 3.0进行身份验证

Authentication 使用OWIN Ws-Federation包根据ADFS 3.0进行身份验证,authentication,owin,adfs,katana,Authentication,Owin,Adfs,Katana,我有一个MVC内部网站,需要使用AD帐户进行身份验证 我设置了ADFS 3.0(Win Server 2012 R2),然后设置了ADFS依赖方信任 另一篇文章介绍了Ws-Federation OWIN组件,我想使用它。它提到了如何连接到Azure广告,但没有提到关于ADF的内容 我尝试设置配置属性“MetadataAddress”和“Wtrealm”以匹配我在ADFS中配置的内容,但在运行时出现错误: A default value for SignInAsAuthenticationType

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

我设置了ADFS 3.0(Win Server 2012 R2),然后设置了ADFS依赖方信任

另一篇文章介绍了Ws-Federation OWIN组件,我想使用它。它提到了如何连接到Azure广告,但没有提到关于ADF的内容

我尝试设置配置属性“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.

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

是的。。我遇到了同样的问题。只需执行以下操作,它就会起作用:

    app.SetDefaultSignInAsAuthenticationType(WsFederationAuthenticationDefaults.AuthenticationType );

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

实际上,您只是缺少这一行,这一行通常位于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,因为它为您做了这件事。

我一直在努力解决这一问题,特别是感谢和,我相信公认的做法如下:

app.SetDefaultSignInAsAuthenticationType(CookieAuthenticationDefaults.AuthenticationType);

app.UseCookieAuthentication(
    new CookieAuthenticationOptions { }
);

app.UseWsFederationAuthentication(
    new WsFederationAuthenticationOptions
    {
        Wtrealm = ConfigurationManager.AppSettings["ida:Wtrealm"],
        MetadataAddress = ConfigurationManager.AppSettings["ida:FedMetadataURI"]
    }
);
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);
        }
    }
);
您将默认身份验证类型配置为“Cookie身份验证”以使WsFederation正常工作,这似乎是违反直觉的,但是这些实际上只是用于标识每个中间件的字符串(例如,这允许您多次注册同一类型的中间件),它们的评估如下:

app.SetDefaultSignInAsAuthenticationType(CookieAuthenticationDefaults.AuthenticationType);

app.UseCookieAuthentication(
    new CookieAuthenticationOptions { }
);

app.UseWsFederationAuthentication(
    new WsFederationAuthenticationOptions
    {
        Wtrealm = ConfigurationManager.AppSettings["ida:Wtrealm"],
        MetadataAddress = ConfigurationManager.AppSettings["ida:FedMetadataURI"]
    }
);
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);
        }
    }
);
  • CookieAuthenticationDefault.AuthenticationType
    =“Cookies”
  • WsFederationAuthenticationDefaults.AuthenticationType
    =“联合”
这里发生的事情是,我们告诉OWIN,默认情况下应该使用标记为“Cookies”的中间件对请求进行身份验证,然后添加Cookie身份验证中间件(默认情况下,标记为“Cookies”)从
CookieAuthenticationDefaults.AuthenticationType
值,因此我们不必编写任何附加代码来设置它),最后我们添加FederationAuthentication中间件(该中间件的标签为
WsFederationAuthenticationDefaults.AuthenticationType
-即“Federation”),我的理解是,联合中间件使用Cookie中间件来管理其与身份验证相关的Cookie

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

app.SetDefaultSignInAsAuthenticationType(CookieAuthenticationDefaults.AuthenticationType);

app.UseCookieAuthentication(
    new CookieAuthenticationOptions { }
);

app.UseWsFederationAuthentication(
    new WsFederationAuthenticationOptions
    {
        Wtrealm = ConfigurationManager.AppSettings["ida:Wtrealm"],
        MetadataAddress = ConfigurationManager.AppSettings["ida:FedMetadataURI"]
    }
);
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);
        }
    }
);
  • 通过返回HTTP 401响应
  • 在MVC控制器上使用
    [Authorize]
    属性
  • 通过调用OWIN上下文
    IAuthenticationManager
    Challenge
    方法(传递联合中间件的标签)
当我问这个问题时,Lars给出了一个简洁的示例,说明了如何为所有请求请求请求身份验证,然后我将其捆绑到OWIN管道中,如下所示:

app.SetDefaultSignInAsAuthenticationType(CookieAuthenticationDefaults.AuthenticationType);

app.UseCookieAuthentication(
    new CookieAuthenticationOptions { }
);

app.UseWsFederationAuthentication(
    new WsFederationAuthenticationOptions
    {
        Wtrealm = ConfigurationManager.AppSettings["ida:Wtrealm"],
        MetadataAddress = ConfigurationManager.AppSettings["ida:FedMetadataURI"]
    }
);
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>


我希望这有帮助。

完全正确。通过查看Vittorio Bertocci在GitHub上提供的示例,您可以看到Microsoft推荐的方法正是这样:我发现使用app.SetDefaultSignInAsAuthenticationType(CookieAuthenticationDefaults.AuthenticationType);导致身份验证循环导致异常:MSIS7042:同一客户端浏览器会话在过去“1”秒内发出了“6”个请求,而app.SetDefaultSignInAsAuthenticationType(WsFederationAuthenticationDefaults.AuthenticationType);为我工作;并且在初始身份验证握手后确实传递了cookies安装包Microsoft.Owin.Security.cookies