Show fields in jsp based on user roles(without using spring security) - java

I have a tabs.jsp which has links to other pages. When an admin logs in he must be given 2 extra links to add users and roles. while authenticating im able to validate if user is admin or not. on validation im returning control to a user display page if user exists if not redirecting back to login page. how do i achieve this extra 2 links if user is admin?
My controller
#RequestMapping(value = "auth", method = RequestMethod.POST)
public ModelAndView printStringLogin(
#ModelAttribute("USERS") Users userAuthentication,
HttpSession httpSession, ModelMap model) {
System.out.println(userAuthentication.getUsers_email());
System.out.println(userAuthentication.getUsers_password());
UserAuthentication userAuthentication2 = new UserAuthentication();
boolean exists = false,admin = false;
try {
exists = userAuthentication2.doesUserExist(
userAuthentication.getUsers_email(),
userAuthentication.getUsers_password());
} catch (Exception e) {
e.printStackTrace();
}
if (exists == true) {
System.out.println("user present");
httpSession.setAttribute("id", userAuthentication.getUsers_email());
System.out.println("Session Attribute: "
+ httpSession.getAttribute("id"));
return new ModelAndView("redirect:employee");
} else {
System.out.println("user not present");
return new ModelAndView("loginpage");
}
}
user authentication
public class UserAuthentication {
public boolean doesUserExist(String uname, String passwrd) throws Exception {
GetSession ses = new GetSession();
Session session = ses.retSession();
String query = "from Users as u where u.users_email = :sUname and u.users_password = :sPass";
List list = session.createQuery(query).setString("sUname", uname)
.setString("sPass", passwrd).list();
Iterator iterator = list.iterator();
boolean userExists = false;
if (iterator.hasNext()) {
Users obj = (Users) iterator.next();
System.out.print(obj.getUsers_email() + "\t"
+ obj.getUsers_password() + "\n");
System.out.println(obj.getMyRoles());
System.out.println("Is Admin??? :" +obj.getMyRoles().toString().contains("Admin")); //gives if user is admin or not
System.out.println(obj.getUser_id());
userExists = true;
}
System.out.println(userExists);
return userExists;
}
}
Tabs.jsp
<%# page language="java" contentType="text/html; charset=ISO-8859-1"
pageEncoding="ISO-8859-1"%>
<html>
<body>
<div id="tabs" style="background-color: #C8C8C8; font-family: fantasy;">
Employee Details
Departments
Designation
Logout
Users
Roles
</div>
</body>
</html>
users and Roles links must be displayed only if user is admin and this tabs.jsp is included in every page of the application.

Put the User object in HttpSession in Controller and check whether the logged in User is admin or not in jsp
<%# page language="java" contentType="text/html; charset=ISO-8859-1"
pageEncoding="ISO-8859-1"%>
<html>
<body>
<div id="tabs" style="background-color: #C8C8C8; font-family: fantasy;">
Employee Details
Departments
Designation
Logout
<c:if test=${sessionScope.user.isAdmin}>
Users
Roles
</c:if>
</div>
</body>
</html>

Related

request.getAttribute("user") returning null object

I am trying to send object of User class to success.jsp. But getting null when trying to retrieve the object in success.jsp.
Code for UserController:
#Controller
#RequestMapping("/user")
public class UserController {
#PostMapping("/login")
public String Register(#Valid #ModelAttribute("user") User user,Errors errors,Model model) {
System.out.println("....done....");
if(errors.hasErrors()) {
return "user";
}
else {
RegisterService.show(user);
model.addAttribute("user",user);
return "redirect:/success";
}
}
}
Code for success.jsp
<%# page language="java" contentType="text/html; charset=ISO-8859-1"
pageEncoding="ISO-8859-1"%>
<%# taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
<%# page import="com.company.models.User" %>
<body>
Registration Successful
<%
User user=(User)request.getAttribute("user");
System.out.println("user="+user);
%>
</body>
you can use RedirectAttributes to send data to the page even if you are redirecting.
example:
#PostMapping("/login")
public String Register(#Valid #ModelAttribute("user") User user,Errors errors, RedirectAttributes attributes) {
System.out.println("....done....");
if(errors.hasErrors()) {
return "user";
}
else {
RegisterService.show(user);
attributes.addFlashAttribute("user", user);
return "redirect:/success";
}
}
read the documentation at: https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/web/servlet/mvc/support/RedirectAttributes.html
It was because I was sending a redirect to success.jsp. So cannot pass data

Spring Boot, Html button which will add parameters to table in database

I want to make a link or another html element which will add parameters to table in MySQL database using JPA and Thymeleaf. I've made a link which have a good url (create a new parameters in table) but after click on this element firefox says : "The address wasn’t understood" but manually entered the same url works. I need that element in index.html which after click will insert into table values. Thank you.
Controller:
#Controller
public class UserController {
#RequestMapping("/")
public String home() {
return "index";
}
#Autowired
private UserDao userDao;
#RequestMapping("/create")
#ResponseBody
public String create(String email, String name) {
String userId="";
try {
User user = new User(email, name);
userDao.save(user);
userId = String.valueOf(user.getId());
}
catch (Exception exception) {
return "Error creating the user" + exception.toString();
}
return "User succesfully created with id = " + userId;
}
index.html :
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>HomePage</title>
</head>
<body>
<div id="container">
<a href="localhost:8080/create/email=john10234#gmail.com&name=John">Click to
add: ([id], 'john10234#gmail.com', 'John')
</a>
</div>
</body>
</html>
you missed ? in url
your url will
a href="localhost:8080/create?email=john10234#gmail.com&name=John">
instead of a href="localhost:8080/create/email=john10234#gmail.com&name=John">
Also use #RequestParam
#RequestMapping("/create")
#ResponseBody
public String create(#RequestParam("email")String email, #RequestParam("name")String name)

The Java servlet HttpSession does not seem to work immediately

In my login servlet, the last code of doPost is as follows:
HttpSession session = request.getSession();
session.setAttribute(Config.CURRENT_USER_PARAMETER, user);
request.getRequestDispatcher("app.jsp").forward(request, response);
What comes to app.jsp, it is as follows:
<%#page import="fi.vakuutustiedot.controllers.Config"%>
<%#page import="fi.vakuutustiedot.model.User"%>
<%#taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
<%#page contentType="text/html" pageEncoding="UTF-8"%>
<%
if (session == null) {
request.getRequestDispatcher("index.html").forward(request, response);
return;
}
User user = (User) session.getAttribute(Config.CURRENT_USER_PARAMETER);
if (user == null) {
session.invalidate();
request.getRequestDispatcher("index.html").forward(request, response);
return;
}
%>
<!DOCTYPE html>
...
My problem is the following scenario:
I login through the HTML form that is connected to my login servlet.
The login servlet creates a HttpSession and adds an attribute for the object describing the user in question.
Finally, it forwards to app.jsp.
The problem is that when I am logged and forwarded to app.jsp, I see everything I am supposed to see, but if I type .../app.jsp in the location bar and press Enter it redirects to index.html! However, when I visit app.jsp the second, third, .etc time, everything is fine and no spurious redirect to index.html happens.
Is this solution adequate from the security standpoint?
I resolved the issue by adding in the login servlet the following line:
HttpSession session = request.getSession();
request.setAttribute(Config.CURRENT_USER_PARAMETER, user); // <- The new added line.
session.setAttribute(Config.CURRENT_USER_PARAMETER, user);
request.getRequestDispatcher("app.jsp").forward(request, response);
And in app.jsp I have:
<%#page import="fi.vakuutustiedot.controllers.Config"%>
<%#page import="fi.vakuutustiedot.model.User"%>
<%#page import="fi.vakuutustiedot.model.UserType"%>
<%#taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
<%#page contentType="text/html" pageEncoding="UTF-8"%>
<%! User user = null; %>
<%
if (session == null) {
request.getRequestDispatcher("no_session.html").forward(request, response);
return;
}
user = (User) session.getAttribute(Config.CURRENT_USER_PARAMETER);
if (user == null) {
user = (User) request.getAttribute(Config.CURRENT_USER_PARAMETER);
}
if (user == null) {
request.getRequestDispatcher("test.jsp").forward(request, response);
return;
}
%>
<!DOCTYPE html>
...
Answering my own question
In the login servlet, all I do is:
HttpSession session = request.getSession();
session.setAttribute(Config.CURRENT_USER_PARAMETER, user);
response.sendRedirect("app.jsp");
That way, the user object is available straight from the session and I do not need to put that user to the request object.
It would seem you are trying to get to a page outside of your context.
By your question, I am only guessing your directory is:
/index.html
/app.jsp
When you are running your application, you probably inter a URI such as:
http://[my_server]/[my_app]/index.html
or just:
http://[my_server]/[my_app]/
When you type ../app.jsp, your are trying to get something that is not there. Your server is probably set to send a default page of index.html with no default error page.
I am guessing you are just getting back the index.html page because of the incorrect URI.

Sending HttpSession from one controller to another in spring mvc

I am redirecting my request from one controller to another, but while doing that I am loosing my session attributes. But I want to use the session only so that I can verify if user is logged in or not. Whole condition is explained below:
Login.jsp
This is the page in which user gives its username and password and the request goes to "LoginController" .
<%# page language="java" contentType="text/html; charset=ISO-8859-1"
pageEncoding="ISO-8859-1"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>Login</title>
</head>
<body>
${loginError }
<h1>Login Details</h1>
<form action="${pageContext.request.contextPath }/login" method="post">
<table>
<tr>
<td>Username</td>
<td><input type="text" name="userId" ></td>
</tr>
<tr>
<td>Password</td>
<td><input type="password" name="password" ></td>
</tr>
<tr>
<td><input type="submit" name="Submit" value="Submit"></td>
</tr>
</table>
</form>
</body>
</html>
LoginController.java
As the action was "login" using post method so the request maps to "verifyLogin()" method.
I have checked for the customer name it is coming after calling "loginCustomer()" method of "CustomerService" class.
But when I set it in session attributes and redirect it to url which match up to "HomeController" method I am losing that session attributes their.
#Controller
#RequestMapping(value="/login")
public class LoginController {
#Autowired
private CustomerService customerService;
#RequestMapping(method=RequestMethod.GET)
public String showLoginForm(){
return "login";
}
#RequestMapping(method=RequestMethod.POST)
public String verifyLogin(#RequestParam String userId, #RequestParam String password, HttpSession session, Model model){
Customer customer = customerService.loginCustomer(userId, password);
if(customer==null){
model.addAttribute("loginError", "Username or password is not correct");
return "login";
}
session.addAttribute("loggedInUser", customer);
return "redirect:/";
}
#RequestMapping(value="logout", method=RequestMethod.GET)
public String logoutUser(HttpSession session){
session.removeAttribute("loggedInUser");
return "login";
}
#ExceptionHandler(Exception.class)
public ModelAndView handleException(){
ModelAndView mav = new ModelAndView();
mav.addObject("loginError", "Usrname or password is not correct");
mav.setViewName("login");
return mav;
}
}
HomeController.java
The request mapped to "home()" method. This method is also called when application loads up, and when user logged in correctly then also it is called.
Here in this method I am loosing my session attribute, but I want it in the page were this method maps i.e. home.jsp the return value of this method.
As session attribute is not available in this method so its not available in the home.jsp page also.
Please help.
#Controller
public class HomeController {
#Autowired
private ProductService productService;
#Autowired
private CategoryService categoryService;
#RequestMapping(value = "/", method = RequestMethod.GET)
public String home(Model model) {
List<Product> products = productService.getFeaturedProducts();
List<Category> categories = categoryService.getAllCategories();
model.addAttribute("featuredProduct", products);
model.addAttribute("categories",categories);
return "home";
}
}
I would suggest to go for RedirectAttributes.
redirectAttrs.addFlashAttribute("loggedInUser", customer);
Further reading: -Flash Attribute
My first guess would be that your session Id cookie might get lost between login and next page. (could be because the Web app is configured not to use cookies or the cookie is set for the wrong domain)
To verify check in your browser that:
After successful login the server sets the session cookie for the current host (chrome or Firefox Dev tools can help you here)
And also that your Browser sends the same cookie in the next request for the homepage.
If this does not help please also include the set cookie and the cookie headers in your reply
I've used session with the help plain old HttpServletRequest request and that seemed to serve the purpose for me.
#RequestMapping(method=RequestMethod.POST)
public String verifyLogin(#RequestParam String userId, #RequestParam String password, HttpServletRequest request, Model model){
Customer customer = customerService.loginCustomer(userId, password);
HttpSession session = request.getSession(false);
if (session == null) {
session = request.getSession();
}
if(customer==null){
model.addAttribute("loginError", "Username or password is not correct");
return "login";
}
session.addAttribute("loggedInUser", customer);
return "redirect:/";
}
By this way, you can access the session values through the request object in both your controller and jsp page.

How to initialize a hash map at Server startup?

I have created a simple login application using JSP form and displaying HomePage through a Servlet.I have also created a HashMap inside servlet which stores a couple of username and passwords.When a user enters username and password it is compared with those present inside the map and appropriate message is displayed.But the problem here is the HashMap is initialized after user hits the Login button i.e,when servlet program starts up.I want to initialize the map before hand and when ever user logs in the comparison with map should take place,instead of initialising map after Logging in.Kindly help me how I can go about it.
Here is what I have done so far
Login.jsp
<%# page language="java" contentType="text/html; charset=ISO-8859-1"
pageEncoding="ISO-8859-1"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>Login</title>
</head>
<body>
<center>
<b>LOGIN PAGE</b><br>
</center>
<form name="login" method="post" action="UserAuthentication">
<center>
USER NAME: <input type="text" name="username">
<br>
<br>
PASSWORD: <input type="password" name="password">
<br>
<br>
<input type="submit" value="LOGIN">
</center>
</form>
</body>
</html>
UserAuthentication.java
public class UserAuthentication extends HttpServlet{
public void doPost(HttpServletRequest request,HttpServletResponse response)
throws IOException{
String username = request.getParameter("username");
String password = request.getParameter("password");
PrintWriter out = response.getWriter();
Map<String,String>users = new HashMap<String,String>();
users.put("Sheetal", "sss");
users.put("Raj","rrr");
users.put("Anjali", "aaa");
users.put("Bhavya","bbb");
if(users.containsKey(username) && users.containsValue(password))
{
if(password.equals(users.get(username)))
{
out.println("<html>"+
"<body>"+
"Login Successful" + "<br>" +
"Welcome " + username + "<br>" +
"</body>" +
"</html>");
}
}
else
{
out.println("<html>"+
"<body>"+
"Login Unsuccessful" + "<br>" +
"Try again" + "<br>" +
"</body>" +
"</html>");
}
}
}
TIA
Make the hashmap a static in the class (I also assumed its final):
private static final Map<String,String> users = new HashMap<>();
And populate it in the static initializer block:
static {
users.put("Sheetal", "sss");
users.put("Raj", "rrr");
users.put("Anjali", "aaa");
users.put("Bhavya", "bbb");
}
This way, the HashMap will be populated, when the class is registered.
If you did not know about initializers, please read this article.
The best way in your case is to create a singleton class called users, which would be like below.
public class Users{
private static Map<String,String> users = new HashMap<>();
private users(){
users.put("Sheetal", "sss");
users.put("Raj", "rrr");
users.put("Anjali", "aaa");
users.put("Bhavya", "bbb");
}
public static Users singleInstance = new Users();
public boolean validate(String userName,String password)
{
boolean result = false;
if(condition)
result = true;
return result;
}
and in your UserAuthentication.java when you want to do the validation,
if(Users.singleInstance.validate(userName,password))

Categories