curiouswebster
asked on
Redirecting after removing one or more query string params.
Need to Redirect after removing one or more query string params.
I am using a whitelist to remove dangerous query string params, and when done, need to redirect to whatever is left in the query string.
I understand things may break, but am okay letting our website's existing default behavior handle it.
What is the exact command to redirect?
ActionExecutingContext filterContext is the input param of the ActionFilterAttribute
public override void OnActionExecuting(ActionEx ecutingCon text filterContext)
and after removing the faulty query string params from:
filterContext.HttpContext. Request.Qu eryString
I am ready to redirect.
filterContext.HttpContext. Response.R edirect(fi lterContex t.HttpCont ext.Reques t.);
Please complete the the above parameter for Redirect()
Thanks
I am using a whitelist to remove dangerous query string params, and when done, need to redirect to whatever is left in the query string.
I understand things may break, but am okay letting our website's existing default behavior handle it.
What is the exact command to redirect?
ActionExecutingContext filterContext is the input param of the ActionFilterAttribute
public override void OnActionExecuting(ActionEx
and after removing the faulty query string params from:
filterContext.HttpContext.
I am ready to redirect.
filterContext.HttpContext.
Please complete the the above parameter for Redirect()
Thanks
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
filterContext.HttpContext. Current.Re quest.Url or
filterContext.HttpContext. Current.Re quest.RawU rl
depending on what you need.
filterContext.HttpContext.
depending on what you need.
ASKER
I need a string.
But there is no "Current" option available.
and both of these fail:
filterContext.HttpContext. Request.Ur l
filterContext.HttpContext. Request.Ur l.ToString ()
But there is no "Current" option available.
and both of these fail:
filterContext.HttpContext.
filterContext.HttpContext.
What do you mean fail?
Are they not available? Are they null?
What about RawURL?
Are they not available? Are they null?
What about RawURL?
ASKER
Sorry, I saw the squiggly underlining and thought it was an error. It was a warning about a null value.
It runs, but seems to be on an infinite loop, hitting breakpoints inside my Action filter forever.
Should I call the following at the end of the Action Filter?
base.OnActionExecuting(fil terContext );
It runs, but seems to be on an infinite loop, hitting breakpoints inside my Action filter forever.
Should I call the following at the end of the Action Filter?
base.OnActionExecuting(fil
Do you check if you need to redirect? That could be the result of your loop.
ASKER
I only do the redirect after I have removed a failed query param. Otherwise, not.
Is that what you're asking?
Is that what you're asking?
if (badQueryStringKeys.Count > 0)
{
filterContext.HttpContext.Response.Redirect(filterContext.HttpContext.Request.Url.ToString());
}
That's what I was asking. Not sure why you would get an infinite loop then -> can you post your code?
ASKER
It stopped looping infinitely.
When I removed the following...
but loops two times, and crashed out with an error about appending the cookie, when I use this:
Here is the entire object:
When I removed the following...
filterContext.Result = new RedirectResult(filterContext.HttpContext.Request.Url.ToString());
but loops two times, and crashed out with an error about appending the cookie, when I use this:
filterContext.HttpContext.Response.Redirect(filterContext.HttpContext.Request.Url.ToString());
Here is the entire object:
public class UrlRedirectValidationAttribute : ActionFilterAttribute
{
private List<string> WhiteListValues => new List<string>()
{
"mydomain.org"
};
public override void OnActionExecuting(ActionExecutingContext filterContext)
{
List<string> badQueryStringKeys = new List<string>();
foreach (var key in filterContext.HttpContext.Request.QueryString.AllKeys)
{
var value = filterContext.HttpContext.Request.QueryString[key];
if (value.IsAbsoluteUrl())
{
try
{
var url = new Uri(value);
if (!url.IsUrlDomainValid(WhiteListValues))
{
badQueryStringKeys.Add(key);
}
}
catch (ArgumentException ex)
{
filterContext.Result = GetRedirectResult(filterContext, "Home", "Index");
}
}
}
foreach (string badQueryStringKey in badQueryStringKeys)
{
RemoveParameter(filterContext.HttpContext.Request.QueryString, badQueryStringKey);
}
if (badQueryStringKeys.Count > 0)
{
//filterContext.HttpContext.Response.Redirect(filterContext.HttpContext.Request.RawUrl.Split(new[] { '?' })[0]);
//filterContext.Result = new RedirectResult(filterContext.HttpContext.Request.Url.ToString()); LOOPS
filterContext.HttpContext.Response.Redirect(filterContext.HttpContext.Request.Url.ToString());
}
base.OnActionExecuting(filterContext);
}
private void RemoveParameter(NameValueCollection nameCollection, string keyToRemove)
{
// reflect to readonly property
PropertyInfo isreadonly = typeof(System.Collections.Specialized.NameValueCollection).GetProperty("IsReadOnly", BindingFlags.Instance | BindingFlags.NonPublic);
if (isreadonly != null)
{
// make collection editable
isreadonly.SetValue(nameCollection, false, null);
// remove
nameCollection.Remove(keyToRemove);
// make collection readonly again
isreadonly.SetValue(nameCollection, true, null);
}
}
private ActionResult GetRedirectResult(ActionExecutingContext context, string controller, string action, string clientId = null,
List<KeyValuePair<string, object>> additionalParameters = null)
{
var returnUrl = context.HttpContext.Request.RawUrl;
var requestAccept = context.HttpContext.Request.Headers["Accept"];
var dictionary = new RouteValueDictionary
{
{"controller", controller},
{"action", action},
{"ReturnUrl", returnUrl}
};
if (!string.IsNullOrEmpty(clientId))
dictionary.Add("ClientID", clientId);
if (additionalParameters != null)
{
additionalParameters.ForEach(param => dictionary.Add(param.Key, param.Value));
}
return new RedirectToRouteResult(dictionary);
}
}
}
ASKER
Hold the phone!
The following seems to be working...
filterContext.HttpContext. RewritePat h(filterCo ntext.Http Context.Re quest.Path );
The following seems to be working...
filterContext.HttpContext.
ASKER
Perhaps you can comment on whether I even need that function called GetRedirectResult().
I added this so I could at least route to /Home/Index/ in the event there is some unexplained exception.
Does this make sense?
I added this so I could at least route to /Home/Index/ in the event there is some unexplained exception.
Does this make sense?
Going back to your looping - in your code you need to pass in the sanitized url.
If it's working for you and you don't care then no sense going down the rabbit hole.
As far as GetRedirectResult I would rename it to GetHomeRedirect() to make it more clear.
And yes it does make sense that in an error you would want the page to go somewhere. Though I would add some logging or send an email to yourself.
EG: Hey, we got an error, here's the full URL so you can reproduce and see what's going on.
In theory you shouldn't need it, but theories only survive until you encounter the real world.
if (badQueryStringKeys.Count > 0)
{
//filterContext.HttpContext.Response.Redirect(filterContext.HttpContext.Request.RawUrl.Split(new[] { '?' })[0]);
// I believe this loops because you're passing in the same query string. You have to redirect to the new, santizied url.
filterContext.Result = new RedirectResult(filterContext.HttpContext.Request.Url.ToString());
return;
}
Rewrite path is used to serve one page as another if that makes sense. More info on it here: https://msdn.microsoft.com/en-us/library/sa5wkk6d(v=vs.110).aspx If it's working for you and you don't care then no sense going down the rabbit hole.
As far as GetRedirectResult I would rename it to GetHomeRedirect() to make it more clear.
And yes it does make sense that in an error you would want the page to go somewhere. Though I would add some logging or send an email to yourself.
EG: Hey, we got an error, here's the full URL so you can reproduce and see what's going on.
In theory you shouldn't need it, but theories only survive until you encounter the real world.
ASKER
Can I avoid that function entirely and the /Home/Index/ redirect simply by using the following line in the Catch?
filterContext.HttpContext. Response.R edirect(fi lterContex t.HttpCont ext.Reques t.RawUrl.S plit(new[] { '?' })[0]);
filterContext.HttpContext.
filterContext.HttpContext. Response.R edirect(fi lterContex t.HttpCont ext.Reques t.RawUrl.S plit(new[] { '?' })[0]);
That will redirect to the same page without the query string.
eg:
/somepath/page?goto=XXXX
filterContext.HttpContext. Request.Ra wUrl.Split (new[] { '?' })[0] = /somepath/page
The home function will go to the actual home path.
That will redirect to the same page without the query string.
eg:
/somepath/page?goto=XXXX
filterContext.HttpContext.
The home function will go to the actual home path.
ASKER
> That will redirect to the same page without the query string.
Isn't that the safest thing to do?
Isn't that the safest thing to do?
Just depends on your logic. I don't have enough application context to answer that.
ASKER
So long as there is no exposure to a hack by using this exceptional redirect, I am okay with it. Is it safe to do?
There shouldn't be any exposure to a hack. Only exposure would be if you allowed access based on an empty query string or if something else weird was happening.
Basically if your page handles the empty query string and you're okay with that in all context / cases (EG: user logged in / not logged in / errors, etc.) then you're fine to redirect to the same path with the empty query string.
Basically if your page handles the empty query string and you're okay with that in all context / cases (EG: user logged in / not logged in / errors, etc.) then you're fine to redirect to the same path with the empty query string.
ASKER
> if your page handles the empty query string
I have been told to let the cookies fall where they may on that. We want safety first.
I have been told to let the cookies fall where they may on that. We want safety first.
ASKER
Here is my follow-on question...
https://www.experts-exchange.com/questions/29089040/Why-can-I-not-update-the-URL-in-the-browser.html#questionAdd
https://www.experts-exchange.com/questions/29089040/Why-can-I-not-update-the-URL-in-the-browser.html#questionAdd
ASKER
I have remove faulty params of
var value = filterContext.HttpContext.
using the following code
Open in new window
with the NameValueCollection param coming from
filterContext.HttpContext.