Github : advsecurity

3. Basic Spring Security



    3. 2 . Signup / Signin / SIgnout 


1. Signup:

   - Signup refers to the process where a new user registers with the system.

   - In Spring Security, the user's account information is typically stored in a database, and passwords are encrypted when necessary.

   - When implementing signup functionality, a form for users to input their information is usually provided, and the entered information is processed to create a new account.


2. Signin:

   - Signin is the process where a user authenticates with their account in the system.

   - In Spring Security, a login form is provided, and authentication is performed based on the account information provided by the user.

   - If the provided account information is correct, the system grants the user an authenticated session and sets up a security context.

   - Spring Security uses the AuthenticationManager for user authentication and processes authentication through AuthenticationProviders.


3. Signout:

   - Signout is the process where a user ends their login session in the system.

   - Spring Security provides an endpoint for logout, where users can access to request logout.

   - When a logout request is received, the system terminates the user's session and resets the security context.

   - Typically, during logout, it's advisable to redirect the user to a login page or homepage to notify them of the logout.


        Here's a detailed list of the topics


  • 3.2.1 Advanced Spring Security Project:
  • 3.2.2 Spring Security Configuration:
  • 3.2.3 Signup, Signin, Signout, Withdraw:
  • 3.2.4 Authentication / Authorization:


3.2.1 Advanced Spring Security Project:

  


3.2.2 Spring Security Configuration:


application.properties


spring.application.name=advsecurityexam

# Database Setting
spring.datasource.dbcp2.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.url=jdbc:mysql://localhost:3306/securityexam
spring.datasource.username=root
spring.datasource.password=1111

# JPA
spring.jpa.hibernate.ddl-auto=update
spring.jpa.properties.hibernate.show_sql=true


        create Database



       create Customer.java

package com.example.advsecurityexam;
import java.time.LocalDateTime;
import jakarta.persistence.Column;
import jakarta.persistence.Entity;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.GenerationType;
import jakarta.persistence.Id;
import lombok.Data;

@Data
@Entity
public class Customer {

@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer cid;

@Column(unique = true)
private String username; // for SpringSecurity Policy
private String password; // for SpringSecurity Policy
private boolean enabled; // for SpringSecurity Policy
private String role;           // for SpringSecurity Policy

@Column(unique = true)
private String cemail;
private String cimage;
private LocalDateTime cdate;

}


      create SecurityConfig.java Class

package com.example.advsecurityexam;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.config.annotation.authentication.configuration.AuthenticationConfiguration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.web.SecurityFilterChain;
import org.springframework.security.web.util.matcher.AntPathRequestMatcher;

@Configuration
@EnableWebSecurity
public class SecurityConfig {

@Bean
SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
http
.authorizeHttpRequests((authorizeHttpRequests) -> authorizeHttpRequests
.requestMatchers(new AntPathRequestMatcher("/**")).permitAll())
.formLogin((formLogin) -> formLogin
.loginPage("/signin")
.defaultSuccessUrl("/")
)
.logout((logout) -> logout
.logoutRequestMatcher(new AntPathRequestMatcher("/signout"))
.logoutSuccessUrl("/")
.invalidateHttpSession(true))
;
return http.build();
}
@Bean
PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
@Bean
AuthenticationManager authenticationManager(AuthenticationConfiguration authenticationConfiguration) throws Exception {
return authenticationConfiguration.getAuthenticationManager();

}

}



3.2.3 SIgnup, Signin, Signout, WIthdraw:


      Repository

package com.example.advsecurityexam;
import java.util.Optional;
import org.springframework.data.jpa.repository.JpaRepository;

public interface CustomerRepository extends JpaRepository<Customer, Integer> {

Optional<Customer> findByusername(String username); // login check

}


      Service

package com.example.advsecurityexam;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.userdetails.User;
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;

@Service
public class CustomerService implements UserDetailsService {

@Autowired
private CustomerRepository customerRepository;

@Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {

Optional<Customer> tcustomer = customerRepository.findByusername(username);
if (tcustomer.isEmpty()) {
throw new UsernameNotFoundException("You need to Sign up first...");
}
Customer customer = tcustomer.get();
List<GrantedAuthority> authorities = new ArrayList<>();
if ("ROLE_USER".equals(customer.getRole())) {
authorities.add(new SimpleGrantedAuthority("ROLE_USER"));
} else if ("ROLE_MANAGER".equals(customer.getRole())) {
authorities.add(new SimpleGrantedAuthority("ROLE_MANAGER"));
} else {
authorities.add(new SimpleGrantedAuthority("ROLE_ADMIN"));
}
return new User(customer.getUsername(), customer.getPassword(), authorities);

}

public void create(Customer customer) {

customer.setEnabled(true);
customer.setRole("ROLE_USER"); //ROLE_ADMIN, ROLE_MANAGER, ROLE_PAID...
customer.setCdate(LocalDateTime.now());
BCryptPasswordEncoder passwordEncoder = new BCryptPasswordEncoder();
customer.setPassword(passwordEncoder.encode(customer.getPassword()));
customerRepository.save(customer);

}

}


      Controller

package com.example.advsecurityexam;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;

@Controller
public class CustomerController {

@Autowired
private CustomerService customerService;
@GetMapping("/")
public String signup() {
return "signup";
}
@PostMapping("/signup")
public String signup(Customer customer) {
customerService.create(customer);
return "signup";
}
@GetMapping("/signin")
public String signin() {
return "signin";
}

}


     signup.html

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
<span sec:authorize="isAnonymous()">Signin First...<a href="/signin">Sign in</a></span>
<span sec:authorize="isAuthenticated()">Welcome...<span th:text="${#authentication.name}"></span>
<span th:text="${#authentication.authorities}"></span>
<a href="/signout">Sign out</a>
</span>


<form action="/signup" method="post">
<input type="hidden" th:name="${_csrf.parameterName}" th:value="${_csrf.token}" />
<p>ID : <input type="text" name="username">
<p>PW : <input type="password" name="password">
<p>Mail : <input type="text" name="cemail">
<p><input type="submit" value="Sign up">
</form>
</body>
</html>


      signin.html

<!DOCTYPE html>
<html>
<head>
<meta charset="ISO-8859-1">
<title>Insert title here</title>
</head>
<body>
<form action="/signin" method="post">
<div th:if="${param.error}">
<div class="alert alert-danger">
Please, Check your ID or Password...
</div>
</div>
<input type="hidden" th:name="${_csrf.parameterName}" th:value="${_csrf.token}" />
<p>ID : <input type="text" name="username">
<p>PW : <input type="password" name="password">
<p><input type="submit" value="Sign in">
</form>
</body>
</html>




3.2.4 Authentication & Authorization:

  



   


      Controller

package com.example.advsecurityexam;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
@Controller
public class AuthoController {
@GetMapping("/")
public String index() {

return "autho/index";
}
@GetMapping("/admin")
public String admin() {

return "autho/admin";
}
@GetMapping("/manager")
public String manager() {

return "autho/manager";
}
@GetMapping("/user")
public String user() {

return "autho/user";
}
}


index.html

<!DOCTYPE html>
<html>
<head>
<meta charset="EUC-KR">
<title>Insert title here</title>
</head>
<body>
<p><a href="/admin">admin</a>
<p><a href="/manager">manager</a>
<p><a href="/user">user</a>
</body>
</html>






you need to set security config first...



package com.example.advsecurityexam;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
@Controller
public class AuthoController {
@GetMapping("/")
public String index() {

return "autho/index";
}

@PreAuthorize("hasAuthority('ROLE_ADMIN')")
@GetMapping("/admin")
public String admin() {

return "autho/admin";
}

@PreAuthorize("hasAnyAuthority('ROLE_ADMIN','ROLE_MANAGER')")
@GetMapping("/manager")
public String manager() {

return "autho/manager";
}

@PreAuthorize("isAuthenticated()")
@GetMapping("/user")
public String user() {

return "autho/user";
}
}






한국정보시스템개발원 |
Hankook Information System Institute

austiny@snu.ac.kr / austiny@gatech.edu