diff --git a/src/main/java/com/example/nto/App.java b/src/main/java/com/example/nto/App.java index b22ec6c..d4add94 100644 --- a/src/main/java/com/example/nto/App.java +++ b/src/main/java/com/example/nto/App.java @@ -2,9 +2,8 @@ package com.example.nto; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; -import org.springframework.boot.autoconfigure.security.servlet.SecurityAutoConfiguration; -@SpringBootApplication(exclude = { SecurityAutoConfiguration.class }) +@SpringBootApplication public class App { public static void main(String[] args) { SpringApplication.run(App.class, args); diff --git a/src/main/java/com/example/nto/config/WebSecurityConfig.java b/src/main/java/com/example/nto/config/WebSecurityConfig.java index 0bd9ecd..ae47ed2 100644 --- a/src/main/java/com/example/nto/config/WebSecurityConfig.java +++ b/src/main/java/com/example/nto/config/WebSecurityConfig.java @@ -1,35 +1,40 @@ -//package com.example.nto.controller.config; -// -//import org.springframework.context.annotation.Bean; -//import org.springframework.context.annotation.Configuration; -//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; -// -//@Configuration -//@EnableWebSecurity -//public class WebSecurityConfig { -// @Bean -// public PasswordEncoder passwordEncoder() { -// return new BCryptPasswordEncoder(); -// } -// -// @Bean -// public SecurityFilterChain filterChain(HttpSecurity http) throws Exception { -// http -// .csrf(csrf -> csrf.disable()) -// .authorizeHttpRequests((authorize) -> authorize -// .requestMatchers("/h2-console").permitAll() -// .requestMatchers("/index.html").permitAll() -// .requestMatchers("/register").permitAll() -// .anyRequest().authenticated() -// ); -// -// return http.build(); -// } -// -// -// -//} +package com.example.nto.config; + +import com.example.nto.filter.BaseAuthFilter; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.security.config.Customizer; +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.authentication.UsernamePasswordAuthenticationFilter; + +@Configuration +@EnableWebSecurity +public class WebSecurityConfig { + @Bean + public PasswordEncoder passwordEncoder() { + return new BCryptPasswordEncoder(); + } + + @Bean + public SecurityFilterChain filterChain(HttpSecurity http) throws Exception { + return + http + .csrf(csrf -> csrf.disable()) + .authorizeHttpRequests((authorize) -> authorize + .requestMatchers("/h2-console").permitAll() + .requestMatchers("/register").permitAll() + .anyRequest().authenticated()). + addFilterBefore(new BaseAuthFilter(), UsernamePasswordAuthenticationFilter.class). + httpBasic(Customizer.withDefaults()) + .build(); + + + } + + + +} diff --git a/src/main/java/com/example/nto/controller/EmployeeController.java b/src/main/java/com/example/nto/controller/EmployeeController.java index 6d7d57c..ab9a7d5 100644 --- a/src/main/java/com/example/nto/controller/EmployeeController.java +++ b/src/main/java/com/example/nto/controller/EmployeeController.java @@ -1,14 +1,21 @@ package com.example.nto.controller; - import com.example.nto.controller.dto.EmployeeDto; -import com.example.nto.controller.dto.EmployeeRegisterDto; import com.example.nto.entity.Employee; import com.example.nto.service.EmployeeService; import lombok.RequiredArgsConstructor; +import org.apache.tomcat.util.net.openssl.ciphers.Authentication; import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.security.core.context.SecurityContext; +import org.springframework.security.core.context.SecurityContextHolder; +import org.springframework.security.web.server.authorization.AuthorizationContext; import org.springframework.web.bind.annotation.*; +import java.util.Map; + +import static com.example.nto.controller.dto.EmployeeDto.toDto; + @RestController @RequestMapping("api") @RequiredArgsConstructor @@ -16,17 +23,14 @@ public class EmployeeController { private final EmployeeService employeeService; - @GetMapping("/{username}/info") - @ResponseStatus(code = HttpStatus.OK) - public EmployeeDto getByUsername(@PathVariable String username) { - return employeeService.getByUsername(username); + @GetMapping("/login") + public Employee login(Authentication auth) { + return employeeService.getByUsername((auth.getDeclaringClass()).getName()); } @PostMapping("/register") - @ResponseStatus(code = HttpStatus.CREATED) - public Employee registerEmployee(EmployeeRegisterDto employeeRegisterDto) { - return employeeService.register(employeeRegisterDto); + public void register(@RequestBody Map body) { + employeeService.register(body.get("login"), body.get("password")); } - } diff --git a/src/main/java/com/example/nto/entity/Employee.java b/src/main/java/com/example/nto/entity/Employee.java index 4b27334..9465ad7 100644 --- a/src/main/java/com/example/nto/entity/Employee.java +++ b/src/main/java/com/example/nto/entity/Employee.java @@ -17,7 +17,7 @@ import java.util.List; @NoArgsConstructor @AllArgsConstructor @Table(name = "employee") -public class Employee implements UserDetails{ +public class Employee implements UserDetails { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) diff --git a/src/main/java/com/example/nto/exception/NoSuchUsernameException.java b/src/main/java/com/example/nto/exception/NoSuchUsernameException.java new file mode 100644 index 0000000..c6ca91f --- /dev/null +++ b/src/main/java/com/example/nto/exception/NoSuchUsernameException.java @@ -0,0 +1,7 @@ +package com.example.nto.exception; + +public class NoSuchUsernameException extends RuntimeException { + public NoSuchUsernameException(String message) { + super(message); + } +} diff --git a/src/main/java/com/example/nto/exception/handler/GlobalExceptionHandler.java b/src/main/java/com/example/nto/exception/handler/GlobalExceptionHandler.java index 89860b5..c0ef676 100644 --- a/src/main/java/com/example/nto/exception/handler/GlobalExceptionHandler.java +++ b/src/main/java/com/example/nto/exception/handler/GlobalExceptionHandler.java @@ -28,6 +28,11 @@ public class GlobalExceptionHandler { return new ResponseEntity<>(e.getMessage(), HttpStatus.CONFLICT); } + @ExceptionHandler(NoSuchUsernameException.class) + public ResponseEntity handleNoSuchUsernameException(NoSuchUsernameException e) { + return new ResponseEntity<>(e.getMessage(), HttpStatus.CONFLICT); + } + @ExceptionHandler(Exception.class) public ResponseEntity handleGenericException(Exception e) { return new ResponseEntity<>(e.getMessage(), HttpStatus.BAD_REQUEST); diff --git a/src/main/java/com/example/nto/filter/BaseAuthFilter.java b/src/main/java/com/example/nto/filter/BaseAuthFilter.java new file mode 100644 index 0000000..02d0166 --- /dev/null +++ b/src/main/java/com/example/nto/filter/BaseAuthFilter.java @@ -0,0 +1,36 @@ +package com.example.nto.filter; + +import jakarta.servlet.FilterChain; +import jakarta.servlet.ServletException; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; +import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; +import org.springframework.security.core.context.SecurityContextHolder; +import org.springframework.web.filter.OncePerRequestFilter; + +import java.io.IOException; +import java.nio.charset.StandardCharsets; +import java.util.ArrayList; +import java.util.Base64; + +public class BaseAuthFilter extends OncePerRequestFilter { + @Override + protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException { + String header = request.getHeader("Authorisation"); + if (header != null && header.startsWith("Base")) { + try { + String base64Token = header.substring(5); + byte[] decoded = Base64.getDecoder().decode(base64Token); + String credentials = new String(decoded, StandardCharsets.UTF_8); + String[] values = credentials.split(" ", 2); + String username = values[0]; + String password = values[1]; + + UsernamePasswordAuthenticationToken auth = new UsernamePasswordAuthenticationToken(username, password, new ArrayList<>()); + SecurityContextHolder.getContext().setAuthentication(auth); + } catch (Exception e) { + filterChain.doFilter(request, response); + } + } + } +} diff --git a/src/main/java/com/example/nto/service/EmployeeService.java b/src/main/java/com/example/nto/service/EmployeeService.java index 084cda2..6367440 100644 --- a/src/main/java/com/example/nto/service/EmployeeService.java +++ b/src/main/java/com/example/nto/service/EmployeeService.java @@ -1,11 +1,9 @@ package com.example.nto.service; -import com.example.nto.controller.dto.EmployeeDto; -import com.example.nto.controller.dto.EmployeeRegisterDto; import com.example.nto.entity.Employee; public interface EmployeeService { - EmployeeDto getByUsername(String username); + Employee getByUsername(String username); - Employee register(EmployeeRegisterDto employeeRegisterDto); + void register(String login, String password); } diff --git a/src/main/java/com/example/nto/service/impl/CustomUserDetailsServiceImpl.java b/src/main/java/com/example/nto/service/impl/CustomUserDetailsServiceImpl.java new file mode 100644 index 0000000..b577749 --- /dev/null +++ b/src/main/java/com/example/nto/service/impl/CustomUserDetailsServiceImpl.java @@ -0,0 +1,23 @@ +package com.example.nto.service.impl; + +import com.example.nto.entity.Employee; +import com.example.nto.exception.NoSuchUsernameException; +import com.example.nto.repository.EmployeeRepository; +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 java.util.ArrayList; + +public class CustomUserDetailsServiceImpl implements UserDetailsService { + @Autowired private EmployeeRepository employeeRepository; + @Override + public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException { + Employee employee = employeeRepository.findByUsername(username).orElseThrow(() -> new NoSuchUsernameException("No employee with " + username + " username!!!")); + + return new org.springframework.security.core.userdetails.User(employee.getUsername(), + employee.getPassword(), + new ArrayList<>()); + } +} diff --git a/src/main/java/com/example/nto/service/impl/EmployeeServiceImpl.java b/src/main/java/com/example/nto/service/impl/EmployeeServiceImpl.java index e73ef9d..aec9e6e 100644 --- a/src/main/java/com/example/nto/service/impl/EmployeeServiceImpl.java +++ b/src/main/java/com/example/nto/service/impl/EmployeeServiceImpl.java @@ -1,43 +1,37 @@ package com.example.nto.service.impl; -import com.example.nto.controller.dto.EmployeeDto; -import com.example.nto.controller.dto.EmployeeRegisterDto; import com.example.nto.entity.Employee; import com.example.nto.exception.EmployeeAlreadyExistsException; -import com.example.nto.exception.EmployeeNotFoundException; +import com.example.nto.exception.NoSuchUsernameException; import com.example.nto.repository.EmployeeRepository; import com.example.nto.service.EmployeeService; import lombok.RequiredArgsConstructor; +import org.springframework.beans.factory.annotation.Autowired; import org.springframework.security.crypto.password.PasswordEncoder; import org.springframework.stereotype.Service; -import org.springframework.transaction.annotation.Transactional; @Service @RequiredArgsConstructor public class EmployeeServiceImpl implements EmployeeService { + @Autowired private final EmployeeRepository employeeRepository; + private final PasswordEncoder passwordEncoder; @Override - @Transactional(readOnly = true) - public EmployeeDto getByUsername(String username) { - return employeeRepository.findByUsername(username).map(EmployeeDto::toDto) - .orElseThrow(() -> new EmployeeNotFoundException("Employee with " + username + " code not found!")); + public Employee getByUsername(String username) { + return employeeRepository.findByUsername(username).orElseThrow(() -> new NoSuchUsernameException("No employee with " + username + " username!!!")); } @Override - public Employee register(EmployeeRegisterDto employeeRegisterDto) { - if (employeeRepository.findByUsername(employeeRegisterDto.getUsername()).isPresent()) { - throw new EmployeeAlreadyExistsException("Employee with " + employeeRegisterDto.getUsername() + " username"); + public void register(String login, String password) { + if (employeeRepository.findByUsername(login).isPresent()){ + throw new EmployeeAlreadyExistsException("Username is already exists"); } Employee employee = new Employee(); - employee.setUsername(employeeRegisterDto.getUsername()); - employee.setPassword(employeeRegisterDto.getPassword()); - - return employeeRepository.save(employee); + employee.setUsername(login); + employee.setPassword(passwordEncoder.encode(password)); } - - }