Best practice for redirecting from one web domain to another in Grails? - grails

I am currently working on a filter in Grails that will allow me to redirect all incoming requests on foo.org to the same subpage on foo.com.
So far I have been doing the following:
if(!(""+request.requestURL).toLowerCase().startsWith(
grailsApplication.config.grails.serverURL ))
{redirect(url:"${grailsApplication.config.grails.serverURL}${request.requestURI}",params:params) }
Unfortunately, I am experiencing several issues in this approach:
The request.requestURI value seems to behave differently than expected: instead of giving me the normal "/[controller]/[action]" pattern as I would expect, it returns something like: "/grails/[controller]/[action].dispatch". - Is there an alternative way to obtain the "normal" URI? (excuse me if this is trivial, but have not been able to find it in the documentation, nor by trying out the various methods available on the request object)
Params are not being passed in the above redirect. This is probably due to the fact that I am using the "url" parameter in the redirect which according to the docs is supposed to be used for redirects to absolute paths (which again causes it to ignore the params section?). However, since I will not be able to use the normal redirect(controller:...,action:...) approach when redirecting to another domain what approach could I use in order to pass the params correctly along to the subpage on foo.com ? Am considering a solution where I will add the params manually via a params.each{} closure, but isn't there a more elegant solution to this?
301 redirects. Since my redirects are of a permanent nature, I would like to use the 301 status code. I have tried to set "response.status = 301" but it seems to be ignored when using the Grails redirect(...) method. Further I can see from grails.org that this seems to be introduced with grails 2.0, but is there a way to obtain this already now in Grails 1.3.7?

Use request.forwardURI.
If you have meant GET params, then it should be resolved using the above URI?
I think 301 redirects are not possible using classic redirect. You can do this in a filter like this, which is obviously not the cleanest way:
def filters = {
all(controller:'*', action:'*') {
before = {
if (request.serverName == "foo.org") {
response.setStatus(301);
response.setHeader("Location", "http://foo.com" + request.forwardURI)
response.flushBuffer()
return false; // return false, otherwise request is handled from controller
}
}
}
}

Related

Redirecting a Website request with multiple embedded URL strings

I need to redirect the following example to a new website URL.
https://test.test.com/MDR/LauncherInterface.aspx?host=https://test.test.com/MDR&numid=11111&numid=1111&username=1111&userpass=1111
I need to redirect both URL statements to https://test2.test.com. Using iRules in my F5 load balancer I am able to redirect the first statement but I am unable to figure out how to redirect the second as well.
something like this should help:
when HTTP_REQUEST {
if { [HTTP::host] eq "test.test.com" } {
HTTP::redirect https://test2.test.com[HTTP::uri]
}
}
You can also do this with a local traffic policy, and if the rule is really this simple, that would be the preferred approach as it would be more performant. See this article on DevCentral for details on choosing iRules versus local traffic policy.
Finally, known that using the HTTP::redirect command, you'll be restricted to a 302. Use HTTP::respond to change the redirect code.

Grails filters: can uri and uriExclude be used in the same filter?

I've defined a filter in grails like so:
securityFilter(uri: '/api/**', uriExclude: '/api/**/*skipthis*') {
before {
...
println request.url
}
}
I was expecting it to handle any requests like /api/mything but ignore requests like /blahblah/mything/ and /api/mything/andskipthisthing requests yet my log reveals it's dutifully looking at /blahblah/mything
I understand that excludes take precedence, but I would have thought that would mean it would still only look at anything under /api/. I haven't seen any examples of excludeUri in my searches, and all the uri examples I see only use the uri and nothing else. Are we allowed to use excludeUri and uri together? Is this a bug in grails?
Doh! I was looking at request.requestURL, which is the grails dispatcher url (ends with .dispatch) ... What I wanted was the request.forwardURI

Generic URLMapping in Grails for all 4xx or 5xx Errors

I am using Grails 2.4.4 and would like to define a generic UrlMapping for a range of HTTP-error-codes (like 450-499, 510-540).
I've found some related questions - even on SO - but the answers are either outdated or not working.
The container does not start once I use regular expressions on error-mappings.
For instance, this simple example will fail:
"$errorCode" {
controller = "error"
action = "general"
constraints {
errorCode(matches:/\d{3}/)
}
}
Does anyone know how I may approach this?
I tried doing same using Filters but we cannot redirect again after checking status code in httpResponse hence that also doesn't help.
As per grails-doc "Mapping to Response Codes"
http://grails.github.io/grails-doc/3.1.x/guide/single.html#urlmappings
we can only hard code them and redirect it to mentioned controller and action.
So you need to mention all http codes and handle all of them separately.
Thanks.

Determine the url (or controller and action names) of a request which is unauthorized with Shiro Grails plugin

I would like to be able to log the requests that my app receives that are unauthorized. Because the Shiro plugin uses an HTTP redirect to send the user to auth/unauthorized the request object is a fresh one and I can't get the original URL; controller/action name; or request parameters from it.
Is there a way to determine either the original url, or the controller and action names (and request params if possible) inside the AuthController unauthorized action?
I am looking at http://plugins.grails.org/grails-shiro/tags/RELEASE_1_1_3/ShiroGrailsPlugin.groovy as a reference of the plugin source.
Details:
Grails 1.3.7
Shiro Grails plugin 1.1.3
I had the same problem... my solution is not perfect:
a browser sends the so called referer in one of the headers which you can get through
request?.getHeader('Referer')
But the referer is nothing you really can rely on -- but most of the browsers send it.
Another solution could be the filter: try to write the current url to another variable before you call accessControl() in ShiroSecurityFilters.groovy. You can get the current URL through request.forwardURI.
Update: just verified my last assumption - this seems the cleanest solution to me:
In ShiroSecurityFilters.groovy, replace
// Access control by convention.
accessControl()
with
// Access control by convention.
if (!accessControl()) {
session.deniedUrl = request.forwardURI
return false
}
which enables you to access the url as session.deniedUrl in your auth/unauthorized controller.

Handling question mark in url in codeigniter

I am using a payment method which on success returns a url like mysite/payment/sucess?auth=SDX53641sSDFSDF, but since i am using codeigniter, question marks in url are not working for me.
I tried routing but it didnt work. As a final resort i created a pre system hook and unset the GET part from the url for with i had to set
$config["uri_protocol"] = "REQUEST_URI";
It worked that way but all other links in my site were not working as intended, tried changing the uri_protocol but could not make it work by any means.
So basically my problem is handling the ?auth=SDFSEFSDFXsdf5345sdf part in my url, whenever the paypment method redirects to my site with the url mentioned above, it gets redirected to homepage instead of the function inside controller.
How can i handle this, i'm using codeIgniter 1.7 version, and couldnt find any way.
Please suggest some solution.
I think I would extend the core URI class, by creating new file at application/libraries/MY_URI.php which will extend the CI_URI class, then copy the _fetch_uri_string method and here you can add your logic if the $_SERVER['QUERY_STRING'] is present:
class MY_URI extends CI_URI
{
function __construct()
{
parent::CI_URI();
}
//Whatever this method returns the router class is using to map controller and action accordingly.
function _fetch_uri_string()
{
if(isset($_SERVER['QUERY_STRING']) AND !empty($_GET['auth']))
{
//Do your logic here, For example you can do something like if you are using REQUEST_URI
$this->uri_string = 'payment/success/'.$_GET['auth'];
return;
//You will set the uri_string to controller/action/param the CI way and process further
}
//Here goes the rest of the method that you copied
}
}
Also please NOTE that you must do security check of your URL and I hope this works for you, otherwise you can try extending the CI_Router class or other methods (experiment little bit with few methods, though the _set_routing is important). These 2 classes are responsible for the intercepted urls and mapping them to controller/action/params in CI.
I believe this thread holds the answer.
Basically add
$config['enable_query_strings'] = TRUE;
to your config.php
hope this will help you ! no need to change htaccess,just change your code.
redirect(base_url()."controller_name/function_name");
Looking at the example code in the Stripe docs:
https://stripe.com/docs/payments/checkout/set-up-a-subscription
one might conclude that you can only retrieve a checkout_session_id as a named GET parameter like this:
'success_url' => 'https://example.com/success?session_id={CHECKOUT_SESSION_ID}',
After playing around with .htaccess and config settings (as in previous answers) and finally getting it to work, it suddenly dawned on me that the DEVELOPER is in control of the success_url format, not Stripe. So one can avoid all the problems with a GET parameter by specifying the success url in the normal, clean Codeigniter format, like this:
'success_url' => 'https://example.com/success/{CHECKOUT_SESSION_ID}',
In my routes file, the incoming CHECKOUT_SESSION_ID string is passed to the Subscription controller's checkout_success method with this route:
$route['success/(:any)'] = 'subscription/checkout_success/$1';
The method accepts the $checkout_session_id like this:
function checkout_success($checkout_session_id)
{
// Do something with the $checkout_session_id...
}
I'm new to Stripe Checkout but this seems to simplify the integration without breaking Codeigniter's GET processing rules.

Resources