diff --git a/spring-security/src/main/java/com/spring/security1/config/SecurityConfig.java b/spring-security/src/main/java/com/spring/security1/config/SecurityConfig.java index 5fba44af..bbfb4a22 100644 --- a/spring-security/src/main/java/com/spring/security1/config/SecurityConfig.java +++ b/spring-security/src/main/java/com/spring/security1/config/SecurityConfig.java @@ -21,13 +21,15 @@ public class SecurityConfig extends WebSecurityConfigurerAdapter { protected void configure(HttpSecurity http) throws Exception { http.csrf().disable(); http.authorizeRequests() - .antMatchers("/user/**").authenticated() + .antMatchers("/user/**").authenticated() // 인증만 되면 들어갈 수 있다. .antMatchers("/manager/**").access("hasRole('ROLE_ADMIN') or hasRole('ROLE_MANAGER')") .antMatchers("/admin/**").access("hasRole('ROLE_ADMIN')") .anyRequest().permitAll() .and() .formLogin() - .loginPage("/loginForm"); + .loginPage("/loginForm") + .loginProcessingUrl("/login") // /login 주소가 호출이 되면 시큐리티가 대신 로그인을 진행해 준다. + .defaultSuccessUrl("/"); } } diff --git a/spring-security/src/main/java/com/spring/security1/config/auth/PrincipalDetails.java b/spring-security/src/main/java/com/spring/security1/config/auth/PrincipalDetails.java new file mode 100644 index 00000000..fdb760d4 --- /dev/null +++ b/spring-security/src/main/java/com/spring/security1/config/auth/PrincipalDetails.java @@ -0,0 +1,71 @@ +package com.spring.security1.config.auth; + +// 시큐리티가 /login 주소 요청이 오면 대신 로그인을 진행시킨다. +// 로그인이 완료가 되면 시큐리티 session을 만들어 준다. (Security ContextHolder) +// 오브젝트 타입 => Authentication 타입 객체 +// Authentication 안에 User 정보가 있어야 한다. +// User오브젝트 타입 => UserDetails 타입 객체 + +// Security Session => Authentication => UserDetails + +import com.spring.security1.model.User; +import org.springframework.security.core.GrantedAuthority; +import org.springframework.security.core.userdetails.UserDetails; + +import java.util.ArrayList; +import java.util.Collection; + +public class PrincipalDetails implements UserDetails { + + private User user; + + public PrincipalDetails(User user) { + this.user = user; + } + + // 해당 User의 권한을 리턴하는 곳 + @Override + public Collection getAuthorities() { + Collection collection = new ArrayList<>(); + collection.add(new GrantedAuthority() { + @Override + public String getAuthority() { + return user.getRole(); + } + }); + return collection; + } + + @Override + public String getPassword() { + return user.getPassword(); + } + + @Override + public String getUsername() { + return user.getUsername(); + } + + @Override + public boolean isAccountNonExpired() { + return true; + } + + @Override + public boolean isAccountNonLocked() { + return true; + } + + @Override + public boolean isCredentialsNonExpired() { + return true; + } + + @Override + public boolean isEnabled() { + + // ex) 1년동안 회원이 로그인을 안하면 휴면계정으로 하기로 했다면? + // 현재시간 - 로그인 시간 => 1년을 초과하면 false 리턴 + return true; + } +} diff --git a/spring-security/src/main/java/com/spring/security1/config/auth/PrincipalDetailsService.java b/spring-security/src/main/java/com/spring/security1/config/auth/PrincipalDetailsService.java new file mode 100644 index 00000000..f08ddba9 --- /dev/null +++ b/spring-security/src/main/java/com/spring/security1/config/auth/PrincipalDetailsService.java @@ -0,0 +1,30 @@ +package com.spring.security1.config.auth; + +import com.spring.security1.model.User; +import com.spring.security1.repository.UserRepository; +import lombok.RequiredArgsConstructor; +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.Service; + +// 시큐리티 설정에서 loginProcessingUrl("/login); +// /login 요청이 들어오면 자동으로 UserDetailsService 타입으로 IoC되어 있는 +// loadUserByUsername 함수가 실행 된다. +@Service +@RequiredArgsConstructor +public class PrincipalDetailsService implements UserDetailsService { + + private final UserRepository userRepository; + + + @Override + public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException { + User userEntity = userRepository.findByUsername(username); + System.out.println(username); + if(userEntity != null) { + return new PrincipalDetails(userEntity); // 시큐리티 session 내부에 Authentication 내부에 UserDetail 이 들어간다. + } + return null; + } +} diff --git a/spring-security/src/main/java/com/spring/security1/repository/UserRepository.java b/spring-security/src/main/java/com/spring/security1/repository/UserRepository.java index f81928f2..f1c1f882 100644 --- a/spring-security/src/main/java/com/spring/security1/repository/UserRepository.java +++ b/spring-security/src/main/java/com/spring/security1/repository/UserRepository.java @@ -8,4 +8,7 @@ import org.springframework.stereotype.Repository; // JpaRepository를 상속 했기 때문에 @Repository 어노테이션이 없어도 IoC된다. @Repository public interface UserRepository extends JpaRepository { + // findBy규칙 ->Username 문법 + // select * from user where username='?'; + User findByUsername(String username); } diff --git a/spring-security/src/main/resources/application.yml b/spring-security/src/main/resources/application.yml index 3aa441f1..574d6baa 100644 --- a/spring-security/src/main/resources/application.yml +++ b/spring-security/src/main/resources/application.yml @@ -16,7 +16,7 @@ spring: jpa: hibernate: - ddl-auto: create #create update none + ddl-auto: update #create update none naming: physical-strategy: org.hibernate.boot.model.naming.PhysicalNamingStrategyStandardImpl show-sql: true \ No newline at end of file diff --git a/spring-security/src/main/resources/templates/loginForm.html b/spring-security/src/main/resources/templates/loginForm.html index 5af3ae35..a013732f 100644 --- a/spring-security/src/main/resources/templates/loginForm.html +++ b/spring-security/src/main/resources/templates/loginForm.html @@ -7,7 +7,7 @@

로그인 페이지


-
+