Andrey Pesoshin
Andrey Pesoshin

Reputation: 1186

Incorrect redirect from ASP.NET MVC application under URL Rewrite

I have the next configuration of websites in the IIS:

A wildcard binding *.domain.com is specified in DNS settings.

The desired behavior is to have http://main.domain.com as an entry point and a set of dynamic user-subdomains like http://user1.domain.com, http://user2.domain.com, etc.

Now this behavior is simulated using links like http://main.domain.com/user/user1

I have set up the URL Rewrite rule for main.domain.com in the way like this:

<rule name="user-redirection" enabled="true" stopProcessing="true">
  <match url="^.*$" />
  <conditions logicalGrouping="MatchAll" trackAllCaptures="true">
    <add input="{HTTP_HOST}" pattern="^([\w\d-]+)\.domain\.com$" />
  </conditions>
  <action type="Rewrite" url="http://main.domain.com/user/{C:1}/{R:0}" logRewrittenUrl="true" />
</rule>

Everything is ok here - I can see that http://user1.domain.com works just like http://main.domain.com/user/user1 as it worked earlier.

Then I try to re-implement a logic of checking the existance of specified user in the database. For instance, when user47 doesn't exist - opening of the http://main.domain.com/user/user47 link leads to redirection to the http://main.domain.com entry point.

In the code-side it is done by adding custom filter attribute to the controller action that implements the needed conditional redirect. I have the next code:

public class UserController : Controller {
    [CustomRedirectBehavior]
    public ActionResult Index()
    {
       ...
    }
}

public class CustomRedirectBehaviorAttribute : ActionFilterAttribute {
    public override void OnActionExecuting(ActionExecutingContext filterContext)
    {
        base.OnActionExecuting(filterContext);

        ...

        if (redirectingCondition) {
          filterContext.Result = new RedirectResult("http://main.domain.com");
        }
    }
}

And here.... I get a cyclic redirection error in the browser! To be certain - I have double-checked this behavior:

  1. When I open http://main.domain.com/user/user47 I'm properly redirected to http://main.domain.com
  2. When I open http://user47.domain.com/ I get a cyclic redirection error.

Then in order to investigate the problem I've modified redirect callback to:

filterContext.Result = new RedirectResult("http://someotherdomain.com/some/other/path");

And.... I can see that:

  1. When I open http://main.domain.com/user/user47 I'm properly redirected to http://someotherdomain.com/some/other/path
  2. When I open http://user47.domain.com/ I'm redirected to http://user47.domain.com/some/other/path !!! (And yes, that's not a typo and I've also double-checked this behavior)

So. I need an idea on how to pass through this problem

Upvotes: 0

Views: 2557

Answers (2)

Andrey Pesoshin
Andrey Pesoshin

Reputation: 1186

Well... Finally I got the answer.

The problem was coming from the Application Request Routing (ARR) module being installed in order to make rewriting work with custom subdomains.

The Reverse rewrite host in response headers option was set to true by default after enabling proxy in the Server Proxy Settings area. Disabling this setting makes redirect working correctly under subdomain-based rewriting.

Upvotes: 1

Simeon Nenov
Simeon Nenov

Reputation: 51

I've tried to reproduce your case and it seems you are really getting a redirecting loop. So I added a negative lookahead group ((?!main)) into the pattern and it works for me. This is how my web.config looks:

<rule name="user-redirection" enabled="true" stopProcessing="true">
    <match url="^.*$" />
    <conditions logicalGrouping="MatchAll" trackAllCaptures="true">
        <add input="{HTTP_HOST}" pattern="^(?!main)([\w\d-]+)\.domain\.com$" />
    </conditions>
    <action type="Rewrite" url="http://main.domain.com/user/{C:1}" logRewrittenUrl="true" />
</rule>

In order to investigate your problem I've tried:

  1. Disable browser cache. If your browser using cache it might you will not see every change of the rule you made.
  2. Change the type of action to be "Redirect" instead of "Rewrite" and watching what's going on in the "Network" tab in the "Developer tools (F12)". e.g. <action type="Redirect" ...

Upvotes: 1

Related Questions