Asp.net OWIN WS-Federation在SSL代理后重定向

Asp.net OWIN WS-Federation在SSL代理后重定向,asp.net,owin,adfs,ws-federation,Asp.net,Owin,Adfs,Ws Federation,我正在尝试编写我的第一个启用ADFS的ASP.Net web应用程序。该应用程序在我的本地计算机上运行正常,但当我将其发布到IIS(位于SSL代理之后)时,我的应用程序最终会将经过身份验证的用户重定向到应用程序的http地址,而不是https地址。我如何解决这个问题 为了澄清流程的故障,以下是发生的情况: 未经验证的用户浏览应用程序主页并重定向至Idp[良好] 用户在Idp进行身份验证,令牌通过https POST发送回我的应用程序[良好] 我的应用程序分配一个cookie,并将用户重定向到ht

我正在尝试编写我的第一个启用ADFS的ASP.Net web应用程序。该应用程序在我的本地计算机上运行正常,但当我将其发布到IIS(位于SSL代理之后)时,我的应用程序最终会将经过身份验证的用户重定向到应用程序的http地址,而不是https地址。我如何解决这个问题

为了澄清流程的故障,以下是发生的情况:

  • 未经验证的用户浏览应用程序主页并重定向至Idp[良好]
  • 用户在Idp进行身份验证,令牌通过https POST发送回我的应用程序[良好]
  • 我的应用程序分配一个cookie,并将用户重定向到http主页[错误]
  • 在我的Startup.Auth.cs中,我只是使用样板代码:

        public partial class Startup
        {
        private static string realm = ConfigurationManager.AppSettings["ida:Wtrealm"];
        private static string adfsMetadata = ConfigurationManager.AppSettings["ida:ADFSMetadata"];
    
        public void ConfigureAuth(IAppBuilder app)
        {
            app.SetDefaultSignInAsAuthenticationType(CookieAuthenticationDefaults.AuthenticationType);
    
            app.UseCookieAuthentication(new CookieAuthenticationOptions());
    
            app.UseWsFederationAuthentication(
                new WsFederationAuthenticationOptions
                {
                    Wtrealm = realm,
                    MetadataAddress = adfsMetadata                    
                });
        }
        }
    
    我已经读过几篇关于ssl代理背后的identity/auth的类似问题的帖子,并且建议对我没有影响。我猜是因为重定向是由ws-fed中间件而不是cookie提供者执行的。

    明白了

    在阅读了OWIN/Katana源代码之后,我在ws-fed代码中找到了允许您操作url的钩子。在我的例子中,如果检测到SSL代理的存在(通过检查请求头),我将重写URL以实现https而不是http

    public partial class Startup
    {
        private static string realm = ConfigurationManager.AppSettings["ida:Wtrealm"];
        private static string adfsMetadata = ConfigurationManager.AppSettings["ida:ADFSMetadata"];
    
        public void ConfigureAuth(IAppBuilder app)
        {
            app.SetDefaultSignInAsAuthenticationType(CookieAuthenticationDefaults.AuthenticationType);
    
            app.UseCookieAuthentication(new CookieAuthenticationOptions());
    
            app.UseWsFederationAuthentication(
                new WsFederationAuthenticationOptions
                {
                    Wtrealm = realm,
                    MetadataAddress = adfsMetadata,
                    Notifications = new WsFederationAuthenticationNotifications
                    {
                        SecurityTokenValidated = (notification) =>
                        {
                            notification.AuthenticationTicket.Properties.RedirectUri = ApplySchemeFromSSLProxy(notification.Request, notification.AuthenticationTicket.Properties.RedirectUri);
                            return Task.FromResult(0);
                        },
                        RedirectToIdentityProvider = (notification) =>
                        {
                            if (notification.ProtocolMessage.IsSignOutMessage)
                            {
                                notification.ProtocolMessage.Wreply = ApplySchemeFromSSLProxy(notification.Request, notification.ProtocolMessage.Wreply);
                            }
                            return Task.FromResult(0);
                        }                       
                    }
                });
        }
    
        /// <summary>
        /// If there is evidence of an SSL proxy in use, convert the uri to https.
        /// </summary>
        /// <param name="request"></param>
        /// <param name="uri"></param>
        /// <returns>Converted URI</returns>
        private string ApplySchemeFromSSLProxy(IOwinRequest request, string uri)
        {            
            if (
                Uri.IsWellFormedUriString(uri, UriKind.Absolute) && 
                request.Headers.Any(h => 
                    h.Key.ToLower().StartsWith("x-forwarded-proto") && 
                    h.Value.Contains(Uri.UriSchemeHttps)
                    )
                )
            {
                var uriBuilder = new UriBuilder(uri)
                {
                    Scheme = Uri.UriSchemeHttps,
                    Port = -1 // default port for scheme
                };
                return uriBuilder.ToString();
            }
            else
            {
                return uri;
            }
        }
    
    }
    
    公共部分类启动
    {
    私有静态字符串realm=ConfigurationManager.AppSettings[“ida:Wtrealm”];
    私有静态字符串adfsMetadata=ConfigurationManager.AppSettings[“ida:adfsMetadata”];
    public void ConfigureAuth(IAppBuilder应用程序)
    {
    app.SetDefaultSignInAsAuthenticationType(CookieAuthenticationDefaults.AuthenticationType);
    app.UseCookieAuthentication(新的CookieAuthenticationOptions());
    app.UseWsFederationAuthentication(
    新WsFederationAuthenticationOptions
    {
    Wtrealm=realm,
    MetadataAddress=adfsMetadata,
    通知=新WsFederationAuthenticationNotifications
    {
    SecurityTokenValidated=(通知)=>
    {
    notification.AuthenticationTicket.Properties.RedirectUri=ApplySchemeFromSSLProxy(notification.Request,notification.AuthenticationTicket.Properties.RedirectUri);
    返回Task.FromResult(0);
    },
    RedirectToIdentityProvider=(通知)=>
    {
    if(notification.ProtocolMessage.IsSignOutMessage)
    {
    notification.ProtocolMessage.Wreply=ApplySchemeFromSSLProxy(notification.Request,notification.ProtocolMessage.Wreply);
    }
    返回Task.FromResult(0);
    }                       
    }
    });
    }
    /// 
    ///如果有证据表明正在使用SSL代理,请将uri转换为https。
    /// 
    /// 
    /// 
    ///转换URI
    私有字符串ApplySchemeFromSSLProxy(IOwinRequest请求,字符串uri)
    {            
    如果(
    IsWellFormedUriString(Uri,UriKind.Absolute)和
    request.Headers.Any(h=>
    h、 Key.ToLower().StartsWith(“x-forwarded-proto”)和
    h、 Value.Contains(Uri.UriSchemeHttps)
    )
    )
    {
    var uriBuilder=新的uriBuilder(uri)
    {
    Scheme=Uri.UriSchemeHttps,
    端口=-1//方案的默认端口
    };
    返回uriBuilder.ToString();
    }
    其他的
    {
    返回uri;
    }
    }
    }
    
    明白了

    在阅读了OWIN/Katana源代码之后,我在ws-fed代码中找到了允许您操作url的钩子。在我的例子中,如果检测到SSL代理的存在(通过检查请求头),我将重写URL以实现https而不是http

    public partial class Startup
    {
        private static string realm = ConfigurationManager.AppSettings["ida:Wtrealm"];
        private static string adfsMetadata = ConfigurationManager.AppSettings["ida:ADFSMetadata"];
    
        public void ConfigureAuth(IAppBuilder app)
        {
            app.SetDefaultSignInAsAuthenticationType(CookieAuthenticationDefaults.AuthenticationType);
    
            app.UseCookieAuthentication(new CookieAuthenticationOptions());
    
            app.UseWsFederationAuthentication(
                new WsFederationAuthenticationOptions
                {
                    Wtrealm = realm,
                    MetadataAddress = adfsMetadata,
                    Notifications = new WsFederationAuthenticationNotifications
                    {
                        SecurityTokenValidated = (notification) =>
                        {
                            notification.AuthenticationTicket.Properties.RedirectUri = ApplySchemeFromSSLProxy(notification.Request, notification.AuthenticationTicket.Properties.RedirectUri);
                            return Task.FromResult(0);
                        },
                        RedirectToIdentityProvider = (notification) =>
                        {
                            if (notification.ProtocolMessage.IsSignOutMessage)
                            {
                                notification.ProtocolMessage.Wreply = ApplySchemeFromSSLProxy(notification.Request, notification.ProtocolMessage.Wreply);
                            }
                            return Task.FromResult(0);
                        }                       
                    }
                });
        }
    
        /// <summary>
        /// If there is evidence of an SSL proxy in use, convert the uri to https.
        /// </summary>
        /// <param name="request"></param>
        /// <param name="uri"></param>
        /// <returns>Converted URI</returns>
        private string ApplySchemeFromSSLProxy(IOwinRequest request, string uri)
        {            
            if (
                Uri.IsWellFormedUriString(uri, UriKind.Absolute) && 
                request.Headers.Any(h => 
                    h.Key.ToLower().StartsWith("x-forwarded-proto") && 
                    h.Value.Contains(Uri.UriSchemeHttps)
                    )
                )
            {
                var uriBuilder = new UriBuilder(uri)
                {
                    Scheme = Uri.UriSchemeHttps,
                    Port = -1 // default port for scheme
                };
                return uriBuilder.ToString();
            }
            else
            {
                return uri;
            }
        }
    
    }
    
    公共部分类启动
    {
    私有静态字符串realm=ConfigurationManager.AppSettings[“ida:Wtrealm”];
    私有静态字符串adfsMetadata=ConfigurationManager.AppSettings[“ida:adfsMetadata”];
    public void ConfigureAuth(IAppBuilder应用程序)
    {
    app.SetDefaultSignInAsAuthenticationType(CookieAuthenticationDefaults.AuthenticationType);
    app.UseCookieAuthentication(新的CookieAuthenticationOptions());
    app.UseWsFederationAuthentication(
    新WsFederationAuthenticationOptions
    {
    Wtrealm=realm,
    MetadataAddress=adfsMetadata,
    通知=新WsFederationAuthenticationNotifications
    {
    SecurityTokenValidated=(通知)=>
    {
    notification.AuthenticationTicket.Properties.RedirectUri=ApplySchemeFromSSLProxy(notification.Request,notification.AuthenticationTicket.Properties.RedirectUri);
    返回Task.FromResult(0);
    },
    RedirectToIdentityProvider=(通知)=>
    {
    if(notification.ProtocolMessage.IsSignOutMessage)
    {
    notification.ProtocolMessage.Wreply=ApplySchemeFromSSLProxy(notification.Request,notification.ProtocolMessage.Wreply);
    }
    返回Task.FromResult(0);
    }                       
    }
    });
    }
    /// 
    ///如果有证据表明正在使用SSL代理,请将uri转换为https。
    /// 
    /// 
    /// 
    ///转换URI
    私有字符串ApplySchemeFromSSLProxy(IOwinRequest请求,字符串uri)
    {            
    如果(
    IsWellFormedUriString(Uri,UriKind.Absolute)和
    request.Headers.Any(h=>
    h、 Key.ToLower().StartsWith(“x-forwarded-proto”)&&