I am implementing Role based spring security
In this example they have used thymeleaf for frontend purpose, but I am using angular9 with html.
they are using sec:authorize="hasRole('ROLE_ADMIN')" to provide access to the admin,in the same way if I want to provide the same thing in html, for that I have used the following code,
<li *ngFor="let user of users">
{{user.username}} ({{user.firstName}} {{user.lastName}})
- <a sec:authorize="hasRole('ROLE_ADMIN')" (click)="deleteUser(user.userid)" class="text-danger">Delete</a>
</li>
The person logged in is Role_user, eventhough the delete link is visible to the user.
How can I restrict.
Thanks in advance.
use *ngIf directive to show and hide the anchor tag
<li *ngFor="let user of users">
{{user.username}} ({{user.firstName}} {{user.lastName}})
- <a *ngIf="hasRole('ROLE_ADMIN')" (click)="deleteUser(user.userid)" class="text-danger">Delete</a>
</li>
but the hasRole() must return boolean. because *ngIf accepts the boolean
Related
so here's my problem.
I'm trying to have dynamic data in my header. It's supposed to represent the number of items a user has in his cart.
So here's my header (the header is a fragment that I included in the layout.html) and the data is in the last li
<nav >
<ul>
<li><a th:href="#{/index}" class="">Home</a></li>
<li><a th:href="#{/products/list}" class="">Products</a></li>
<li><a th:href="#{/admin/index}" class="">Admin</a></li>
<li>Account</li>
<li>Contacts</li>
<li><a th:href="#{/login}" class="">Login</a></li>
<li><a th:href="#{/user-page}" class="">User</a></li>
<li>
<p th:text="${cart.id}"></p>
</li>
</ul>
</nav>
But since the header is available on every page of the web app, what should I do (in the controllers) to get this data?
I tried to put the cart data in the IndexController but it doesn't work. I'm not comfortable with Spring and Thymeleaf so I might be doing something wrong or maybe I missed something on data binding. I only have once constraint, I don't want to use Ajax or Jquery. Unless I have no choice but I doubt that. Here's what I tried in the IndexController
#GetMapping({"/", "/index", "/home"})
public String getIndex(Model model) {
this.userCart.setId(5);
this.userCart.setNumberItems(11);
model.addAttribute("cart", userCart);
model.addAttribute("phrase", "Oui oui si si 92izi");
model.addAttribute("nbItems", "10");
return "index";
}
I also tried to make another method mapped to "/" but it causes an error since I can't have to methods mapped to the same url. So what am I supposed to do ?
If you need a model attribute application wide, then you can use an #ControllerAdvice annotated class:
#ControllerAdvice
public class GlobalControllerAdvice {
#ModelAttribute("numberOfItemsInCart")
public int getNumberOfItemsInCart() {
// get the cart and return the number of items
}
}
And use this attribute in your template:
<p th:text="${numberOfItemsInCart}"></p>
The method that is annotated with #ModelAttribute can also declare HttpServletRequest request as a parameter if needed (See https://docs.spring.io/spring-framework/docs/current/reference/html/web.html#mvc-ann-arguments for all possible arguments for the method).
See https://docs.spring.io/spring-framework/docs/current/reference/html/web.html#mvc-ann-controller-advice for more details about #ControllerAdvice.
I have a thymeleaf fragment called nav which I include in all front-end pages, it goes like so:
<nav class="navbar navbar-expand-md navbar-dark bg-dark" th:fragment="nav">
<div class="collapse navbar-collapse" id="navbarsExampleDefault">
<ul class="navbar-nav mr-auto">
<li class="nav-item active">
<a class="nav-link" href="#">Home <span class="sr-only">(current)</span></a>
</li>
How to get Java data here ?
</ul>
</div>
</nav>
But what I want to do now is get some data from the database and have that data available in this fragment, which in turn will appear on every page that includes this fragment.
If I want to pass data to a view regularly from a controller, I would use Model and model.addAttribute and return the appropriate view which would contain the relevant model data, but how can I pass data to this fragment?
You can create an interceptor and add model attribute on the postHandle method (which allows you access to the ModelAndView object. The interceptor will have to be on all the controllers that have this fragment.
You can add the relevant model attributes to the session and access them via ${session.attribute}.
Use the #ControllerAdvice annotation in combination with #ModelAttribute to add a model attribute to all controllers.
here is my problem. How could I hide the value of the parameter from the url? because I don't have idea how to hide it. it keep on appearing like this (http://localhost:8084/YIP/MentorServlet?action=peribadi&mentorid=951218-02-5598)
<div id="mySidenav" class="sidenav">
<a href="javascript:void(0)" class="closebtn" onclick="closeNav()">×
</a>
<% String id=request.getParameter("mentorid");%>
<li>
Utama
</li>
<li>
Peribadi
</li>
Some options:
do nothing: this is the best one, as there is no such thing as securely hiding something in HTML. Whoever looks into the page source, will see how the servlet in question can be invoked
switch to a form and a submit button, something what #alayor shows. If you use POST, the parameters will not appear in the URL
switch to a form, but keep the looks of an anchor and submit form from JavaScript (some docs some overcomplicated examples)
manipulate browser history from the target page (docs1, docs2)
keep mentorid in a session variable on server-side: hackers never see it
keep mentorid in an encrypted cookie: hackers see it, but can not decode. However they can try reusing it later (replay attack)
the various other ones I have forgotten and/or never even heard about
You can create an HTML for instead of an anchor.
<div id="mySidenav" class="sidenav">
<a href="javascript:void(0)" class="closebtn" onclick="closeNav()">×
</a>
<% String id=request.getParameter("mentorid");%>
<li>
Utama
</li>
<li>
<form action="/MentorServlet" method="POST">
<input type="hidden" name="action" value="peribadi" />
<input type="hidden" name="mentorid" value="<%=id%>" />
<button>Peribadi</button>
</form>
</li>
This way you can avoid sending the parameter in the URL and it will send in the HTTP Request Body instead.
I'm trying to learn Spring MVC & Thymeleaf. I've got the following HTML portion that prints out a link & a button:
<ul th:each="item : ${typesMap}">
<li>
Linky
<button type="button" th:text="${item.value}">Button Text</button>
</li>
</ul>
In the two examples, the parameters in the link are never replaced. I always end up with something along the lines of roomdetails/${item.key}/${item.value} in the HTML. The button works fine though & will show with the text that is found in ${item.value} for each iteration of the loop.
Does anyone know why I can't get URLs in the format I want? From what I can see, I'm doing what the documentation is telling me to.
This should work:
<a href="roomdetails.html" th:href="#{'/roomdetails/' + ${item.key} + '/' + ${item.value}}">
Answer:
<a href="roomdetails.html" th:href="#{'/roomdetails/{paramsKey}/{paramsValue}'(paramsKey=${item.key}, paramsValue=${item.value})}">
I hope that this might solve your issue.
I've set a session that controls the menu based on the role of every user... Now for example I have this
<c:set var="role" scope="session" value='<%=((Long) session.getAttribute("role")).longValue()%>' />
<c:if test="${role == 121}">
<div id="menu">
<span class="menu-header">Registration</span>
<ul>
<li>Organization Registry</li>
</ul>
</div>
</c:if>
<div id="menu">
<span class="menu-header">Directory</span>
<ul>
<li>Organization</li>
</ul>
</div>
Now what if I want to go to that page without logging in? I tried to go to that page without logging in but NullPointetExcepetion was encountered basically because I don't have any session stored in the role. I set every session when the user logs in. When not logging in I want to view menu that does not need any role... For example I redirect to that page with one link that can be viewed by other.
How can I still view the directory menu when I'm not logged in?
Get rid of the <c:set> line altogether. You don't need it. EL ${} already searches for attribtues in page, request, session and application scope. The NPE is caused because you invoked longValue() on null.
Remember: you should never mix oldschool scriptlets <% %> with modern EL ${}. That makes no sense. You'll only confuse yourself.
See also:
Our EL wiki page