简体   繁体   English

WebSeal反向代理背后的.Net Web应用程序

[英].Net web application behind a WebSeal reverse proxy

We are currently designing a solution that will run as a .Net Web application behind a WebSeal reverse proxy. 我们目前正在设计一个在WebSeal反向代理后面作为.Net Web应用程序运行的解决方案。

I have seen some comments on the net where people have had various problems with this, for example rewriting of viewstate. 我在网上看到了一些评论,人们对此有各种各样的问题,例如重写viewstate。

Question is: Has anyone implemented this combination of techologies and got it to work? 问题是:有没有人实施这种技术组合并让它发挥作用?

I made an ASP.NET application workin behind WEBSEAL. 我在WEBSEAL后面创建了一个ASP.NET应用程序。 After lot of study and development and test it works. 经过大量的研究和开发和测试,它的工作原理。

I suggest some issues to help you: 我建议一些问题来帮助你:

IIS and ASP.NET are case insensitive IIS和ASP.NET不区分大小写

("...Login.aspx" and "...login.aspx" both lead to the same page); (“... Login.aspx”和“... login.aspx”都导致同一页面); by default webseal is case sensitive. 默认情况下,webseal区分大小写。 So you should set WEBSEAL junction to be case insensitive or check any single link (page, javascript, image) 因此,您应该将WEBSEAL结点设置为不区分大小写或检查任何单个链接(页面,javascript,图像)

Internal links, written as server relative URLs won't be served 将不提供作为服务器相对URL编写的内部链接

WEBSEAL changes any link referring your application but doesn't change links to other applications. WEBSEAL会更改引用您的应用程序的任何链接,但不会更改指向其他应用程序的链接。 Internal links, written as server relative URLs instead of application relative URLs won't be changed (WEBSEAL doesn't recognize it's the same application) and won't be served (WEBSEAL rejects links that are not modified). 内部链接(作为服务器相对URL而不是应用程序相对URL)将不会更改(WEBSEAL不会识别它是相同的应用程序)并且不会被提供(WEBSEAL拒绝未修改的链接)。
First rule is to check any single link and make it an application relative URL . 第一条规则是检查任何单个链接并使其成为应用程序相对URL
Look at rendered HTML if you find <.. href=/ anything> : this ia server relative URL and it is bad. 如果找到<.. href=/ anything>查看呈现的HTML:这个ia服务器相对URL并且它很糟糕。
Look in the Code Behind if you use "= ~/ anything" it is good. 如果使用"= ~/ anything" ,请查看Code Behind,这很好。 If you use "= / anything" OR ResolveUrl(..) it is bad. 如果使用"= / anything"ResolveUrl(..)则不好。

But this is not enough: AJAX puts loads of javascript and code inside ScriptResource.axd and WebResource.axd and creates server relative URL to link it. 但这还不够:AJAX将大量的javascript和代码放在ScriptResource.axdWebResource.axd中,并创建服务器相对URL来链接它。 This links are not controlled by programmers and there is no easy way to change them. 这些链接不受程序员的控制,也没有简单的方法来改变它们。
Easy solution (if possible): solve the problem setting WEBSEAL junction to be transparent . 简单的解决方案(如果可能):解决问题设置WEBSEAL结是透明的
Hard solution: write the following code (thanks to this answer ) 硬解决方案:编写以下代码(感谢这个答案

protected void Page_Load(object sender, EventArgs e)
    {
        //Initialises my dirty hack to remove the leading slash from all web reference files.
        Response.Filter = new WebResourceResponseFilter(Response.Filter);
    }

public class WebResourceResponseFilter : Stream
{
    private Stream baseStream;

    public WebResourceResponseFilter(Stream responseStream)
    {
        if (responseStream == null)
            throw new ArgumentNullException("ResponseStream");
        baseStream = responseStream;
    }

    public override bool CanRead
    { get { return baseStream.CanRead; } }

    public override bool CanSeek
    { get { return baseStream.CanSeek; } }

    public override bool CanWrite
    { get { return baseStream.CanWrite; } }

    public override void Flush()
    { baseStream.Flush(); }

    public override long Length
    { get { return baseStream.Length; } }

    public override long Position
    {
        get { return baseStream.Position; }
        set { baseStream.Position = value; }
    }

    public override int Read(byte[] buffer, int offset, int count)
    { return baseStream.Read(buffer, offset, count); }

    public override long Seek(long offset, System.IO.SeekOrigin origin)
    { return baseStream.Seek(offset, origin); }

    public override void SetLength(long value)
    { baseStream.SetLength(value); }

    public override void Write(byte[] buffer, int offset, int count)
    {
        //Get text from response stream.
        string originalText = System.Text.Encoding.UTF8.GetString(buffer, offset, count);

        //Alter the text.
        originalText = originalText.Replace(HttpContext.Current.Request.ApplicationPath + "/WebResource.axd",
            VirtualPathUtility.MakeRelative(HttpContext.Current.Request.Url.AbsolutePath, "~/WebResource.axd"));
        originalText = originalText.Replace(HttpContext.Current.Request.ApplicationPath + "/ScriptResource.axd",
            VirtualPathUtility.MakeRelative(HttpContext.Current.Request.Url.AbsolutePath, "~/ScriptResource.axd"));

        //Write the altered text to the response stream.
        buffer = System.Text.Encoding.UTF8.GetBytes(originalText);
        this.baseStream.Write(buffer, 0, buffer.Length);

    }

This intercepts the stream to the page and replaces all occurrences of "/WebResource.axd" or "ScriptResource.axd" with "../../WebResource.axd" and "../../ScriptResource.axd" 这将拦截流到页面,并将所有出现的“/WebResource.axd”或“ScriptResource.axd”替换为“../../WebResource.axd”和“../../ScriptResource.axd”

Develop code to get actual WEBSEAL user 开发代码以获得实际的WEBSEAL用户

WEBSEAL has been configured to put username inside HTTP_IV_USER . WEBSEAL已配置为将用户名放在HTTP_IV_USER中 I created Webseal\\Login.aspx form to read it programmatically. 我创建了Webseal \\ Login.aspx表单以编程方式读取它。 Now, in order to make this user the CurrentUser I put an hidden asp.Login 现在,为了使这个用户成为CurrentUser我放了一个隐藏的asp.Login

<span style="visibility:hidden"> 
<asp:Login ID="Login1" runat="server" DestinationPageUrl="~/Default.aspx">..

and clicked the button programmatically 并以编程方式单击该按钮

protected void Page_Load(object sender, EventArgs e)
{
    string username = Request.ServerVariables["HTTP_IV_USER"];
    (Login1.FindControl("Password") as TextBox).Text = MyCustomProvider.PswJump;
    if (!string.IsNullOrEmpty(username))
    {
        (Login1.FindControl("UserName") as TextBox).Text = username;
        Button btn = Login1.FindControl("LoginButton") as Button;
        ((IPostBackEventHandler)btn).RaisePostBackEvent(null);
     }
    else
    {
        lblError.Text = "Login error.";
    }
}

When LoginButton fires, application reads UserName (set from WEBSEAL variable) and password (hard coded). LoginButton触发时,应用程序读取UserName(从WEBSEAL变量设置)和密码(硬编码)。 So i implemented a custom membership provider that validates users and sets current Principal. 所以我实现了一个自定义成员资格提供程序 ,用于验证用户并设置当前Principal。

Changes in web.config web.config中的更改

loginUrl is the URL for the login page that the FormsAuthentication class will redirect to. loginUrl是FormsAuthentication类将重定向到的登录页面的URL。 It has been set to WEBSEAL portal: not authenticated user and logout button will redirect to portal. 它已设置为WEBSEAL门户:未经过身份验证的用户和注销按钮将重定向到门户网站。

<authentication mode="Forms">
  <forms loginUrl="https://my.webseal.portal/" defaultUrl="default.aspx"...."/>
</authentication>

Since Webseal/login.aspx is NOT default login page, authorization tag grants access to not authenticated users: 由于Webseal / login.aspx不是默认登录页面,因此授权标记授予对未经过身份验证的用户的访问权限:

<location path="Webseal/login.aspx">
    <system.web>
        <authorization>
            <allow users="*"/>
        </authorization>
    </system.web>
</location>

Application is set to use custom membership providers: 应用程序设置为使用自定义成员资格提供

 <membership defaultProvider="MyCustomMembershipProvider">
  <providers>
    <add name="MyCustomMembershipProvider" type="MyNamespace.MyCustomMembershipProvider" connectionStringName="LocalSqlServer"/>
  </providers>
</membership>
<roleManager enabled="true" defaultProvider="MyCustomRoleProvider">
  <providers>
    <add name="MyCustomRoleProvider" type="MyNamespace.MyCustomRoleProvider" connectionStringName="LocalSqlServer"/>
  </providers>
</roleManager>

Debug is set to off: Debug设置为off:

<compilation debug="false" targetFramework="4.0">

that's all folks! 这是所有人!

I initially has some issues with the ASP.Net app when accessed through WebSeal. 当通过WebSeal访问时,我最初对ASP.Net应用程序有一些问题。 I was running the site on a development server. 我在开发服务器上运行该站点。 What worked for me was to deploy the application with debugging turned off in the config file. 对我有用的是在配置文件中关闭调试部署应用程序。

<compilation debug="false" ...>

With debugging turned on, there were some AJAX calls that would work fine when I accessed the site directly but would fail when access through WebSeal. 启用调试后,有些AJAX调用在我直接访问站点时可以正常工作,但在通过WebSeal访问时会失败。 Once I turned the debugging off, everything work fine. 一旦我关闭调试,一切正常。

Also, because WebSeal requires anonymous authentication, we couldn't have used Windows Authentication. 此外,由于WebSeal需要匿名身份验证,因此我们无法使用Windows身份验证。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 反向代理后面的 ASP.NET MVC 应用程序 - 身份验证后使用错误的主机名 - ASP.NET MVC application behind reverse proxy - using wrong host name after auth 反向代理背后的 WebService - WebService behind reverse proxy nginx反向代理背后的ASP.NET customErrors - ASP.NET customErrors behind nginx reverse proxy C# Web 应用程序 -&gt; 代理所有请求 -&gt; 从另一个 Web 应用程序返回内容(反向代理) - C# web application -> proxy all requests -> return content from another web application (Reverse proxy) ASP.NET 应用程序需要 ISA Server(反向代理) - Need of ISA Server (Reverse Proxy) for ASP.NET application 当ASP.NET服务器作为反向代理位于ISA服务器之后时,获取原始HOST地址 - Get original HOST address when the ASP.NET server is behind an ISA server as a reverse proxy 如果启用了代理,asp.net Web应用程序将无法运行 - asp.net web application is not working if proxy enabled IIS URL将反向代理重写为localhost上的asp.net核心Web应用 - IIS url rewrite reverse proxy to asp.net core web app on localhost WCF在公共反向代理后面,用于流量加密 - WCF behind a public reverse proxy which is used for traffic encryption 将 NGINX 与 Asp.Net Core 应用程序反向代理配置为子文件夹,如 IIS - Configure NGINX with Asp.Net Core Application Reverse Proxy as SubFolder like IIS
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM