diff --git a/build.gradle b/build.gradle index 0b4ed94..8e92312 100644 --- a/build.gradle +++ b/build.gradle @@ -23,6 +23,8 @@ dependencies { implementation 'org.springframework.boot:spring-boot-starter-data-mongodb' implementation 'org.springframework.boot:spring-boot-starter-security' implementation 'org.springframework.boot:spring-boot-starter-web' + compile "org.springframework.boot:spring-boot-starter-security:*" + compile "org.springframework.security:spring-security-config:*" testImplementation('org.springframework.boot:spring-boot-starter-test') { exclude group: 'org.junit.vintage', module: 'junit-vintage-engine' } diff --git a/src/main/java/com/fnecan/study/bookapi/config/SecurityConfiguration.java b/src/main/java/com/fnecan/study/bookapi/config/SecurityConfiguration.java new file mode 100644 index 0000000..133df73 --- /dev/null +++ b/src/main/java/com/fnecan/study/bookapi/config/SecurityConfiguration.java @@ -0,0 +1,38 @@ +package com.fnecan.study.bookapi.config; + +import com.fnecan.study.bookapi.service.UserService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.context.properties.EnableConfigurationProperties; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder; +import org.springframework.security.config.annotation.web.builders.HttpSecurity; +import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; +import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; +import org.springframework.security.crypto.password.PasswordEncoder; + +@Configuration +@EnableConfigurationProperties +public class SecurityConfiguration extends WebSecurityConfigurerAdapter { + @Autowired + UserService userService; + + @Override + protected void configure(HttpSecurity http) throws Exception { + http + .csrf().disable() + .authorizeRequests().anyRequest().authenticated() + .and().httpBasic() + .and().sessionManagement().disable(); + } + + @Bean + public PasswordEncoder passwordEncoder() { + return new BCryptPasswordEncoder(); + } + + @Override + public void configure(AuthenticationManagerBuilder builder) throws Exception { + builder.userDetailsService(userService); + } +} diff --git a/src/main/java/com/fnecan/study/bookapi/model/UserDocument.java b/src/main/java/com/fnecan/study/bookapi/model/UserDocument.java index 5070fd9..9af92ff 100644 --- a/src/main/java/com/fnecan/study/bookapi/model/UserDocument.java +++ b/src/main/java/com/fnecan/study/bookapi/model/UserDocument.java @@ -3,12 +3,21 @@ package com.fnecan.study.bookapi.model; import org.springframework.data.annotation.Id; import org.springframework.data.mongodb.core.mapping.Document; -@Document public class UserDocument { @Id - private String userId; + private String _id; private String username; + + public String getPassword() { + return password; + } + + public void setPassword(String password) { + this.password = password; + } + + private String password; private String location; public UserDocument(String username, String location) { diff --git a/src/main/java/com/fnecan/study/bookapi/repository/UserRepository.java b/src/main/java/com/fnecan/study/bookapi/repository/UserRepository.java new file mode 100644 index 0000000..46d3430 --- /dev/null +++ b/src/main/java/com/fnecan/study/bookapi/repository/UserRepository.java @@ -0,0 +1,8 @@ +package com.fnecan.study.bookapi.repository; + +import com.fnecan.study.bookapi.model.UserDocument; +import org.springframework.data.mongodb.repository.MongoRepository; + +public interface UserRepository extends MongoRepository { + UserDocument findByUsername(String userName); +} diff --git a/src/main/java/com/fnecan/study/bookapi/service/UserService.java b/src/main/java/com/fnecan/study/bookapi/service/UserService.java new file mode 100644 index 0000000..66f0e1c --- /dev/null +++ b/src/main/java/com/fnecan/study/bookapi/service/UserService.java @@ -0,0 +1,35 @@ +package com.fnecan.study.bookapi.service; + +import com.fnecan.study.bookapi.model.UserDocument; +import com.fnecan.study.bookapi.repository.UserRepository; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.security.core.Authentication; +import org.springframework.security.core.authority.SimpleGrantedAuthority; +import org.springframework.security.core.userdetails.AuthenticationUserDetailsService; +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.stereotype.Component; + +import java.util.Arrays; +import java.util.Collections; +import java.util.List; +import java.util.Optional; + +@Component +public class UserService implements UserDetailsService { + + @Autowired + UserRepository userRepository; + + @Override + public UserDetails loadUserByUsername(String userName) throws UsernameNotFoundException { + UserDocument user = Optional.ofNullable(userRepository.findByUsername(userName)) + .orElseThrow(() -> new UsernameNotFoundException("User not found")); + + List authorities = Collections.singletonList(new SimpleGrantedAuthority("user")); + + return new User(user.getUsername(), user.getPassword(), authorities); + } +}