how to evaluate variable expression in spring security hasRole() - java

Seeking help in spring secuity with thyemeleaf. I want to pass specific role as a paramter in spring security hasRole() function.
<li sec:authorize="hasRole(__${someVariable}__)" th:if="${#authentication}">
i just want to pass my role as a variable "somevariable" would have value of like 'admin', 'systemadmin' etc
FYI.. I am using Thymeleaf + Spring

I solved the same basic problem in a way that avoids trying to hack the double-underscore (e.g. __${someVariable}__) syntax.
<th:block th:with="secAuth=${yourNormalModelAccessHere}">
<li class="nav-item" sec:authorize="${#authorization.expression(#vars.secAuth)}">
</th:block>
Hope this helps someone. :)

I can get it solved by using:
${#authorization.expression('hasRole(__${someVariable}__)')}

What do you mean by pass some variable? If you have implemented spring security correctly, hasRole can be evaluated using sec:authorize="hasRole('ROLE_ADMIN') .. etc. Also, you do not need to include th:if since sec:authorize attribute renders its content when the attribute expression is evaluated to true
See reference here

I would ditch sec:authorize and instead write it like this:
<li th:if="${#request.isUserInRole(someVariable)}">
(Assuming somewhat recent version of Servlet API and use of Spring Expression Language in Thymeleaf template.)

Related

Thymeleaf: how to use conditionals to dynamically add/remove a CSS class

By using Thymeleaf as template engine, is it possible to add/remove dynamically a CSS class to/from a simple div with the th:if clause?
Normally, I could use the conditional clause as follows:
Lorem Ipsum
We will be creating a link to the lorem ipsum page, but only if condition clause is true.
I'm looking for something different: I'd like the block to always visible, but with changeable classes according to the situation.
There is also th:classappend.
If isAdmin is true, then this will result in:
Yes, it is possible to change a CSS class dynamically according to the situation, but not with th:if. This is done with the elvis operator.
Lorem Ipsum
For this purpose and if i dont have boolean variable i use the following:
<li th:class="${#strings.contains(content.language,'CZ')} ? active : ''">
Another very similar answer is to use "equals" instead of "contains".
<li th:class="${#strings.equals(pageTitle,'How It Works')} ? active : ''">
If you just want to append a class in case of an error you can use th:errorclass="my-error-class" mentionned in the doc.
<input type="text" th:field="*{datePlanted}" class="small" th:errorclass="fieldError" />
Applied to a form field tag (input, select, textarea…), it will read the name of the field to be examined from any existing name or th:field attributes in the same tag, and then append the specified CSS class to the tag if such field has any associated errors
Just to add my own opinion, in case it might be useful to someone.
This is what I used.
<div th:class="${request.read ? 'mdl-color-text--grey-800 w500' : ''}"> </div>
Yet another usage of th:class, same as #NewbLeech and #Charles have posted, but simplified to maximum if there is no "else" case:
<input th:class="${#fields.hasErrors('password')} ? formFieldHasError" />
Does not include class attribute if #fields.hasErrors('password') is false.
What #Nilsi mentioned is perfectly correct. However, adminclass and user class need to be wrapped in single quotes as this might fail due to Thymeleaf looking for adminClass or userclass variables which should be strings. That said,
it should be: -
<a href="" class="baseclass" th:classappend="${isAdmin} ? 'adminclass' :
'userclass'">
</a>
or just:
<a href="" th:class="${isAdmin} ? 'newclass' :
'baseclass'">
</a>
If you are looking to add or remove class accordingly if the url contains certain params or not .This is what you can do
<a th:href="#{/admin/home}" th:class="${#httpServletRequest.requestURI.contains('home')} ? 'nav-link active' : 'nav-link'" >
If the url contains 'home' then active class will be added and vice versa.
Just in case someone is using Bootstrap, I was able to add more than one class:

Spring MVC does not render html with angularjs directive

the angularjs feature called directive cause to problems in spring mvc. If I use thymeleaf to render a html with elements such
<div ui-view autoscroll="false"></div>
i got a error like
org.xml.sax.SAXParseException: Attribute name "ui-view" associated with an element type "div" must be followed by the ' = ' character.
is there an elegant workaround or should I use something else than thymeleaf?
Edit:
Many thanks for your answers, they helped me a lot.
Either you code xml or you use some workaround. open your application.properties and add following
spring.thymeleaf.prefix=classpath:/templates/
spring.thymeleaf.suffix=.html
spring.thymeleaf.mode=LEGACYHTML5
spring.thymeleaf.encoding=UTF-8
spring.thymeleaf.content-type=text/html
spring.thymeleaf.cache=false
Just put the below code. basically what it is saying is that every attribute in HTML should have a value. When the browser renders it, it will anyway look like below.
<div ui-view="" autoscroll="false"></div>
Update: You can also use directive in a class or as an element.

thymeleaf - combined th:each with th:href

I'm new to Thymeleaf (and webdev) and I'm trying to combine Thymeleaf iteration (th:each) with URL re-writing (th:href).
<a th:each="lid : ${lists}" th:text="${lid}" th:href="#{/list?l=${lid}}">
hello
</a>
This produces the following (where lid=45):
45
So, it did the substitution on the th:text, but not on the th:href.
I'm not trying to do any sort of URL re-writing, I'm just using the '#' syntax because I want Thymeleaf to substitute the 'lid' attribute.
I'm using the current version of Thymeleaf (2.1.2) with Google App Engine.
If you don't want to do any url rewriting, you shouldn't use the # syntax.
You can use the pipeline (|) syntax to do some literal substitions:
th:href="|/list?l=${lid}|"
Source: Thymeleaf documentation
You can also try this way:
<a th:href="#{'/list?l=' + ${lid}}" th:text="${lid}">element</a>
I don't have enough reputation to add a comment on a previous post but the Thymeleaf Source documentation link from a previous post is broken. Documentation can now be found at the following link:
Thymeleaf Standard URL Syntax
Section 9 Using Expressions in URLs in this documentation explains how you can use expressions within other expressions when generating URLs with the # syntax. The following is an example:
<a th:href="#{/order/details(id=${modelattribute})}"/>
Will produce a link similar to:
http://domain.org/context/order/details?id=1
if modelattribute had a value of 1 in the current context.

ESAPI implementation for spring form tags

How can we implement ESAPI output encoding in an application using java and spring-mvc.
Read many posts and saw this:
<%# page import="org.owasp.esapi.*" %>
<input type="hidden" name="hidden" value="<%out.print(ESAPI.encoder().encodeForHTML(content));%>"/>
But, in my application all the jsps use spring form tags like the following,
<td>Number:
<form:input path="someNo" size="20" maxlength="18" id="firstfield" onkeypress="return PressAButton('submithidden');"/></td>
How can I have ESAPI implementation for above code? is there any other way of implementing output encoding like creating a filter or something? Any suggestions are greatly appreciated!
After researching spring tags a bit, it appears that the data-binding happens in framework code thus preventing you from applying any escaping in the jsp.
One, semi-quick win could be defaulting all output to escape HTML. Add this entry in web.xml:
<context-param>
<param-name>defaultHtmlEscape</param-name>
<param-value>true</param-value>
</context-param>
The only problem here is that output-escaping is a BIG pain... the rules for html escaping are different when your value is going to be passed as data to an HTML attribute or a Javascript function. And there could be some parts of your application where you DO NOT want to html escape, but you should be able to override those with the form tag attribute htmlEscape="false" when you need to.
What you need is to be able to hook the part of Spring tags where it is binding the HTML to the form, but you need to be able to do it so you can escape based on where its being placed. Escaping rules are different for an HTMLAttribute as opposed to plain HTML and if the value is going to be passed as data to a javascript function. So Spring's solution only defends one category of attack.
These are the only ways out I see, all of them will require work:
Use JSTL tags instead of Spring tags so you can write your variables with ${thisSyntax} and wrap them in esapi tags like this:
<c:out value="<esapi:encodeForHTML>${variable}</esapi:encodeForHTML>"/>
Follow a solution like what #A. Paul put forward, where you do your context escaping back on the controller side. I'm aware you feel that this isn't an option, but the next solution I'm putting forward is untested.
Implement your own tag library that subclasses [org.springframework.web.servlet.tags.form.InputTag][1], specifically the method writeValue. While esapi prevents alot, I would recommend looking at owasp's new Encoder project to show you exactly how tricky output encoding is. Ideally your tag library will allow you to utilize either esapi's Encoder or this new API.
Just a thought not sure if this is what you are looking for.
Can you use the below code in Java and change the data in the bean itself and then send in the user interface.
if ( ESAPI.securityConfiguration().getLogEncodingRequired() ) {
data = ESAPI.encoder().encodeForHTML(message);
}
You can check the below url.
http://www.jtmelton.com/tag/esapi/

How to pass dynamic parameter value in a link using Struts taglib?

I'm trying to use Struts framework in my project. I want to use the html:button to send parameter in the link but I don't understand how to make it.
In other words, I want to translate this line:
<input type="button" onClick="window.location.href='resum.do?action=ViewMessage&&id_message=<%= id_msg %>'" value="View"/>
to Struts taglib, something like this:
<html:button property="" onclick="window.location.href='resum.do?action=ViewMessage&&id_message=<%= id_msg %>'" value="View"></html:button>
But it didn't work.
The html:button tag is used only inside the form tag. See the docs
This tag is only valid when nested inside a form tag body.
Also set the property attribute.

Categories

Resources