If I have a simple GSP (using Grails 2.3.6):
<% page import=org.me.Widget %>
<header>
<!-- Header stuff -->
</header>
<body>
The requested URL is ${url}!
</body>
How do I inspect the HTTP request URL (the current URL the server is responding to) and inject it into the ${url} variable?
Note: I need to do this inside of GSP and not from inside a controller, if at all humanly possible, even if it is a violation of best practices.
you could try
def var = request.forwardURI
forwardURI - Useful for obtaining the current request URI since the request object’s requestURI property returns the original URI, not the matched one.
You can even check for additional methods added to the request object here
You have quite a few options in a GSP to find out the current URL.
First, you can always access the request object which is an HttpServletRequest. Using methods such as getRequestURL() or getRequestURI(), you can inspect the request.
${request.getRequestURL()}
However, actionName and controllerName may be more useful. Both of these properties are exposed to the GSP within the model. With these you can construct the URL current using the standard createLink tag if needed.
${createLink(controller: controllerName, action: actionName)}
These should give you enough options to accomplish what you need.
Related
I am developing an Angular2 and integrating it with my ASP.NET MVC application.
To prevent CSRF attacks we have used Anti-Forgery Tokens in ASP.NET MVC helper function, which renders an input type inside the body.
Now I want to read this value and append it to the headers of all my ajax calls in my angular2 app.
I was not able to find a way how to read this value and pass to http wrapper service.
This is how the DOM looks:
<html>
<head></head>
<body>
<input name="__RequestVerificationToken" type="hidden" value="6fGBtLZmVBZ59oUad1Fr33BuPxANKY9q3Srr5y[...]" />
<my-app>
</my-app>
</body>
</html>
Thanks.
You can access it with jQuery selector:
<html>
<head></head>
<body>
<input name="__RequestVerificationToken" id="input_element" type="hidden" value="6fGBtLZmVBZ59oUad1Fr33BuPxANKY9q3Srr5y[...]" />
<my-app>
</my-app>
</body>
</html>
Component
checkValue(): string {
return $('#input_element').value();
}
This is not the most elegant way to do what you need, but it is the only one, since angular doesnt allow access to anything outside scope.
I actually used this to change css link in my tag located in tag.
But
Also consider the comments, that there is a better way to implement token based communication. You can actually save your token in localStorage after authentication procedure, or any other REST call. Take data from result of that REST call and localStorage.setItem('token', value).
You can create HttpInterceptor, custom one, where you can modify every REST call to have that token. Example of that:
https://medium.com/aviabird/http-interceptor-angular2-way-e57dc2842462
Thanks for your suggestions everyone.
So here is what I did after researching and from all of the above suggestion.
I created a window-ref service that returns me the window object and also has the getToken() method.
Then I inject this service in my http wrapper service.
The window ref service has the getToken() method that will check if the document object is present and if it finds the element with the provided name "__RequestVerificationToken" it will returns its value.
If the element is not present then blank value or null is returned.
While in the HttpWrapper service I check if the returned value from getToken() is blank then don't append the "__RequestVerificationToken" header else append it.
I followed this https://juristr.com/blog/2016/09/ng2-get-window-ref/ link for the window ref service.
I did'nt wanted to make another call to get the token from the server, because this call would obviously wont have any security token attached to its request headers and this would have made this call unsafe. An attacker could have easily called this method and got the token and successively attached it to next calls.
When I use url helper to generate url for route with query params and then add that url to link href, validator warns me, that there is unescaped & in attribute:
▲
I tried to search but still I'm not sure who is responsible for escaping that.
Router generates url but that might be used anywhere, not only in html attribute, so it correctly does no escaping in his case.
Url helper does not change anything in that url but it is meand for use in html so it might done here
View template - there url is put inside href attribute, so it might be here too
I couldn't find any clue how to decide this and if fill an issue with zf2 about this.
EDIT: html/php code from paginator
<<
generates html
<<
and from what I found it should be
<<
I would argue that the current behavior (not HTML entity encoding) is correct and it is up to the developer to encode HTML entities, when appropriate.
For instance you may want to use the view helper inside a <script> tag, where the HTML entities would be uncalled for.
According to Marc Palmer
Preventing XSS attacks
In a nutshell, to protect your app from code injection XSS exploits
you must:
Set the default grails.views.default.codec in config to "HTML"
OK.
So if I have this below in my Config.groovy
grails.views.default.codec = "none"
And in my Controller, I add:
def afterInterceptor = { model ->
model.headerJs = "alert('bingo for '+[$params.unitId]);"
}
And in my GSP:
<r:script disposition="head">${headerJs}</r:script>
It works. I see the expected javascript alert when I do View Source and I get my alert when the page serves.
But, if in Config.groovy I apply the recommended change:
grails.views.default.codec = "html"
My GSP renders
<script type="text/javascript">alert('halooba for '+[1]);</script>
which I can see is very secure.
My goal with this app is to have custom JS snippets, various properties and other values stored for the customer in the Domain. These values would be entered by our Admins (not the customer). Based on who invokes the page with an HTTP request, such as www.mydomain.com/ThisApp/?customerId=13423 (but an encoded customerId) I'd make calls to Services from my Controller to fetch the associated settings for the customer from the Domain and inject them into the GSP.
I know that I can put JS and CSS into files and then use the Resources Plugin to bring them in properly, but I'm also looking at this method for specific customizations.
So, to follow this security method, I either need to be able to unencode this, or I need to determine another method for including javascript into the GSP that does not encode it.
Any suggestions?
THANKS!
You can suggest Grails not to escape by using raw() available in GSP as:
<r:script disposition="head">${raw(headerJs)}</r:script>
For Grails 2.2.x and below, you can put the recommended encoding in your Config.groovy:
grails.views.default.codec = "html"
and use a Taglib to bring in values that are SAFE and should not be HTML encoded:
<r:script><com_myapp:getJSDeferred unitId="${params.unitId}" /></r:script>
and it will be rendered raw.
FYI: Above solution will not allow for JSON output to assign to javascript variable.
My workaround, say you have model.data defined as hashmap:
var someVar= ${raw(data as JSON).toString())};
In my application, a login controller should return redirect URL if client is authorized:
<path to grails app> + <another controller, method, params>
How can I get application URL?
You should be able to build a URL using the grails tags as method calls. createLink is likely what you want. This has action, controller, params and absolute as options to get a full URL to a controller action (you may need to configure the base url as noted in the docs). In an example in the first link, something like this would get the absolute URL to that resource:
g.createLink(action:"myact", controller:"somecontroller", params:[foo:'bar', boo:'far'], absolute:true)
For generic approach you can inject LinkGenerator and then call
linkGenerator.link(controller: "foo", action: "bar", absolute: true)
For some reason, tag use completely different logic.
I have a site that have URL similar to this:
/mysite/admin/controller/action/id
/mysite/search/controller/action/id
/mysite/user/controller/action/id
I have my URL mapping like this
"/$prefix/$controller/$action?/$id?"{
constraints {}
}
I am able to get to the controller correctly.
But on the GSP side
<g:link controller="controller">abc</g:link> ==> abc
Notice how I lose the prefix between mysite and the controller.
You can use named url mappings and then pass the prefix as part of the params:
URLMappings:
name prefix: "/$prefix/$controller/$action?/$id?"{
constraints {}
}
GSP:
<g:link mapping="prefix" params="[prefix:$prefix, controller:...]">abc</g:link>
To use sortableColumn, just put all of the URLMapping parameters in the params property:
<g:sortableColumn property="col" title="title" params="[ prefix: 'prefix', controller:'controller', action:'action']" />
It works when you hit the URL in browser, because prefix is available in URL. It does not work when you use link tag to create url, because grails does not have information about which prefix should be used for this controller. You will need to provide the value for prefix to link tag.
Try this
<g:link controller="controller" params="[prefix:'admin']">abc</g:link>
in-short - You have to pass those dynamic variables as params if you want link re-writing to consider them. Read more docs here