我有一个遗留的 WebForms 应用程序,该应用程序使用驻留在同一 IIS 服务器上的(ASP.net)Web服务(使用匿名访问)(同一个域,不同应用程序每个都有自己的专用应用程序池)。此应用程序托管在安全的 VPN 中,但现在请求主办公开。
在不进行大量重新编码的情况下(在应用程序级别)保护Web服务站点的权宜(但安全)方法是什么。我尝试在 IIS 中配置Web服务站点,以便它仅启用运行Web应用程序池的服务帐户(标识),但当前请求模式即将到来从应用程序始终使用匿名访问。我需要限制访问权限以仅允许此特定Web应用程序。我在想一个 ISAPI 过滤器,但不建议用于 IIS 7 +?
ADDENDUM:我很想找到基于IIS的解决方案。目前我正在尝试仅基于Web应用程序源限制访问。问题是(如上所述)那些请求都是" 匿名"如果我可以使用" 网络服务"或者其他一些本地身份然后我会被设置。
答案 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()
{
}
}
}
<强>实施强>
将已编译的DLL(FilterModule.dll
)添加到Web服务(站点)bin
目录。
将以下内容添加到Web服务(或站点)配置文件(web.config)中的模块定义
<system.webServer>
部分中的添加以下内容:
<modules>