C# 使用OWIN在不同域上使用服务器进行Ws-Federation身份验证

C# 使用OWIN在不同域上使用服务器进行Ws-Federation身份验证,c#,owin,adfs2.0,ws-federation,C#,Owin,Adfs2.0,Ws Federation,背景: 1个Web服务器:带网站的IIS(购买真实证书)。服务器位于域my-web-domain.com上 1个测试ADFS服务器(2.0):ADFS元数据:(自签名证书) vt.Test域中有1个测试客户端 工作: 我将网站安装在与ADFS(fs.vt.test)相同的服务器上,它可以正常工作 通缉: ADFS是一种在tiers应用程序上对客户端进行身份验证的方法,这就是我的情况。 如果我在服务器my-app-domain.com上尝试我的应用程序,而Owin无法对我进行身份验证

背景:

  • 1个Web服务器:带网站的IIS(购买真实证书)。服务器位于域my-web-domain.com上

  • 1个测试ADFS服务器(2.0):ADFS元数据:(自签名证书)

  • vt.Test域中有1个测试客户端

工作:

  • 我将网站安装在与ADFS(fs.vt.test)相同的服务器上,它可以正常工作
通缉:

  • ADFS是一种在tiers应用程序上对客户端进行身份验证的方法,这就是我的情况。 如果我在服务器my-app-domain.com上尝试我的应用程序,而Owin无法对我进行身份验证
只是一个无声的失败,ADFS事件中没有任何内容,也没有异常或http错误

我为OWIN尝试了很多配置,这是我最后的代码:

app.SetLoggerFactory(new NLogFactory());
        app.UseErrorPage(new ErrorPageOptions()
        {
            //Shows the OWIN environment dictionary keys and values. This detail is enabled by default if you are running your app from VS unless disabled in code. 
            ShowEnvironment = true,
            //Hides cookie details
            ShowCookies = false,
            //Shows the lines of code throwing this exception. This detail is enabled by default if you are running your app from VS unless disabled in code. 
            ShowSourceCode = true,
        });
        app.SetDefaultSignInAsAuthenticationType(CookieAuthenticationDefaults.AuthenticationType);
        app.UseCookieAuthentication(new CookieAuthenticationOptions
        {
            AuthenticationType = WsFederationAuthenticationDefaults.AuthenticationType,
            CookieManager = new SystemWebCookieManager(container.GetInstance<ILoggingService>())
        });

        app.Use(async (Context, next) =>
        {
            new NLogLoggingService("Owin after cookie log").Debug(JsonConvert.SerializeObject(Context.Authentication, Formatting.None,
                    new JsonSerializerSettings()
                    {
                        ReferenceLoopHandling = ReferenceLoopHandling.Ignore
                    }));
            await next.Invoke();
            new NLogLoggingService("Owin after cookie log").Debug(JsonConvert.SerializeObject(Context.Authentication, Formatting.None,
                    new JsonSerializerSettings()
                    {
                        ReferenceLoopHandling = ReferenceLoopHandling.Ignore
                    }));
        });
        //AppBuilderLoggerExtensions
        app.UseWsFederationAuthentication(
            new WsFederationAuthenticationOptions
            {
                Wtrealm = realm,
                MetadataAddress = adfsMetadata,
                AuthenticationMode = AuthenticationMode.Passive,
                Notifications = new WsFederationAuthenticationNotifications
                {
                    AuthenticationFailed = context =>
                    {
                        context.HandleResponse();
                        context.Response.Redirect("Home/Unauthorized?message=" + context.Exception.Message);
                        return Task.FromResult(0);
                    }
                }
});

        app.Use(async (Context, next) =>
        {
            new NLogLoggingService("Owin after federation log").Debug(JsonConvert.SerializeObject(Context.Authentication, Formatting.None,
                     new JsonSerializerSettings()
                     {
                         ReferenceLoopHandling = ReferenceLoopHandling.Ignore
                     }));
            await next.Invoke();
            new NLogLoggingService("Owin after federation log").Debug(JsonConvert.SerializeObject(Context.Authentication, Formatting.None,
                    new JsonSerializerSettings()
                    {
                        ReferenceLoopHandling = ReferenceLoopHandling.Ignore
                    }));
        });
        // This makes any middleware defined above this line run before the Authorization rule is applied in web.config
        app.UseStageMarker(PipelineStage.Authenticate);
app.SetLoggerFactory(新的NLogFactory());
app.UseErrorPage(新的ErrorPageOptions()
{
//显示OWIN环境字典键和值。如果从VS运行应用程序,则默认情况下启用此详细信息,除非在代码中禁用。
ShowEnvironment=true,
//隐藏cookie详细信息
ShowCookies=false,
//显示引发此异常的代码行。如果您是从VS运行应用程序,则默认情况下启用此详细信息,除非在代码中禁用。
ShowSourceCode=true,
});
app.SetDefaultSignInAsAuthenticationType(CookieAuthenticationDefaults.AuthenticationType);
app.UseCookieAuthentication(新的CookieAuthenticationOptions
{
AuthenticationType=WsFederationAuthenticationDefaults.AuthenticationType,
CookieManager=new SystemWebCookieManager(container.GetInstance())
});
应用程序使用(异步(上下文,下一步)=>
{
新的NLogLoggingService(“cookie日志后的Owin”).Debug(JsonConvert.SerializeObject(Context.Authentication,Formatting.None,
新的JsonSerializerSettings()
{
ReferenceLoopHandling=ReferenceLoopHandling.Ignore
}));
等待next.Invoke();
新的NLogLoggingService(“cookie日志后的Owin”).Debug(JsonConvert.SerializeObject(Context.Authentication,Formatting.None,
新的JsonSerializerSettings()
{
ReferenceLoopHandling=ReferenceLoopHandling.Ignore
}));
});
//AppBuilderLoggerExtensions
app.UseWsFederationAuthentication(
新WsFederationAuthenticationOptions
{
Wtrealm=realm,
MetadataAddress=adfsMetadata,
AuthenticationMode=AuthenticationMode.Passive,
通知=新WsFederationAuthenticationNotifications
{
AuthenticationFailed=上下文=>
{
context.HandleResponse();
context.Response.Redirect(“Home/Unauthorized?message=“+context.Exception.message”);
返回Task.FromResult(0);
}
}
});
应用程序使用(异步(上下文,下一步)=>
{
新的NLogLoggingService(“联合日志后的Owin”).Debug(JsonConvert.SerializeObject(Context.Authentication,Formatting.None,
新的JsonSerializerSettings()
{
ReferenceLoopHandling=ReferenceLoopHandling.Ignore
}));
等待next.Invoke();
新的NLogLoggingService(“联合日志后的Owin”).Debug(JsonConvert.SerializeObject(Context.Authentication,Formatting.None,
新的JsonSerializerSettings()
{
ReferenceLoopHandling=ReferenceLoopHandling.Ignore
}));
});
//这使得在web.config中应用授权规则之前,该行上面定义的任何中间件都会运行
应用程序UseStageMarker(PipelineStage.Authenticate);
我在下面的帖子中介绍了如何在ADFS管理中配置我的参与方信任:

我的配置是:

  • ida:ADFSMetadata:“

  • 艾达:你是谁

我一直在搜索博客,stackoverflow已经有几天了,但我的身份验证无法正常工作。可能是证书颁发或

我找不到调试配置错误的方法


我的Nlog中没有来自OWIN的任何内容。

请尝试wireshark并将Wait放在Try-catch块中,因为错误消息可能会被吞没。我也遵循了您上面提到的tut,我的代码可以工作,但在我的情况下,两个虚拟机都在同一个域中。这可能也有助于调试身份验证问题。请尝试wireshark并将Wait放在Try-catch块中,因为错误消息可能会被吞没。我也遵循了你上面提到的这个tut,我的代码可以工作,但是在我的例子中,两个虚拟机都在同一个域中。也许这也有助于调试auth问题。