개발자
데이터베이스에 user테이블과 role테이블 그리고 user_role테이블을 만들어 user_id와 role_id를 만들어 다대다 매핑을 하였습니다. 기존에는 configureGlobal방식으로 .authoritiesByUsernameQuery(“select u.email, r.name from user_role ur inner join user u on ur.user_id = u.id inner join role r on ur.role_id = r.id where u.email = ?") 이런 방식으로 했는데 userDetailsService 인터페이스를 이용하여 로그인 처리를 하는 방식에서 유저의 권한을 어떻게 처리해야할지 모르겠습니다ㅠㅠㅠ 아직 시큐리티에 대해 잘 몰라 자세히 알려주시면 정말 감사하겠습니다 ㅠㅠ
답변 1
' UserDetailsService ' 인터페이스를 사용하여 로그인 처리를 할 때, 유저의 권한을 처리하기 위해서는 커스텀 ' UserDetailsService '를 구현하고, ' UserDetails ' 인터페이스를 구현한 클래스를 이용하여 권한 정보를 반환해야 합니다. 아래 예시 코드를 참조하세요. 1. 먼저 ' UserDetails ' 인터페이스를 구현한 커스텀 클래스를 만듭니다. 예를 들어 ' CustomUserDetails '라고 이름 짓겠습니다. 2. 다음으로 ' UserDetailsService ' 인터페이스를 구현한 커스텀 클래스를 만듭니다. 예를 들어 ' CustomUserDetailsService '라고 이름 짓겠습니다. 3. 마지막으로 ' WebSecurityConfigurerAdapter '를 상속받아 구성을 설정하고 ' CustomUserDetailsService '를 사용하도록 지정합니다.
1#1
2import org.springframework.security.core.GrantedAuthority;
3import org.springframework.security.core.authority.SimpleGrantedAuthority;
4import org.springframework.security.core.userdetails.UserDetails;
5
6import java.util.Collection;
7import java.util.Set;
8import java.util.stream.Collectors;
9
10public class CustomUserDetails implements UserDetails {
11
12 private String username;
13 private String password;
14 private Set<String> roles;
15
16 public CustomUserDetails(String username, String password, Set<String> roles) {
17 this.username = username;
18 this.password = password;
19 this.roles = roles;
20 }
21
22 @Override
23 public Collection<? extends GrantedAuthority> getAuthorities() {
24 return roles.stream().map(SimpleGrantedAuthority::new).collect(Collectors.toList());
25 }
26
27 // ... 생략 (나머지 UserDetails 인터페이스 메서드 구현)
28}
29
30
31#2
32import org.springframework.security.core.userdetails.UserDetails;
33import org.springframework.security.core.userdetails.UserDetailsService;
34import org.springframework.security.core.userdetails.UsernameNotFoundException;
35import org.springframework.stereotype.Service;
36
37import javax.sql.DataSource;
38import java.sql.Connection;
39import java.sql.PreparedStatement;
40import java.sql.ResultSet;
41import java.util.HashSet;
42import java.util.Set;
43
44@Service
45public class CustomUserDetailsService implements UserDetailsService {
46
47 private final DataSource dataSource;
48
49 public CustomUserDetailsService(DataSource dataSource) {
50 this.dataSource = dataSource;
51 }
52
53 @Override
54 public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
55 String userQuery = "SELECT email, password FROM user WHERE email = ?";
56 String roleQuery = "SELECT r.name FROM user_role ur INNER JOIN user u ON ur.user_id = u.id INNER JOIN role r ON ur.role_id = r.id WHERE u.email = ?";
57
58 try (Connection conn = dataSource.getConnection()) {
59 PreparedStatement userStmt = conn.prepareStatement(userQuery);
60 userStmt.setString(1, username);
61 ResultSet userRs = userStmt.executeQuery();
62
63 if (!userRs.next()) {
64 throw new UsernameNotFoundException("User not found");
65 }
66
67 String password = userRs.getString("password");
68
69 PreparedStatement roleStmt = conn.prepareStatement(roleQuery);
70 roleStmt.setString(1, username);
71 ResultSet roleRs = roleStmt.executeQuery();
72
73 Set<String> roles = new HashSet<>();
74 while (roleRs.next()) {
75 roles.add(roleRs.getString("name"));
76 }
77
78 return new CustomUserDetails(username, password, roles);
79 } catch (Exception e) {
80 throw new RuntimeException(e);
81 }
82 }
83}
84
85
86#3
87import org.springframework.beans.factory.annotation.Autowired;
88import org.springframework.context.annotation.Bean;
89import org.springframework.security.config.annotation
커리어리 AI 봇의 답변을 평가해 주세요!
지금 가입하면 모든 질문의 답변을 볼 수 있어요!
현직자들의 명쾌한 답변을 얻을 수 있어요.
이미 회원이신가요?
지금 가입하면 모든 질문의 답변을 볼 수 있어요!