使用匿名身份验证保护旧版Web服务站点以进行本地访问

时间:2017-09-05 22:01:29

标签: asp.net web-services iis isapi

我有一个遗留的 WebForms 应用程序,该应用程序使用驻留在同一 IIS 服务器上的(ASP.net)Web服务(使用匿名访问)(同一个域,不同应用程序每个都有自己的专用应用程序池)。此应用程序托管在安全的 VPN 中,但现在请求主办公开

在不进行大量重新编码的情况下(在应用程序级别)保护Web服务站点的权宜(但安全)方法是什么。我尝试在 IIS 中配置Web服务站点,以便它仅启用运行Web应用程序池的服务帐户(标识),但当前请求模式即将到来从应用程序始终使用匿名访问。我需要限制访问权限以仅允许此特定Web应用程序。我在想一个 ISAPI 过滤器,但不建议用于 IIS 7 +?

  

ADDENDUM:我很想找到基于IIS的解决方案。目前我正在尝试仅基于Web应用程序源限制访问。问题是(如上所述)那些请求都是" 匿名"如果我可以使用" 网络服务"或者其他一些本地身份然后我会被设置。

2 个答案:

答案 0 :(得分:2)

我建议你使用IdentityServer和OpenIdConnect来做到这一点。

  

IdentityServer是一个基于.NET / Katana的框架和托管组件   这允许实现现代的单点登录和访问控制   使用OpenID Connect和OpenID等协议的Web应用程序和API   OAuth2用户。它支持广泛的客户,如移动,网络,SPA和   桌面应用程序,可扩展,允许集成到新的和   现有架构。

     

OpenID Connect 1.0是OAuth 2.0之上的简单身份层   协议。它允许客户端验证最终用户的身份   基于授权服务器执行的身份验证,如   以及获取有关最终​​用户的基本配置文件信息   可互操作且类似REST的方式。 https://connect2id.com/learn/openid-connect

使用此功能,您可以要求身份服务器为您提供访问令牌和Id令牌。

  

身份令牌表示身份验证过程的结果。   它至少包含用户的标识符(称为   sub aka subject claim)。它可以包含有关的其他信息   用户以及用户如何在OP上进行身份验证的详细信息。

     

访问令牌允许访问资源。客户端请求访问权限   令牌并将它们转发给API。访问令牌包含信息   关于客户和用户(如果有的话)。 API使用该信息   授权访问他们的数据。

在您的情况下,您可以在Webforms应用程序和WebService之间实现客户端凭据流。 (在此流程中,您不会向WebForms应用程序的用户提出任何要求)。因此,我们的想法是WebForms应用程序将要求身份服务器为其提供访问令牌以访问Web服务资源。在WebService中,您必须根据您想要的任何内容(范围,声明等)实现授权。请阅读LeastPrivilege博客(Dominick Baier),他和他的好友Brock Allen一起是这个话题的主人。由于我无法在StackOverflow中发布超过1个链接,这非常糟糕,您必须谷歌或谷歌任何其他信息。

如果您需要用户身份验证,可以使用隐式,代码或混合流。但这取决于你真正想做的事情。

我认为你可能需要做一些代码,但不是太多。您可以找到在达到任何端点之前请求授权的方法。

我希望我很清楚。如果没有,请向我询问更多解释。

答案 1 :(得分:1)

经过更多研究后,我选择了http Module解决方案,因为它具有以下好处:

•最小编码

•无需修改现有代码库

•轻松部署

•遵循现有的ASP.Net安全模型(本地访问)

模块(VS:DLL项目)

using System;
using System.Web;
using System.Threading;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace FilterModule
{
    class AuthorizeLocal : IHttpModule
    {
        public void Init(HttpApplication app)
        {
            app.BeginRequest += new EventHandler(OnBeginRequest);
        }


        private void OnBeginRequest(Object s, EventArgs e)
        {
            HttpApplication app = s as HttpApplication;
            HttpRequest req = app.Request;
            HttpContext context = app.Context;

            if (!req.IsLocal)    // Is the request from a Local Source?
            {
                context.Response.Close(); // close the response: ends request
            }

            /* Optional Test Code - to view locally create an html page TestModule.html in target site */
            string Identity = Thread.CurrentPrincipal.Identity.Name;
            string filePath = context.Request.FilePath;
            string fileExtension = VirtualPathUtility.GetExtension(filePath);
            string fileName = VirtualPathUtility.GetFileName(filePath);

            if (fileName.ToLower().Equals("testmodule.html"))
            {
                try
                {
                    app.Context.Response.Write("app: " + app.ToString());
                    context.Response.Write("<br/>server: " + app.Server.ToString());
                    context.Response.Write("<br/>Thread.CurrentPrincipal.Identity.Name: " + Thread.CurrentPrincipal.Identity.Name);
                    context.Response.Write("<br/>HttpRequest: " + req.Url.ToString());
                    context.Response.Write("<br/>req.UserHostName: " + req.UserHostName);
                    context.Response.Write("<br/>req.UserHostAddress: " + req.UserHostAddress);
                    context.Response.Write("<br/>filePath: " + filePath);
                    context.Response.Write("<br/>fileName: " + fileName);
                    context.Response.Write("<br/>fileExtension: " + fileExtension);
                    context.Response.Write("<br/>req.IsLocal: " + req.IsLocal.ToString());
                    context.Response.Write("<br/>req.LogonUserIdentity: " + req.LogonUserIdentity);
                    context.Response.Write("<br/>req.UserHostName : " + req.UserHostName);
                    context.Response.Write("<br/>req.AnonymousID " + req.AnonymousID);
                    context.Response.Write("<br/>req.IsAuthenticated : " + req.IsAuthenticated);
                }
                catch (Exception Ex)
                {
                    context.Response.Write("<br/> " + Ex.ToString());
                }
            }

            //if (_eventHandler != null)
            //    _eventHandler(this, null);
        }

        public void Dispose()
        {

        }

    }
}

<强>实施

  1. 将已编译的DLL(FilterModule.dll)添加到Web服务(站点)bin目录。

  2. 将以下内容添加到Web服务(或站点)配置文件(web.config)中的模块定义

  3. <{1}}下的<system.webServer>部分中的

    添加以下内容:

    <modules>