Issue
home Controller
package com.book.controller;
import java.util.HashSet;
import java.util.Locale;
import java.util.Set;
import java.util.UUID;
import javax.servlet.http.HttpServletRequest;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.mail.SimpleMailMessage;
import org.springframework.mail.javamail.JavaMailSender;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import com.book.entity.User;
import com.book.security.entity.PasswordResetToken;
import com.book.security.entity.Role;
import com.book.security.entity.UserRole;
import com.book.security.impl.MailConstructor;
import com.book.security.impl.SecurityUtility;
import com.book.security.impl.UserSecurityService;
import com.book.security.repo.UserService;
@Controller
public class HomeController {
@Autowired
private JavaMailSender mailSender;
@Autowired
private MailConstructor mailConstructor;
@Autowired
private UserService userService;
@Autowired
private UserSecurityService userSecurityService;
@RequestMapping("/")
public String index() {
return "index";
}
@RequestMapping("/login")
public String login(Model model) {
model.addAttribute("classActiveLogin", true);
return "myAccount";
}
@RequestMapping("/forgetPassword")
public String forgetPassword(HttpServletRequest request, @ModelAttribute("email") String email, Model model) {
model.addAttribute("classActiveForgetPassword", true);
User user = userService.findByEmail(email);
if (user == null) {
model.addAttribute("emailNotExist", true);
return "myAccount";
}
String password = SecurityUtility.randomPassword();
String encryptedPassword = SecurityUtility.passwordEncoder().encode(password);
user.setPassword(encryptedPassword);
userService.save(user);
String token = UUID.randomUUID().toString();
userService.createPasswordResetTokenForUser(user, token);
String appUrl = "http://" + request.getServerName() + ":" + request.getServerPort() + request.getContextPath();
SimpleMailMessage emails = mailConstructor.constructResetTokenEmail(appUrl, request.getLocale(), token, user,
password);
mailSender.send(emails);
model.addAttribute("emailSent", "true");
return "myAccount";
}
@RequestMapping(value = "/newUser", method = RequestMethod.POST)
public String newUserPost(HttpServletRequest request, @ModelAttribute("email") String userEmail,
@ModelAttribute("username") String username, Model model) throws Exception {
model.addAttribute("classActiveNewAccount", true);
model.addAttribute("email", userEmail);
model.addAttribute("username", username);
if (userService.findByUsername(username) != null) {
model.addAttribute("usernameExists", true);
return "myAccount";
}
if (userService.findByEmail(userEmail) != null) {
model.addAttribute("emailExists", true);
return "myAccount";
}
User user = new User();
user.setUsername(username);
user.setEmail(userEmail);
String password = SecurityUtility.randomPassword();
String encryptedPassword = SecurityUtility.passwordEncoder().encode(password);
user.setPassword(encryptedPassword);
Role role = new Role();
role.setRoleId(1);
role.setName("ROLE_USER");
Set<UserRole> userRoles = new HashSet<>();
userRoles.add(new UserRole(user, role));
userService.createUser(user, userRoles);
String token = UUID.randomUUID().toString();
userService.createPasswordResetTokenForUser(user, token);
String appUrl = "http://" + request.getServerName() + ":" + request.getServerPort() + request.getContextPath();
SimpleMailMessage email = mailConstructor.constructResetTokenEmail(appUrl, request.getLocale(), token, user,
password);
mailSender.send(email);
model.addAttribute("emailSent", "true");
return "myAccount";
}
@RequestMapping("/newUser")
public String newUser(Locale locale, @RequestParam("token") String token, Model model) {
PasswordResetToken passToken = userService.getPasswordResetToken(token);
if (passToken == null) {
String message = "Invalid Token.";
model.addAttribute("message", message);
return "redirect:/badRequest";
} else {
User user = passToken.getUser();
String username = user.getUsername();
UserDetails userDetails = userSecurityService.loadUserByUsername(username);
Authentication authentication = new UsernamePasswordAuthenticationToken(userDetails,
userDetails.getPassword(), userDetails.getAuthorities());
SecurityContextHolder.getContext().setAuthentication(authentication);
model.addAttribute("user", user);
model.addAttribute("classActiveEdit", true);
return "myProfile";
}
}
}
Header.html
<!DOCTYPE html>
<html lang="en" xmlns="http://www.w3.org/1999/xhtml"
xmlns:th="http://www.thymeleaf.org"
xmlns:sec="http://www.thymeleaf.org/thymeleaf-extras-springsecurity4">
<head th:fragment="common-header">
<meta charset="utf-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<title>Le's Bookstore</title>
<!-- Bootstrap core CSS -->
<link href="/css/bootstrap.min.css" rel="stylesheet" />
<link href="/css/non-responsive.css" rel="stylesheet" />
<!-- Custom styles for this template -->
<link href="/css/style.css" rel="stylesheet" />
<link rel="icon" href="/image/applie-touch-icon.png" />
</head>
<body>
<div th:fragment="navbar">
<div class="page-top"
style="width: 100%; height: 20px; background-color: #f46b42;"></div>
<!-- Static navbar -->
<nav class="navbar navbar-default navbar-inverse">
<div class="container-fluid">
<div class="navbar-header">
<a class="navbar-brand" href="#">LE'S BOOKSTORE</a>
</div>
<div id="navbar">
<ul class="nav navbar-nav navbar-left">
<li class="dropdown"><a href="#" class="dropdown-toggle"
data-toggle="dropdown" role="button" aria-haspopup="true"
aria-expanded="false">BOOKS <span class="caret"></span></a>
<ul class="dropdown-menu">
<li><a href="#">Browse the bookshelf</a></li>
<li><a href="#">Store hours & Directions</a></li>
<li><a href="#">FAQ</a></li>
</ul></li>
<form class="navbar-form" role="search">
<div class="form-group">
<input type="text" name="keyword" class="form-control"
placeholder="Book title" />
</div>
<button type="submit" class="btn btn-default">Search</button>
</form>
</ul>
<ul class="nav navbar-nav navbar-right">
<li><a href="#">SHOPPING CART</a></li>
<li sec:authorize="isAnonymous()"><a th:href="@{/login}">MY ACCOUNT</a></li>
<li sec:authorize="isAuthenticated()"><a th:href="@{/myProfile}">MY ACCOUNT</a></li>
<li sec:authorize="isAuthenticated()"><a th:href="@{/logout}">LOGOUT</a></li>
</ul>
</div>
<!--/.nav-collapse -->
</div>
<!--/.container-fluid -->
</nav>
</div>
<div th:fragment="body-bottom-scripts">
<script
src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script>
<script src="/js/bootstrap.min.js"></script>
</div>
</body>
</html>
SecurityConfig
package com.book.security.config;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.web.util.matcher.AntPathRequestMatcher;
import com.book.security.impl.SecurityUtility;
import com.book.security.impl.UserSecurityService;
@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled=true)
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Autowired
private UserSecurityService userSecurityService;
private BCryptPasswordEncoder passwordEncoder() {
return SecurityUtility.passwordEncoder();
}
private static final String[] PUBLIC_MATCHERS = {
"/css/**",
"/js/**",
"/image/**",
"/",
"/newUser",
"/forgetPassword",
"/login",
"/fonts/**"
};
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.antMatchers(PUBLIC_MATCHERS).permitAll()
.anyRequest().authenticated()
.and()
.csrf().disable().cors().disable()
.formLogin().failureUrl("/login?error")
.defaultSuccessUrl("/")
.loginPage("/login").permitAll()
.and()
.logout().logoutRequestMatcher(new AntPathRequestMatcher("/logout"))
.logoutSuccessUrl("/?logout").deleteCookies("remember-me").permitAll()
.and()
.rememberMe();
}
@Autowired
public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(userSecurityService).passwordEncoder(passwordEncoder());
}
}
pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.1.3.RELEASE</version>
<relativePath /> <!-- lookup parent from repository -->
</parent>
<groupId>com.rakib.springboot</groupId>
<artifactId>book-shop</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>book-shop</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jdbc</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<dependency>
<groupId>org.thymeleaf.extras</groupId>
<artifactId>thymeleaf-extras-springsecurity4</artifactId>
<version>3.0.4.RELEASE</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context-support</artifactId>
</dependency>
<dependency>
<groupId>javax.mail</groupId>
<artifactId>mail</artifactId>
<version>1.4.7</version>
</dependency>
<dependency>
<groupId>org.antlr</groupId>
<artifactId>antlr-complete</artifactId>
<version>3.5.2</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
Problem: sec:authorize returning true for both isAuthenticated() and isAnonymous() in thymeleaf view. i try to hide my_Profile, Log in when user log in and when log out then show only Log in. BUT ITS not working .... enter image description here
not working in both condition. please help me sir to continue the project.
Solution
<dependency>
<groupId>org.thymeleaf.extras</groupId>
<artifactId>thymeleaf-extras-springsecurity5</artifactId>
</dependency>
When you upgrade your security version 5 and it will be fixed.
Answered By - xpec