diff --git a/README.md b/README.md index a123dfb..e4ee052 100644 --- a/README.md +++ b/README.md @@ -9,7 +9,7 @@ Learn to Implement this project: [Tutorial - Login Register in Spring Boot](http application.properties (change database settings) ``` #-------------------- server properties --------------- -server.port=8080 +server.port='Your port of choice' server.error.include-message=always #--------------------- Logging ------------------ @@ -19,14 +19,14 @@ logging.level.org.springframework.web=DEBUG logging.level.org.hibernate=ERROR #--------------------- DB Connection ------------------ -spring.datasource.url=jdbc:postgresql://localhost:5432/demo -spring.datasource.username=demo -spring.datasource.password=password +spring.datasource.url=jdbc:'your sql provider'://localhost:5432/demo +spring.datasource.username='username for your database' +spring.datasource.password='password to your database' #--------------------JPA-ORM Properties----------------- spring.jpa.show-sql=true spring.jpa.hibernate.ddl-auto=update -spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.PostgreSQLDialect +spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.'Your SQL dialect option' spring.jpa.properties.hibernate.format_sql=true ``` diff --git a/pom.xml b/pom.xml index 4bae3e6..4c1ef3b 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ org.springframework.boot spring-boot-starter-parent - 2.7.2 + 2.7.16 com.example @@ -14,7 +14,7 @@ Login Register Login Register Example for Spring Boot (Maven) - 17 + 21 @@ -35,8 +35,8 @@ - org.postgresql - postgresql + com.mysql + mysql-connector-j runtime @@ -58,6 +58,11 @@ org.thymeleaf.extras thymeleaf-extras-springsecurity5 + + org.projectlombok + lombok + true + @@ -65,6 +70,14 @@ org.springframework.boot spring-boot-maven-plugin + + + + org.projectlombok + lombok + + + diff --git a/src/main/java/com/example/demo/config/CustomLoginSucessHandler.java b/src/main/java/com/example/demo/config/CustomLoginSuccessHandler.java similarity index 91% rename from src/main/java/com/example/demo/config/CustomLoginSucessHandler.java rename to src/main/java/com/example/demo/config/CustomLoginSuccessHandler.java index f979338..4f4c201 100644 --- a/src/main/java/com/example/demo/config/CustomLoginSucessHandler.java +++ b/src/main/java/com/example/demo/config/CustomLoginSuccessHandler.java @@ -15,7 +15,7 @@ import java.util.List; @Configuration -public class CustomLoginSucessHandler extends SimpleUrlAuthenticationSuccessHandler { +public class CustomLoginSuccessHandler extends SimpleUrlAuthenticationSuccessHandler { @Override protected void handle(HttpServletRequest request, HttpServletResponse response, Authentication authentication) throws IOException { @@ -28,7 +28,7 @@ protected void handle(HttpServletRequest request, HttpServletResponse response, protected String determineTargetUrl(Authentication authentication){ String url = "/login?error=true"; Collection extends GrantedAuthority> authorities = authentication.getAuthorities(); - List roles = new ArrayList(); + List roles = new ArrayList<>(); for(GrantedAuthority a : authorities){ roles.add(a.getAuthority()); } diff --git a/src/main/java/com/example/demo/config/WebSecurityConfig.java b/src/main/java/com/example/demo/config/WebSecurityConfig.java index 424e360..66ae996 100644 --- a/src/main/java/com/example/demo/config/WebSecurityConfig.java +++ b/src/main/java/com/example/demo/config/WebSecurityConfig.java @@ -1,6 +1,7 @@ package com.example.demo.config; import com.example.demo.service.UserServiceImpl; +import lombok.AllArgsConstructor; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @@ -17,16 +18,10 @@ @Configuration @EnableWebSecurity +@AllArgsConstructor public class WebSecurityConfig { - @Autowired - private CustomLoginSucessHandler sucessHandler; - - @Bean - public UserDetailsService userDetailsService() { - return new UserServiceImpl(); - } - + private CustomLoginSuccessHandler successHandler; @Bean public BCryptPasswordEncoder passwordEncoder() { return new BCryptPasswordEncoder(); @@ -37,31 +32,21 @@ public AuthenticationManager authenticationManager(AuthenticationConfiguration a return authConfig.getAuthenticationManager(); } - @Bean - public DaoAuthenticationProvider authenticationProvider() { - DaoAuthenticationProvider authProvider = new DaoAuthenticationProvider(); - - authProvider.setUserDetailsService(userDetailsService()); - authProvider.setPasswordEncoder(passwordEncoder()); - - return authProvider; - } - @Bean public SecurityFilterChain filterChain(HttpSecurity http) throws Exception { http.authorizeRequests() // URL matching for accessibility - .antMatchers("/", "/login", "/register").permitAll() + .antMatchers("/", "/auth/login", "/auth/register").permitAll() .antMatchers("/admin/**").hasAnyAuthority("ADMIN") .antMatchers("/account/**").hasAnyAuthority("USER") .anyRequest().authenticated() .and() // form login .csrf().disable().formLogin() - .loginPage("/login") - .failureUrl("/login?error=true") - .successHandler(sucessHandler) + .loginPage("/auth/login") + .failureUrl("/auth/login?error=true") + .successHandler(successHandler) .usernameParameter("email") .passwordParameter("password") .and() @@ -72,10 +57,6 @@ public SecurityFilterChain filterChain(HttpSecurity http) throws Exception { .and() .exceptionHandling() .accessDeniedPage("/access-denied"); - - http.authenticationProvider(authenticationProvider()); - http.headers().frameOptions().sameOrigin(); - return http.build(); } diff --git a/src/main/java/com/example/demo/controller/AdminController.java b/src/main/java/com/example/demo/controller/AdminController.java index b9d8feb..60812bf 100644 --- a/src/main/java/com/example/demo/controller/AdminController.java +++ b/src/main/java/com/example/demo/controller/AdminController.java @@ -1,13 +1,15 @@ package com.example.demo.controller; import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; @Controller +@RequestMapping("/admin") public class AdminController { - @RequestMapping(value = {"/admin/dashboard"}, method = RequestMethod.GET) + @GetMapping("/dashboard") public String adminHome(){ return "admin/dashboard"; } diff --git a/src/main/java/com/example/demo/controller/AuthController.java b/src/main/java/com/example/demo/controller/AuthController.java index 659a394..bb49f5b 100644 --- a/src/main/java/com/example/demo/controller/AuthController.java +++ b/src/main/java/com/example/demo/controller/AuthController.java @@ -2,36 +2,39 @@ import com.example.demo.model.User; import com.example.demo.service.UserService; -import org.springframework.beans.factory.annotation.Autowired; +import lombok.AllArgsConstructor; import org.springframework.stereotype.Controller; import org.springframework.ui.Model; import org.springframework.validation.BindingResult; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RequestMethod; import javax.validation.Valid; import java.util.List; @Controller +@AllArgsConstructor +@RequestMapping("/auth") public class AuthController { - @Autowired + UserService userService; - @RequestMapping(value = {"/login"}, method = RequestMethod.GET) + @GetMapping("/login") public String login(){ return "auth/login"; } - @RequestMapping(value = {"/register"}, method = RequestMethod.GET) + @GetMapping("/register") public String register(Model model){ model.addAttribute("user", new User()); return "auth/register"; } - @RequestMapping(value = {"/register"}, method = RequestMethod.POST) + @PostMapping("/register") public String registerUser(Model model, @Valid User user, BindingResult bindingResult){ if(bindingResult.hasErrors()){ - model.addAttribute("successMessage", "User registered successfully!"); + model.addAttribute("errorMessage", "User not Registered!"); model.addAttribute("bindingResult", bindingResult); return "auth/register"; } diff --git a/src/main/java/com/example/demo/controller/UserController.java b/src/main/java/com/example/demo/controller/UserController.java index af8ea4f..b65ff31 100644 --- a/src/main/java/com/example/demo/controller/UserController.java +++ b/src/main/java/com/example/demo/controller/UserController.java @@ -1,13 +1,15 @@ package com.example.demo.controller; import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; @Controller +@RequestMapping("/user") public class UserController { - @RequestMapping(value = {"/dashboard"}, method = RequestMethod.GET) + @GetMapping() public String homePage(){ return "user/dashboard"; } diff --git a/src/main/java/com/example/demo/model/Role.java b/src/main/java/com/example/demo/model/Role.java index aad0ca6..d4f37e4 100644 --- a/src/main/java/com/example/demo/model/Role.java +++ b/src/main/java/com/example/demo/model/Role.java @@ -1,5 +1,9 @@ package com.example.demo.model; +import lombok.AllArgsConstructor; +import lombok.Getter; + +@Getter public enum Role { USER("User"), ADMIN("Admin"); @@ -10,7 +14,4 @@ private Role(String value) { this.value = value; } - public String getValue() { - return value; - } } \ No newline at end of file diff --git a/src/main/java/com/example/demo/model/User.java b/src/main/java/com/example/demo/model/User.java index 423eb22..0fca644 100644 --- a/src/main/java/com/example/demo/model/User.java +++ b/src/main/java/com/example/demo/model/User.java @@ -1,8 +1,11 @@ package com.example.demo.model; +import lombok.Data; + import org.hibernate.annotations.CreationTimestamp; import org.hibernate.annotations.UpdateTimestamp; import org.hibernate.validator.constraints.Length; + import org.springframework.security.core.GrantedAuthority; import org.springframework.security.core.authority.SimpleGrantedAuthority; import org.springframework.security.core.userdetails.UserDetails; @@ -10,12 +13,16 @@ import javax.persistence.*; import javax.validation.constraints.Email; import javax.validation.constraints.NotNull; + import java.time.LocalDateTime; + + import java.util.Collection; import java.util.Collections; @Entity +@Data @Table(name = "users") public class User implements UserDetails { @SequenceGenerator( @@ -30,26 +37,30 @@ public class User implements UserDetails { ) private Long id; + @NotNull(message = "First Name cannot be empty") @Column(name = "first_name") private String firstName; + @NotNull(message = "Last Name cannot be empty") @Column(name = "last_name") private String lastName; + @NotNull(message = "Email cannot be empty") @Email(message = "Please enter a valid email address") @Column(name = "email", unique = true) private String email; @NotNull(message = "Password cannot be empty") - @Length(min = 7, message = "Password should be atleast 7 characters long") + @Length(min = 7, message = "Password should be at least 7 characters long") @Column(name = "password") private String password; + @Column(name = "mobile", unique = true) - @Length(min = 10, message = "Password should be atleast 10 number long") + @Length(min = 10, message = "Password should be at least 10 number long") private String mobile; @CreationTimestamp @@ -60,6 +71,7 @@ public class User implements UserDetails { @Column(name = "updated_at") private LocalDateTime updatedAt; + @Enumerated(EnumType.STRING) private Role role; @@ -108,26 +120,4 @@ public boolean isCredentialsNonExpired() { public boolean isEnabled() { return enabled; } - - public Role getRole() { return role; } - - public void setRole(com.example.demo.model.Role role) { - this.role = role; - } - - public String getEmail() { return email; } - - public void setEmail(String email) { this.email = email; } - - public String getFirstName() { return firstName; } - - public void setFirstName(String firstName) { this.firstName = firstName; } - - public String getMobile() { return mobile; } - - public void setMobile(String mobile) { this.mobile = mobile; } - - public String getLastName() { return lastName; } - - public void setLastName(String lastName) { this.lastName = lastName; } } diff --git a/src/main/java/com/example/demo/service/UserServiceImpl.java b/src/main/java/com/example/demo/service/UserServiceImpl.java index 32832dc..b16d9e2 100644 --- a/src/main/java/com/example/demo/service/UserServiceImpl.java +++ b/src/main/java/com/example/demo/service/UserServiceImpl.java @@ -2,31 +2,30 @@ import com.example.demo.model.User; import com.example.demo.repository.UserRepository; -import org.springframework.beans.factory.annotation.Autowired; import org.springframework.security.core.userdetails.UserDetails; import org.springframework.security.core.userdetails.UserDetailsService; import org.springframework.security.core.userdetails.UsernameNotFoundException; import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; import org.springframework.stereotype.Service; +import lombok.AllArgsConstructor; + import java.util.Arrays; import java.util.List; import java.util.Optional; @Service +@AllArgsConstructor public class UserServiceImpl implements UserService, UserDetailsService { - @Autowired BCryptPasswordEncoder bCryptPasswordEncoder; - @Autowired UserRepository userRepository; @Override public void saveUser(User user) { String encodedPassword = bCryptPasswordEncoder.encode(user.getPassword()); user.setPassword(encodedPassword); -// user.setRole(Role.USER); userRepository.save(user); } @@ -54,8 +53,8 @@ public List isUserPresent(User user) { @Override public UserDetails loadUserByUsername(String email) throws UsernameNotFoundException { return userRepository.findByEmail(email).orElseThrow( - ()-> new UsernameNotFoundException( - String.format("USER_NOT_FOUND", email) + () -> new UsernameNotFoundException( + String.format("user with email %s not found", email) )); } } diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties index ce83caa..4cb2601 100644 --- a/src/main/resources/application.properties +++ b/src/main/resources/application.properties @@ -9,12 +9,13 @@ logging.level.org.springframework.web=DEBUG logging.level.org.hibernate=ERROR #--------------------- DB Connection ------------------ -spring.datasource.url=jdbc:postgresql://localhost:5432/matrimony -spring.datasource.username=matrimonyuser -spring.datasource.password=password +spring.datasource.url=jdbc:mysql://localhost:3306/login_register?createDatabaseIfNotExist=true +spring.datasource.username=root +spring.datasource.password=june12003 #--------------------JPA-ORM Properties----------------- spring.jpa.show-sql=true spring.jpa.hibernate.ddl-auto=update -spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.PostgreSQLDialect +spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.MySQLDialect spring.jpa.properties.hibernate.format_sql=true + diff --git a/src/main/resources/templates/about-us.html b/src/main/resources/templates/about-us.html index c341232..8c115a2 100644 --- a/src/main/resources/templates/about-us.html +++ b/src/main/resources/templates/about-us.html @@ -1,9 +1,11 @@ - + + + About Us - About Us + About Us \ No newline at end of file diff --git a/src/main/resources/templates/access-denied.html b/src/main/resources/templates/access-denied.html index 26a782a..91a0486 100644 --- a/src/main/resources/templates/access-denied.html +++ b/src/main/resources/templates/access-denied.html @@ -1,9 +1,12 @@ - + + + Access Denied Access Denied + OOPS, you are not allowed to access this end point. Contact your administrator \ No newline at end of file diff --git a/src/main/resources/templates/admin/dashboard.html b/src/main/resources/templates/admin/dashboard.html index 9a140e2..eca1e6b 100644 --- a/src/main/resources/templates/admin/dashboard.html +++ b/src/main/resources/templates/admin/dashboard.html @@ -1,5 +1,6 @@ - + User Dashboard diff --git a/src/main/resources/templates/auth/login.html b/src/main/resources/templates/auth/login.html index 1acd9e2..fe7d693 100644 --- a/src/main/resources/templates/auth/login.html +++ b/src/main/resources/templates/auth/login.html @@ -1,15 +1,57 @@ - + + + Login - - - - - | - Email or Password is invalid. - + + + Login Register + + + + + + + + + + + + Invalid Username or Password + + + You have been logged out + + + + Login + + + + + Username + + + + Password + + + + Submit + + + + + + + diff --git a/src/main/resources/templates/auth/register.html b/src/main/resources/templates/auth/register.html index 9608f88..38034c2 100644 --- a/src/main/resources/templates/auth/register.html +++ b/src/main/resources/templates/auth/register.html @@ -1,28 +1,73 @@ + Login - - Registration - - - - - - - Select - ADMIN - USER - - Register | - - - - + + + Home Page + + + + + + + Logout + - + + + + + + + + + + Register + + + + + First Name + + + + Last Name + + + + Mobile + + + + Email + + + + Password + + + + Role + + ADMIN + USER + + + + RegisterLog in + + + + + + + + + \ No newline at end of file diff --git a/src/main/resources/templates/homepage.html b/src/main/resources/templates/homepage.html index 6deb9e1..c1321fd 100644 --- a/src/main/resources/templates/homepage.html +++ b/src/main/resources/templates/homepage.html @@ -1,27 +1,52 @@ - + + Homepage - Welcome to Homepage - Text visible to anonymous. - Text visible to user. - Text visible to admin. - Text visible only to authenticated users. + + + Home Page + + + + + + + Logout + + + + + + - - - - + + + Welcome to Homepage + Text visible to anonymous. + Text visible to user. + Text visible to admin. + Text visible only to authenticated users. + + + + + - - Logged as: - Has role: - - - Log out + + Logged as: + Has role: + + + Log out + + + \ No newline at end of file
OOPS, you are not allowed to access this end point. Contact your administrator
Email or Password is invalid.
Text visible to anonymous.
Text visible to user.
Text visible to admin.
Text visible only to authenticated users.
Logged as:
Has role: