Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 5 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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 ------------------
Expand All @@ -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
```

Expand Down
21 changes: 17 additions & 4 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.7.2</version>
<version>2.7.16</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.example</groupId>
Expand All @@ -14,7 +14,7 @@
<name>Login Register</name>
<description>Login Register Example for Spring Boot (Maven)</description>
<properties>
<java.version>17</java.version>
<java.version>21</java.version>
</properties>
<dependencies>
<dependency>
Expand All @@ -35,8 +35,8 @@
</dependency>

<dependency>
<groupId>org.postgresql</groupId>
<artifactId>postgresql</artifactId>
<groupId>com.mysql</groupId>
<artifactId>mysql-connector-j</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
Expand All @@ -58,13 +58,26 @@
<groupId>org.thymeleaf.extras</groupId>
<artifactId>thymeleaf-extras-springsecurity5</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
</dependencies>

<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<excludes>
<exclude>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</exclude>
</excludes>
</configuration>
</plugin>
</plugins>
</build>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand All @@ -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<String> roles = new ArrayList<String>();
List<String> roles = new ArrayList<>();
for(GrantedAuthority a : authorities){
roles.add(a.getAuthority());
}
Expand Down
33 changes: 7 additions & 26 deletions src/main/java/com/example/demo/config/WebSecurityConfig.java
Original file line number Diff line number Diff line change
@@ -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;
Expand All @@ -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();
Expand All @@ -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()
Expand All @@ -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();
}

Expand Down
Original file line number Diff line number Diff line change
@@ -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";
}
Expand Down
17 changes: 10 additions & 7 deletions src/main/java/com/example/demo/controller/AuthController.java
Original file line number Diff line number Diff line change
Expand Up @@ -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";
}
Expand Down
Original file line number Diff line number Diff line change
@@ -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";
}
Expand Down
7 changes: 4 additions & 3 deletions src/main/java/com/example/demo/model/Role.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
package com.example.demo.model;

import lombok.AllArgsConstructor;
import lombok.Getter;

@Getter
public enum Role {
USER("User"),
ADMIN("Admin");
Expand All @@ -10,7 +14,4 @@ private Role(String value) {
this.value = value;
}

public String getValue() {
return value;
}
}
38 changes: 14 additions & 24 deletions src/main/java/com/example/demo/model/User.java
Original file line number Diff line number Diff line change
@@ -1,21 +1,28 @@
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;

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(
Expand All @@ -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
Expand All @@ -60,6 +71,7 @@ public class User implements UserDetails {
@Column(name = "updated_at")
private LocalDateTime updatedAt;


@Enumerated(EnumType.STRING)
private Role role;

Expand Down Expand Up @@ -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; }
}
Loading