Mdofiy 관리자페이지 게시글내역 히스토리 볼수 있도록 수정, securityConfig 순환참조 오류 수정
This commit is contained in:
@@ -0,0 +1,12 @@
|
|||||||
|
package com.example.springsecuritystudy.common;
|
||||||
|
|
||||||
|
public class AlreadyRegisteredUserException extends RuntimeException {
|
||||||
|
|
||||||
|
public AlreadyRegisteredUserException(String message) {
|
||||||
|
super(message);
|
||||||
|
}
|
||||||
|
|
||||||
|
public AlreadyRegisteredUserException() {
|
||||||
|
super("이미 등록된 유저입니다.");
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,32 @@
|
|||||||
|
package com.example.springsecuritystudy.config;
|
||||||
|
|
||||||
|
import javax.annotation.PostConstruct;
|
||||||
|
|
||||||
|
import org.springframework.context.annotation.Configuration;
|
||||||
|
|
||||||
|
import com.example.springsecuritystudy.notice.NoticeService;
|
||||||
|
import com.example.springsecuritystudy.post.PostService;
|
||||||
|
import com.example.springsecuritystudy.user.User;
|
||||||
|
import com.example.springsecuritystudy.user.UserService;
|
||||||
|
|
||||||
|
import lombok.RequiredArgsConstructor;
|
||||||
|
|
||||||
|
@Configuration
|
||||||
|
@RequiredArgsConstructor
|
||||||
|
public class InitializeConfig {
|
||||||
|
|
||||||
|
private final UserService userService;
|
||||||
|
private final PostService postService;
|
||||||
|
private final NoticeService noticeService;
|
||||||
|
|
||||||
|
@PostConstruct
|
||||||
|
public void adminAccount() {
|
||||||
|
User user = userService.signup("user", "user");
|
||||||
|
userService.signupAdmin("admin", "admin");
|
||||||
|
postService.savePost(user, "테스트", "테스트입니다.");
|
||||||
|
postService.savePost(user, "테스트2", "테스트2입니다.");
|
||||||
|
postService.savePost(user, "테스트3", "테스트3입니다.");
|
||||||
|
postService.savePost(user, "여름 여행계획", "여름 여행계획 작성중...");
|
||||||
|
noticeService.saveNotice("환영합니다", "환영합니다 여러분");
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -3,18 +3,9 @@ package com.example.springsecuritystudy.config;
|
|||||||
import org.springframework.context.annotation.Bean;
|
import org.springframework.context.annotation.Bean;
|
||||||
import org.springframework.context.annotation.Configuration;
|
import org.springframework.context.annotation.Configuration;
|
||||||
import org.springframework.web.filter.HiddenHttpMethodFilter;
|
import org.springframework.web.filter.HiddenHttpMethodFilter;
|
||||||
import org.springframework.web.servlet.config.annotation.ViewControllerRegistry;
|
|
||||||
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
|
|
||||||
|
|
||||||
@Configuration
|
@Configuration
|
||||||
public class MvcConfig implements WebMvcConfigurer {
|
public class MvcConfig {
|
||||||
|
|
||||||
public void addViewControllers(ViewControllerRegistry registry) {
|
|
||||||
registry.addViewController("/").setViewName("index");
|
|
||||||
registry.addViewController("/home").setViewName("index");
|
|
||||||
registry.addViewController("/admin").setViewName("admin/index");
|
|
||||||
registry.addViewController("/login").setViewName("login");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Bean
|
@Bean
|
||||||
public HiddenHttpMethodFilter hiddenHttpMethodFilter(){
|
public HiddenHttpMethodFilter hiddenHttpMethodFilter(){
|
||||||
|
|||||||
@@ -4,28 +4,21 @@ import org.springframework.context.annotation.Bean;
|
|||||||
import org.springframework.http.HttpMethod;
|
import org.springframework.http.HttpMethod;
|
||||||
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
|
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
|
||||||
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
|
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
|
||||||
import org.springframework.security.config.annotation.web.configuration.WebSecurityCustomizer;
|
|
||||||
import org.springframework.security.core.userdetails.UserDetailsService;
|
|
||||||
import org.springframework.security.core.userdetails.UsernameNotFoundException;
|
|
||||||
import org.springframework.security.web.SecurityFilterChain;
|
import org.springframework.security.web.SecurityFilterChain;
|
||||||
import org.springframework.security.web.util.matcher.AntPathRequestMatcher;
|
import org.springframework.security.web.util.matcher.AntPathRequestMatcher;
|
||||||
|
|
||||||
import com.example.springsecuritystudy.user.UserRepository;
|
|
||||||
|
|
||||||
import lombok.RequiredArgsConstructor;
|
import lombok.RequiredArgsConstructor;
|
||||||
|
|
||||||
@EnableWebSecurity
|
@EnableWebSecurity
|
||||||
@RequiredArgsConstructor
|
@RequiredArgsConstructor
|
||||||
public class SecurityConfig {
|
public class SecurityConfig {
|
||||||
|
|
||||||
private final UserRepository userRepository;
|
|
||||||
|
|
||||||
@Bean
|
@Bean
|
||||||
public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
|
public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
|
||||||
http
|
http
|
||||||
.authorizeHttpRequests(auth -> auth
|
.authorizeHttpRequests(auth -> auth
|
||||||
.antMatchers("/", "/home", "/signup", "/example",
|
.antMatchers("/", "/home", "/signup", "/example",
|
||||||
"/css/**", "/js/**", "/h2-console/**").permitAll()
|
"/css/**", "/h2-console/**").permitAll()
|
||||||
.antMatchers("/post").hasRole("USER")
|
.antMatchers("/post").hasRole("USER")
|
||||||
.antMatchers("/admin").hasRole("ADMIN")
|
.antMatchers("/admin").hasRole("ADMIN")
|
||||||
.antMatchers(HttpMethod.POST, "/notice").hasRole("ADMIN")
|
.antMatchers(HttpMethod.POST, "/notice").hasRole("ADMIN")
|
||||||
@@ -48,14 +41,4 @@ public class SecurityConfig {
|
|||||||
return http.build();
|
return http.build();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Bean
|
|
||||||
public WebSecurityCustomizer webSecurityCustomizer() {
|
|
||||||
return web -> web.ignoring().antMatchers("/css/**", "/js/**", "/h2-console/**");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Bean
|
|
||||||
public UserDetailsService userDetailsService() {
|
|
||||||
return username -> userRepository.findByUsername(username)
|
|
||||||
.orElseThrow(() -> new UsernameNotFoundException("유저를 찾지 못 했습니다."));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,26 @@
|
|||||||
|
package com.example.springsecuritystudy.config;
|
||||||
|
|
||||||
|
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;
|
||||||
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
|
|
||||||
|
import com.example.springsecuritystudy.common.UserNotFoundException;
|
||||||
|
import com.example.springsecuritystudy.user.UserRepository;
|
||||||
|
|
||||||
|
import lombok.RequiredArgsConstructor;
|
||||||
|
|
||||||
|
@Service
|
||||||
|
@RequiredArgsConstructor
|
||||||
|
@Transactional(readOnly = true)
|
||||||
|
public class UserDetailServiceImpl implements UserDetailsService {
|
||||||
|
|
||||||
|
private final UserRepository userRepository;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
|
||||||
|
return userRepository.findByUsername(username)
|
||||||
|
.orElseThrow(UserNotFoundException::new);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -7,6 +7,11 @@ import org.springframework.web.bind.annotation.GetMapping;
|
|||||||
@Controller
|
@Controller
|
||||||
public class SampleController {
|
public class SampleController {
|
||||||
|
|
||||||
|
@GetMapping({"/", "/home"})
|
||||||
|
public String index() {
|
||||||
|
return "index";
|
||||||
|
}
|
||||||
|
|
||||||
@GetMapping("/example")
|
@GetMapping("/example")
|
||||||
public String example(Model model) {
|
public String example(Model model) {
|
||||||
model.addAttribute("name", "정우성");
|
model.addAttribute("name", "정우성");
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ package com.example.springsecuritystudy.notice;
|
|||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
|
import org.springframework.data.domain.Sort;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
import org.springframework.transaction.annotation.Transactional;
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
|
|
||||||
@@ -16,7 +17,7 @@ public class NoticeService {
|
|||||||
|
|
||||||
@Transactional(readOnly = true)
|
@Transactional(readOnly = true)
|
||||||
public List<Notice> findAll() {
|
public List<Notice> findAll() {
|
||||||
return noticeRepository.findAll();
|
return noticeRepository.findAll(Sort.by(Sort.Direction.DESC, "id"));
|
||||||
}
|
}
|
||||||
|
|
||||||
public Notice saveNotice(String title, String content) {
|
public Notice saveNotice(String title, String content) {
|
||||||
|
|||||||
@@ -0,0 +1,29 @@
|
|||||||
|
package com.example.springsecuritystudy.post;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import org.springframework.security.core.Authentication;
|
||||||
|
import org.springframework.stereotype.Controller;
|
||||||
|
import org.springframework.ui.Model;
|
||||||
|
import org.springframework.web.bind.annotation.GetMapping;
|
||||||
|
import org.springframework.web.bind.annotation.RequestMapping;
|
||||||
|
|
||||||
|
import com.example.springsecuritystudy.user.User;
|
||||||
|
|
||||||
|
import lombok.RequiredArgsConstructor;
|
||||||
|
|
||||||
|
@Controller
|
||||||
|
@RequiredArgsConstructor
|
||||||
|
@RequestMapping("/admin")
|
||||||
|
public class AdminController {
|
||||||
|
|
||||||
|
private final PostService postService;
|
||||||
|
|
||||||
|
@GetMapping
|
||||||
|
public String getPostForAdmin(Authentication authentication, Model model) {
|
||||||
|
User user = (User) authentication.getPrincipal();
|
||||||
|
List<Post> posts = postService.findByUser(user);
|
||||||
|
model.addAttribute("posts", posts);
|
||||||
|
return "admin/index";
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -43,4 +43,9 @@ public class Post extends BaseTimeEntity {
|
|||||||
this.status = PostStatus.Y;
|
this.status = PostStatus.Y;
|
||||||
this.user = user;
|
this.user = user;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void updatePost(String title, String content) {
|
||||||
|
this.title = title;
|
||||||
|
this.content = content;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -24,7 +24,7 @@ public class PostController {
|
|||||||
private final PostService postService;
|
private final PostService postService;
|
||||||
|
|
||||||
@GetMapping
|
@GetMapping
|
||||||
public String findByPost(Authentication authentication, Model model) {
|
public String getPost(Authentication authentication, Model model) {
|
||||||
User user = (User) authentication.getPrincipal();
|
User user = (User) authentication.getPrincipal();
|
||||||
List<Post> posts = postService.findByUser(user);
|
List<Post> posts = postService.findByUser(user);
|
||||||
model.addAttribute("posts", posts);
|
model.addAttribute("posts", posts);
|
||||||
|
|||||||
@@ -8,7 +8,9 @@ import com.example.springsecuritystudy.user.User;
|
|||||||
|
|
||||||
public interface PostRepository extends JpaRepository<Post, Long> {
|
public interface PostRepository extends JpaRepository<Post, Long> {
|
||||||
|
|
||||||
List<Post> findByUserAndStatus(User user, PostStatus status);
|
List<Post> findByUserAndStatusOrderByIdDesc(User user, PostStatus status);
|
||||||
|
|
||||||
Post findByIdAndUser(Long id, User user);
|
Post findByIdAndUser(Long id, User user);
|
||||||
|
|
||||||
|
List<Post> findByStatusOrderByIdDesc(PostStatus status);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,8 +5,8 @@ import java.util.List;
|
|||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
import org.springframework.transaction.annotation.Transactional;
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
|
|
||||||
|
import com.example.springsecuritystudy.common.UserNotFoundException;
|
||||||
import com.example.springsecuritystudy.user.User;
|
import com.example.springsecuritystudy.user.User;
|
||||||
import com.example.springsecuritystudy.user.UserRepository;
|
|
||||||
|
|
||||||
import lombok.RequiredArgsConstructor;
|
import lombok.RequiredArgsConstructor;
|
||||||
|
|
||||||
@@ -15,18 +15,20 @@ import lombok.RequiredArgsConstructor;
|
|||||||
@Transactional
|
@Transactional
|
||||||
public class PostService {
|
public class PostService {
|
||||||
|
|
||||||
private final UserRepository userRepository;
|
|
||||||
private final PostRepository postRepository;
|
private final PostRepository postRepository;
|
||||||
|
|
||||||
@Transactional(readOnly = true)
|
@Transactional(readOnly = true)
|
||||||
public List<Post> findByUser(User user) {
|
public List<Post> findByUser(User user) {
|
||||||
userNullCheck(user);
|
userNullCheck(user);
|
||||||
return postRepository.findByUserAndStatus(user, PostStatus.Y);
|
if (Boolean.TRUE.equals(user.isAdmin())) {
|
||||||
|
return postRepository.findByStatusOrderByIdDesc(PostStatus.Y);
|
||||||
|
}
|
||||||
|
return postRepository.findByUserAndStatusOrderByIdDesc(user, PostStatus.Y);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void userNullCheck(User user) {
|
private static void userNullCheck(User user) {
|
||||||
if (user == null) {
|
if (user == null) {
|
||||||
throw new RuntimeException("유저가 없습니다.");
|
throw new UserNotFoundException();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -4,18 +4,21 @@ import org.springframework.stereotype.Controller;
|
|||||||
import org.springframework.web.bind.annotation.GetMapping;
|
import org.springframework.web.bind.annotation.GetMapping;
|
||||||
import org.springframework.web.bind.annotation.ModelAttribute;
|
import org.springframework.web.bind.annotation.ModelAttribute;
|
||||||
import org.springframework.web.bind.annotation.PostMapping;
|
import org.springframework.web.bind.annotation.PostMapping;
|
||||||
import org.springframework.web.bind.annotation.RequestMapping;
|
|
||||||
|
|
||||||
import lombok.RequiredArgsConstructor;
|
import lombok.RequiredArgsConstructor;
|
||||||
|
|
||||||
@Controller
|
@Controller
|
||||||
@RequiredArgsConstructor
|
@RequiredArgsConstructor
|
||||||
@RequestMapping("/signup")
|
|
||||||
public class UserController {
|
public class UserController {
|
||||||
|
|
||||||
private final UserService userService;
|
private final UserService userService;
|
||||||
|
|
||||||
@GetMapping
|
@GetMapping("/login")
|
||||||
|
public String loginView() {
|
||||||
|
return "login";
|
||||||
|
}
|
||||||
|
|
||||||
|
@GetMapping("/signup")
|
||||||
public String signupView() {
|
public String signupView() {
|
||||||
return "signup";
|
return "signup";
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,9 +1,11 @@
|
|||||||
package com.example.springsecuritystudy.user;
|
package com.example.springsecuritystudy.user;
|
||||||
|
|
||||||
import org.springframework.security.core.userdetails.UsernameNotFoundException;
|
|
||||||
import org.springframework.security.crypto.password.PasswordEncoder;
|
import org.springframework.security.crypto.password.PasswordEncoder;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
|
import com.example.springsecuritystudy.common.AlreadyRegisteredUserException;
|
||||||
|
import com.example.springsecuritystudy.common.UserNotFoundException;
|
||||||
|
|
||||||
import lombok.RequiredArgsConstructor;
|
import lombok.RequiredArgsConstructor;
|
||||||
|
|
||||||
@Service
|
@Service
|
||||||
@@ -14,22 +16,24 @@ public class UserService {
|
|||||||
private final PasswordEncoder passwordEncoder;
|
private final PasswordEncoder passwordEncoder;
|
||||||
|
|
||||||
public User signup(String username, String password) {
|
public User signup(String username, String password) {
|
||||||
if (userRepository.findByUsername(username).isPresent()) {
|
alreadyRegisteredUser(username);
|
||||||
throw new RuntimeException("이미 등록된 유저입니다.");
|
|
||||||
}
|
|
||||||
return userRepository.save(new User(username, passwordEncoder.encode(password), "ROLE_USER"));
|
return userRepository.save(new User(username, passwordEncoder.encode(password), "ROLE_USER"));
|
||||||
}
|
}
|
||||||
|
|
||||||
public User signupAdmin(String username, String password) {
|
public User signupAdmin(String username, String password) {
|
||||||
if (userRepository.findByUsername(username).isPresent()) {
|
alreadyRegisteredUser(username);
|
||||||
throw new RuntimeException("이미 등록된 Admin유저입니다.");
|
|
||||||
}
|
|
||||||
return userRepository.save(new User(username, passwordEncoder.encode(password), "ROLE_ADMIN"));
|
return userRepository.save(new User(username, passwordEncoder.encode(password), "ROLE_ADMIN"));
|
||||||
}
|
}
|
||||||
|
|
||||||
public User findByUsername(String username) {
|
public User findByUsername(String username) {
|
||||||
return userRepository.findByUsername(username)
|
return userRepository.findByUsername(username)
|
||||||
.orElseThrow(() -> new UsernameNotFoundException("존재하지 않는 유저입니다."));
|
.orElseThrow(UserNotFoundException::new);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void alreadyRegisteredUser(String username) {
|
||||||
|
if (userRepository.findByUsername(username).isPresent()) {
|
||||||
|
throw new AlreadyRegisteredUserException();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,7 +8,19 @@
|
|||||||
<header th:insert="fragments.html::nav"></header>
|
<header th:insert="fragments.html::nav"></header>
|
||||||
<div class="container">
|
<div class="container">
|
||||||
<h1>관리자 페이지</h1>
|
<h1>관리자 페이지</h1>
|
||||||
<p>당신은 관리자입니다.</p>
|
<h3>게시글 내역</h3>
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-lg-8 col-lg-offset-2 col-md-10 col-md-offset-1">
|
||||||
|
<div th:each="post : ${posts}">
|
||||||
|
<p style="margin: 10px 0;">
|
||||||
|
<strong th:text="${post.title}"></strong>
|
||||||
|
Posted by
|
||||||
|
<strong th:if="${post.user}" th:text="${post.user.username}"></strong> on
|
||||||
|
<strong th:text="${#temporals.format(post.createdAt, 'yyyy-MM-dd')}"></strong>
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|||||||
Reference in New Issue
Block a user