问题
我正在努力实现以下目标:
(注意:此域/子域仅用于说明性目的。)
我已经从我的主机WinHost获得了SSL/TLS证书,并且我只将它应用于子域(secure.somedomain.com),而不是主域(somedomain.com)。
当我发布MVC应用程序时,文件实际上存储在目录somedomain.com/secure中。
事实证明,要做到这一点比我想的要困难得多。
我到目前为止尝试过的
我发现了许多关于如何为不同的目的拥有不同的子域的问题(例如,每种语言一个子域,每个公司一个子域,等等),但是我的需求要简单得多--我只是希望我的整个MVC应用程序能够在一个子域上托管。
到目前为止,我尝试了两种基本方法(包括独立的和组合的):
对于方法#1,我有一些运气。我最终想出了一些规则,这些规则将(1)不干扰主域上的网站,(2)阻止对somedomain/secure的任何请求(因为安全证书对主域无效),(3)根据对secure.somedomain.com的请求提供正确的页面。
这种方法的主要失败(至少是孤立的)是静态内容不再被服务,未经身份验证的用户的请求导致不正确的URL,例如"https://secure.somedomain.dom/secure/somecontroller/someaction/?ReturnUrl=%2fsomecontroller“(注意额外的”安全“)。
为了记录在案,下面是我的URL重写:
<system.webServer>
<rewrite>
<rules>
<rule name="subdomain" stopProcessing="true">
<match url="(.*)" />
<conditions>
<add input="{HTTP_HOST}" pattern="^(secure.)somedomain.com$" />
</conditions>
<action type="Rewrite" url="\secure\{R:0}" />
</rule>
<rule name="subfolder" stopProcessing="true">
<match url=".*" />
<conditions>
<add input="{URL}" matchType="Pattern" pattern="^(http://|https://)?(www)?[^/]*/secure" ignoreCase="true" negate="false" />
</conditions>
<action type="CustomResponse" statusCode="403" statusReason="Forbidden: Access is denied." statusDescription="You do not have permission to view this directory or page using the credentials that you supplied." />
</rule>
</rules>
</rewrite>
</system.webServer>至于方法2,老实说,我不能说我尝试过的任何东西都有很大的不同(无论是与URL重写结合使用,还是单独使用)。
首先,我尝试编写以下自定义路由,它基本上是从https://stackoverflow.com/a/15287579/129164中偷来的
public class SubdomainRoute : Route
{
private const string _subdomain = "secure";
public SubdomainRoute(string url) : base(url, new MvcRouteHandler()) { }
public override RouteData GetRouteData(HttpContextBase httpContext)
{
var routeData = base.GetRouteData(httpContext);
if (routeData == null) return null; // Only look at the subdomain if this route matches in the first place.
// A subdomain specified as a query parameter takes precedence over the hostname.
var subdomain = httpContext.Request.Params[_subdomain];
if (subdomain == null)
{
var host = httpContext.Request.Headers["Host"];
var index = host.IndexOf('.');
if (index >= 0) subdomain = host.Substring(0, index);
}
if (subdomain != null) routeData.Values[_subdomain] = subdomain;
return routeData;
}
public override VirtualPathData GetVirtualPath(RequestContext requestContext, RouteValueDictionary values)
{
var subdomainParam = requestContext.HttpContext.Request.Params[_subdomain];
if (subdomainParam != null) values[_subdomain] = subdomainParam;
return base.GetVirtualPath(requestContext, values);
}
}我试图在Global.asax.cs中这样连接它:
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.Add(
"Default",
new SubdomainRoute("{controller}/{action}/{id}")
{
Defaults = new RouteValueDictionary(
new { controller = MVC.Home.Name, action = MVC.Home.ActionNames.Index, id = UrlParameter.Optional }),
Constraints = new RouteValueDictionary(
new { controller = @"[^\.]*" })
});
}(我基本上用routes.Add()代替了routes.Add()。)
我还尝试创建一个自定义路由约束,而不是https://stackoverflow.com/a/15234839/129164建议的自定义路由。我的课是这样的:
public class SubdomainRouteConstraint : IRouteConstraint
{
private readonly string _subdomain;
public SubdomainRouteConstraint(string subdomain)
{
_subdomain = subdomain;
}
public bool Match(
HttpContextBase httpContext,
Route route,
string parameterName,
RouteValueDictionary values,
RouteDirection routeDirection)
{
return httpContext.Request.Url != null && httpContext.Request.Url.Host.StartsWith(_subdomain);
}
}我更新了我的RegisterRoutes方法如下:
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapRoute(
"Default" /* Route name */,
"{controller}/{action}/{id}" /* URL with parameters */,
new { controller = MVC.Home.Name, action = MVC.Home.ActionNames.Index, id = UrlParameter.Optional } /* Parameter defaults */,
new { controller = @"[^\.]*", subdomain = new SubdomainRouteConstraint("secure") } /* Parameter constraints */);
}再一次,当我尝试这个的时候,我没有发现有什么不同。
我遇到的其他一些答案建议编写扩展方法,基本上修改Html.ActionLink和Url.Content,以便在必要时修复URL,但我真的很反对这种方法,因为它需要大量的重构来将其连接起来(鉴于我目前的运气,我不相信它会起作用)。
不管怎么说,如果你还和我在一起,我真的可以用一些建议来处理如何设置我的安全子域(希望如此),而不必对我的MVC应用程序做重大的改动。
另外,如果你在我尝试过的解决方案中看到任何明显的错误,或者你对我应该尝试的具体修改或组合有一些想法,请告诉我。
发布于 2014-03-16 06:52:32
我可能不完全理解你的设置/要求,但如果你有两个独立的领域,两个实体有不同的目的,你为什么不使用两个网站而不是一个网站。
只需在绑定中设置主机标头,并让安全站点的根指向安全文件夹。如果您需要静态站点中的一些静态文件,只需通过一个虚拟目录将它们带进来即可。不需要URL重写或路由。
如果您需要将secure文件夹存储在静态站点下,但不希望用户在那里看到它,只需隐藏它:
<system.webServer>
<security>
<requestFiltering>
<hiddenSegments>
<add segment="secure" />
</hiddenSegments>
</requestFiltering>
</security>
</system.webServer>发布于 2014-03-17 07:12:51
这里还有一个类似的问题-- somedomain.com和abc.subdomain.com。(均在ASP.Net 4.0中) somedomain.com中的静态html文件
将一个简单的aspx文件部署到abc.subdomain.com中。-很好用
将一个简单的mvc3应用程序部署到abc.subdomain.com中。-不工作。显示禁止的消息-您没有访问/在此服务器上的权限。(错误403)。
不对global.asax和webconfig进行任何更改。
部署模式-发布到本地文件夹和ftp上载。(添加了所有依赖项)。
https://stackoverflow.com/questions/22431599
复制相似问题